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>
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 +}