]> xenbits.xen.org Git - xenclient/xen.git/commitdiff
Changes to boot code to relocate the MBI.
authorRoss Philipson <ross.philipson@citrix.com>
Wed, 4 Feb 2009 19:13:30 +0000 (14:13 -0500)
committerRoss Philipson <ross.philipson@citrix.com>
Wed, 4 Feb 2009 19:13:30 +0000 (14:13 -0500)
This fix relocates the MBI and associated data to safe
memory locations before paging is enabled. This fixes the
issue with GRUB2 loading chunks of the MBI at very high
phys. addresses. These fixes are from xen-unstable change-
sets 19146 and 19158.

 Changes to be committed:
   (use "git reset HEAD <file>..." to unstage)

modified:   xen/arch/x86/Makefile
modified:   xen/arch/x86/boot/Makefile
new file:   xen/arch/x86/boot/build32.mk
modified:   xen/arch/x86/boot/head.S
new file:   xen/arch/x86/boot/reloc.c

xen/arch/x86/Makefile
xen/arch/x86/boot/Makefile
xen/arch/x86/boot/build32.mk [new file with mode: 0644]
xen/arch/x86/boot/head.S
xen/arch/x86/boot/reloc.c [new file with mode: 0644]

index eb9dd08f47f4610e582d573ac40167f194b105de..b2930ffea66562ab9bcf98bf79c13147048d7d89 100644 (file)
@@ -91,3 +91,4 @@ boot/mkelf32: boot/mkelf32.c
 clean::
        rm -f asm-offsets.s xen.lds boot/*.o boot/*~ boot/core boot/mkelf32
        rm -f $(BASEDIR)/.xen-syms.[0-9]*
+       rm -f boot/reloc.S boot/reloc.lnk boot/reloc.bin
index ce5c9350affa887beaf1945fdc6e55ccf86649bd..d9a7c3f963a5d673355cf58f099d376af6c413b4 100644 (file)
@@ -1,4 +1,7 @@
 obj-y += head.o
 
-head.o: head.S $(TARGET_SUBARCH).S trampoline.S mem.S video.S \
-       cmdline.S edd.S wakeup.S
+head.o: reloc.S
+
+# NB. BOOT_TRAMPOLINE == 0x8c000
+%.S: %.c
+       RELOC=0x8c000 $(MAKE) -f build32.mk $@
diff --git a/xen/arch/x86/boot/build32.mk b/xen/arch/x86/boot/build32.mk
new file mode 100644 (file)
index 0000000..3223bcf
--- /dev/null
@@ -0,0 +1,24 @@
+XEN_ROOT=../../../..
+override XEN_TARGET_ARCH=x86_32
+CFLAGS =
+include $(XEN_ROOT)/Config.mk
+
+# Disable PIE/SSP if GCC supports them. They can break us.
+$(call cc-option-add,CFLAGS,CC,-nopie)
+$(call cc-option-add,CFLAGS,CC,-fno-stack-protector)
+$(call cc-option-add,CFLAGS,CC,-fno-stack-protector-all)
+
+CFLAGS += -Werror -fno-builtin -msoft-float
+
+%.S: %.bin
+       (od -v -t x $< | head -n -1 | \
+       sed 's/ /,0x/g' | sed 's/^[0-9]*,/ .long /') >$@
+
+%.bin: %.lnk
+       $(OBJCOPY) -O binary $< $@
+
+%.lnk: %.o
+       $(LD) $(LDFLAGS_DIRECT) -N -Ttext 0x8c000 -o $@ $<
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c $< -o $@
index c10aa62b2d8e830976161ad32cba126c002be824..3360107aac04dc4d5be0452637e1aec61369fabf 100644 (file)
@@ -79,8 +79,11 @@ __start:
         cmp     $0x2BADB002,%eax
         jne     not_multiboot
 
-        /* Save the Multiboot info structure for later use. */
-        mov     %ebx,sym_phys(multiboot_ptr)
+        /* Save the Multiboot info struct (after relocation) for later use. */
+        mov     $sym_phys(cpu0_stack)+1024,%esp
+        push    %ebx
+        call    reloc
+        mov     %eax,sym_phys(multiboot_ptr)
 
         /* Initialize BSS (no nasty surprises!) */
         mov     $sym_phys(__bss_start),%edi
@@ -192,6 +195,9 @@ __start:
 
 #include "cmdline.S"
 
+reloc:
+#include "reloc.S"
+
         .align 16
         .globl trampoline_start, trampoline_end
 trampoline_start:
diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
new file mode 100644 (file)
index 0000000..e3333d3
--- /dev/null
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * reloc.c
+ * 
+ * 32-bit flat memory-map routines for relocating Multiboot structures
+ * and modules. This is most easily done early with paging disabled.
+ * 
+ * Copyright (c) 2009, Citrix Systems, Inc.
+ * 
+ * Authors:
+ *    Keir Fraser <keir.fraser@citrix.com>
+ */
+
+asm (
+    "    .text                         \n"
+    "    .globl _start                 \n"
+    "_start:                           \n"
+    "    mov  $_start,%edi             \n"
+    "    call 1f                       \n"
+    "1:  pop  %esi                     \n"
+    "    sub  $1b-_start,%esi          \n"
+    "    mov  $__bss_start-_start,%ecx \n"
+    "    rep  movsb                    \n"
+    "    xor  %eax,%eax                \n"
+    "    mov  $_end,%ecx               \n"
+    "    sub  %edi,%ecx                \n"
+    "    rep  stosb                    \n"
+    "    mov  $reloc,%eax              \n"
+    "    jmp  *%eax                    \n"
+    );
+
+typedef unsigned int u32;
+#include "../../../include/xen/multiboot.h"
+
+extern char _start[];
+
+static void *memcpy(void *dest, const void *src, unsigned int n)
+{
+    char *s = (char *)src, *d = dest;
+    while ( n-- )
+        *d++ = *s++;
+    return dest;
+}
+
+static void *reloc_mbi_struct(void *old, unsigned int bytes)
+{
+    static void *alloc = &_start;
+    alloc = (void *)(((unsigned long)alloc - bytes) & ~15ul);
+    return memcpy(alloc, old, bytes);
+}
+
+static char *reloc_mbi_string(char *old)
+{
+    char *p;
+    for ( p = old; *p != '\0'; p++ )
+        continue;
+    return reloc_mbi_struct(old, p - old + 1);
+}
+
+multiboot_info_t *reloc(multiboot_info_t *mbi_old)
+{
+    multiboot_info_t *mbi = reloc_mbi_struct(mbi_old, sizeof(*mbi));
+    int i;
+
+    if ( mbi->flags & MBI_CMDLINE )
+        mbi->cmdline = (u32)reloc_mbi_string((char *)mbi->cmdline);
+
+    if ( mbi->flags & MBI_MODULES )
+    {
+        module_t *mods = reloc_mbi_struct(
+            (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t));
+        mbi->mods_addr = (u32)mods;
+        for ( i = 0; i < mbi->mods_count; i++ )
+            if ( mods[i].string )
+                mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string);
+    }
+
+    if ( mbi->flags & MBI_MEMMAP )
+        mbi->mmap_addr = (u32)reloc_mbi_struct(
+            (memory_map_t *)mbi->mmap_addr, mbi->mmap_length);
+
+    /* Mask features we don't understand or don't relocate. */
+    mbi->flags &= (MBI_MEMLIMITS |
+                   MBI_DRIVES |
+                   MBI_CMDLINE |
+                   MBI_MODULES |
+                   MBI_MEMMAP);
+
+    return mbi;
+}