ia64/xen-unstable
changeset 19148:aca402831ac1
x86: Relocate Multiboot structures where we know they will be
accessible. GRUB2 seems to like to stick them really high sometimes
(just below 4GB).
The 32-bit C code framework that this sets up can also be used for
other stuff in future:
* early cmdline parsing
* relocating multiboot modules so they too are guaranteed accessible
Its interaction with normal Xen start-of-day, and with the 16-bit
assembly trampoline, needs a bit of thought.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
accessible. GRUB2 seems to like to stick them really high sometimes
(just below 4GB).
The 32-bit C code framework that this sets up can also be used for
other stuff in future:
* early cmdline parsing
* relocating multiboot modules so they too are guaranteed accessible
Its interaction with normal Xen start-of-day, and with the 16-bit
assembly trampoline, needs a bit of thought.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Tue Feb 03 18:11:03 2009 +0000 (2009-02-03) |
parents | d68178692b7c |
children | efef232bbbdb |
files | .hgignore xen/arch/x86/Makefile xen/arch/x86/boot/Makefile xen/arch/x86/boot/build32.mk xen/arch/x86/boot/head.S xen/arch/x86/boot/reloc.c |
line diff
1.1 --- a/.hgignore Tue Feb 03 14:06:51 2009 +0000 1.2 +++ b/.hgignore Tue Feb 03 18:11:03 2009 +0000 1.3 @@ -256,6 +256,7 @@ 1.4 ^xen/arch/x86/asm-offsets\.s$ 1.5 ^xen/arch/x86/boot/mkelf32$ 1.6 ^xen/arch/x86/xen\.lds$ 1.7 +^xen/arch/x86/boot/reloc.S$ 1.8 ^xen/ddb/.*$ 1.9 ^xen/include/asm$ 1.10 ^xen/include/asm-.*/asm-offsets\.h$ 1.11 @@ -279,15 +280,6 @@ 1.12 ^xen/arch/ia64/asm-xsi-offsets\.s$ 1.13 ^xen/arch/ia64/map\.out$ 1.14 ^xen/arch/ia64/xen\.lds\.s$ 1.15 -^xen/arch/powerpc/dom0\.bin$ 1.16 -^xen/arch/powerpc/asm-offsets\.s$ 1.17 -^xen/arch/powerpc/firmware$ 1.18 -^xen/arch/powerpc/firmware.dbg$ 1.19 -^xen/arch/powerpc/firmware_image.bin$ 1.20 -^xen/arch/powerpc/xen\.lds$ 1.21 -^xen/arch/powerpc/\.xen-syms$ 1.22 -^xen/arch/powerpc/xen-syms\.S$ 1.23 -^xen/arch/powerpc/cmdline.dep$ 1.24 ^unmodified_drivers/linux-2.6/\.tmp_versions 1.25 ^unmodified_drivers/linux-2.6/.*\.cmd$ 1.26 ^unmodified_drivers/linux-2.6/.*\.ko$
2.1 --- a/xen/arch/x86/Makefile Tue Feb 03 14:06:51 2009 +0000 2.2 +++ b/xen/arch/x86/Makefile Tue Feb 03 18:11:03 2009 +0000 2.3 @@ -92,3 +92,4 @@ boot/mkelf32: boot/mkelf32.c 2.4 clean:: 2.5 rm -f asm-offsets.s xen.lds boot/*.o boot/*~ boot/core boot/mkelf32 2.6 rm -f $(BASEDIR)/.xen-syms.[0-9]* boot/.*.d 2.7 + rm -f boot/reloc.S boot/reloc.lnk boot/reloc.bin
3.1 --- a/xen/arch/x86/boot/Makefile Tue Feb 03 14:06:51 2009 +0000 3.2 +++ b/xen/arch/x86/boot/Makefile Tue Feb 03 18:11:03 2009 +0000 3.3 @@ -1,1 +1,7 @@ 3.4 obj-y += head.o 3.5 + 3.6 +head.o: reloc.S 3.7 + 3.8 +# NB. BOOT_TRAMPOLINE == 0x8c000 3.9 +%.S: %.c 3.10 + RELOC=0x8c000 $(MAKE) -f build32.mk $@
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/xen/arch/x86/boot/build32.mk Tue Feb 03 18:11:03 2009 +0000 4.3 @@ -0,0 +1,24 @@ 4.4 +XEN_ROOT=../../../.. 4.5 +override XEN_TARGET_ARCH=x86_32 4.6 +CFLAGS = 4.7 +include $(XEN_ROOT)/Config.mk 4.8 + 4.9 +# Disable PIE/SSP if GCC supports them. They can break us. 4.10 +$(call cc-option-add,CFLAGS,CC,-nopie) 4.11 +$(call cc-option-add,CFLAGS,CC,-fno-stack-protector) 4.12 +$(call cc-option-add,CFLAGS,CC,-fno-stack-protector-all) 4.13 + 4.14 +CFLAGS += -Werror -fno-builtin -msoft-float 4.15 + 4.16 +%.S: %.bin 4.17 + (od -v -t x $< | head -n -1 | \ 4.18 + sed 's/ /,0x/g' | sed 's/^[0-9]*,/ .long /') >$@ 4.19 + 4.20 +%.bin: %.lnk 4.21 + $(OBJCOPY) -O binary $< $@ 4.22 + 4.23 +%.lnk: %.o 4.24 + $(LD) $(LDFLAGS_DIRECT) -N -Ttext 0x8c000 -o $@ $< 4.25 + 4.26 +%.o: %.c 4.27 + $(CC) $(CFLAGS) -c $< -o $@
5.1 --- a/xen/arch/x86/boot/head.S Tue Feb 03 14:06:51 2009 +0000 5.2 +++ b/xen/arch/x86/boot/head.S Tue Feb 03 18:11:03 2009 +0000 5.3 @@ -79,8 +79,11 @@ gdt_boot_descr: 5.4 cmp $0x2BADB002,%eax 5.5 jne not_multiboot 5.6 5.7 - /* Save the Multiboot info structure for later use. */ 5.8 - mov %ebx,sym_phys(multiboot_ptr) 5.9 + /* Save the Multiboot info struct (after relocation) for later use. */ 5.10 + mov $sym_phys(cpu0_stack)+1024,%esp 5.11 + push %ebx 5.12 + call reloc 5.13 + mov %eax,sym_phys(multiboot_ptr) 5.14 5.15 /* Initialize BSS (no nasty surprises!) */ 5.16 mov $sym_phys(__bss_start),%edi 5.17 @@ -192,6 +195,9 @@ 2: cmp $L1_PAGETABLE_ENTRIES,%e 5.18 5.19 #include "cmdline.S" 5.20 5.21 +reloc: 5.22 +#include "reloc.S" 5.23 + 5.24 .align 16 5.25 .globl trampoline_start, trampoline_end 5.26 trampoline_start:
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/xen/arch/x86/boot/reloc.c Tue Feb 03 18:11:03 2009 +0000 6.3 @@ -0,0 +1,80 @@ 6.4 +/****************************************************************************** 6.5 + * reloc.c 6.6 + * 6.7 + * 32-bit flat memory-map routines for relocating Multiboot structures 6.8 + * and modules. This is most easily done early with paging disabled. 6.9 + * 6.10 + * Copyright (c) 2009, Citrix Systems, Inc. 6.11 + * 6.12 + * Authors: 6.13 + * Keir Fraser <keir.fraser@citrix.com> 6.14 + */ 6.15 + 6.16 +asm ( 6.17 + " .text \n" 6.18 + " .globl _start \n" 6.19 + "_start: \n" 6.20 + " mov $_start,%edi \n" 6.21 + " call 1f \n" 6.22 + "1: pop %esi \n" 6.23 + " sub $1b-_start,%esi \n" 6.24 + " mov $__bss_start-_start,%ecx \n" 6.25 + " rep movsb \n" 6.26 + " xor %eax,%eax \n" 6.27 + " mov $_end,%ecx \n" 6.28 + " sub %edi,%ecx \n" 6.29 + " rep stosb \n" 6.30 + " mov $reloc,%eax \n" 6.31 + " jmp *%eax \n" 6.32 + ); 6.33 + 6.34 +typedef unsigned int u32; 6.35 +#include "../../../include/xen/multiboot.h" 6.36 + 6.37 +extern char _start[]; 6.38 + 6.39 +static void *memcpy(void *dest, const void *src, unsigned int n) 6.40 +{ 6.41 + char *s = (char *)src, *d = dest; 6.42 + while ( n-- ) 6.43 + *d++ = *s++; 6.44 + return dest; 6.45 +} 6.46 + 6.47 +static void *reloc_mbi_struct(void *old, unsigned int bytes) 6.48 +{ 6.49 + static void *alloc = &_start; 6.50 + alloc = (void *)(((unsigned long)alloc - bytes) & ~15ul); 6.51 + return memcpy(alloc, old, bytes); 6.52 +} 6.53 + 6.54 +multiboot_info_t *reloc(multiboot_info_t *mbi_old) 6.55 +{ 6.56 + multiboot_info_t *mbi = reloc_mbi_struct(mbi_old, sizeof(*mbi)); 6.57 + 6.58 + if ( mbi->flags & MBI_CMDLINE ) 6.59 + { 6.60 + char *cmdline_old, *p; 6.61 + cmdline_old = (char *)mbi->cmdline; 6.62 + for ( p = cmdline_old; *p != '\0'; p++ ) 6.63 + continue; 6.64 + mbi->cmdline = (u32)reloc_mbi_struct(cmdline_old, p - cmdline_old + 1); 6.65 + } 6.66 + 6.67 + if ( mbi->flags & MBI_MODULES ) 6.68 + mbi->mods_addr = (u32)reloc_mbi_struct( 6.69 + (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t)); 6.70 + 6.71 + if ( mbi->flags & MBI_MEMMAP ) 6.72 + mbi->mmap_addr = (u32)reloc_mbi_struct( 6.73 + (memory_map_t *)mbi->mmap_addr, mbi->mmap_length); 6.74 + 6.75 + /* Mask features we don't understand or don't relocate. */ 6.76 + mbi->flags &= (MBI_MEMLIMITS | 6.77 + MBI_DRIVES | 6.78 + MBI_CMDLINE | 6.79 + MBI_MODULES | 6.80 + MBI_MEMMAP); 6.81 + 6.82 + return mbi; 6.83 +}