[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86: Relocate Multiboot structures where we know they will be



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1233684663 0
# Node ID aca402831ac1eb8086e58370d51360a72c39e39b
# Parent  d68178692b7ce1c8dc02fc78f1c131ecf8f410a7
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@xxxxxxxxxx>
---
 .hgignore                    |   10 -----
 xen/arch/x86/Makefile        |    1 
 xen/arch/x86/boot/Makefile   |    6 +++
 xen/arch/x86/boot/build32.mk |   24 ++++++++++++
 xen/arch/x86/boot/head.S     |   10 ++++-
 xen/arch/x86/boot/reloc.c    |   80 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 120 insertions(+), 11 deletions(-)

diff -r d68178692b7c -r aca402831ac1 .hgignore
--- a/.hgignore Tue Feb 03 14:06:51 2009 +0000
+++ b/.hgignore Tue Feb 03 18:11:03 2009 +0000
@@ -256,6 +256,7 @@
 ^xen/arch/x86/asm-offsets\.s$
 ^xen/arch/x86/boot/mkelf32$
 ^xen/arch/x86/xen\.lds$
+^xen/arch/x86/boot/reloc.S$
 ^xen/ddb/.*$
 ^xen/include/asm$
 ^xen/include/asm-.*/asm-offsets\.h$
@@ -279,15 +280,6 @@
 ^xen/arch/ia64/asm-xsi-offsets\.s$
 ^xen/arch/ia64/map\.out$
 ^xen/arch/ia64/xen\.lds\.s$
-^xen/arch/powerpc/dom0\.bin$
-^xen/arch/powerpc/asm-offsets\.s$
-^xen/arch/powerpc/firmware$
-^xen/arch/powerpc/firmware.dbg$
-^xen/arch/powerpc/firmware_image.bin$
-^xen/arch/powerpc/xen\.lds$
-^xen/arch/powerpc/\.xen-syms$
-^xen/arch/powerpc/xen-syms\.S$
-^xen/arch/powerpc/cmdline.dep$
 ^unmodified_drivers/linux-2.6/\.tmp_versions
 ^unmodified_drivers/linux-2.6/.*\.cmd$
 ^unmodified_drivers/linux-2.6/.*\.ko$
diff -r d68178692b7c -r aca402831ac1 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Tue Feb 03 14:06:51 2009 +0000
+++ b/xen/arch/x86/Makefile     Tue Feb 03 18:11:03 2009 +0000
@@ -92,3 +92,4 @@ clean::
 clean::
        rm -f asm-offsets.s xen.lds boot/*.o boot/*~ boot/core boot/mkelf32
        rm -f $(BASEDIR)/.xen-syms.[0-9]* boot/.*.d
+       rm -f boot/reloc.S boot/reloc.lnk boot/reloc.bin
diff -r d68178692b7c -r aca402831ac1 xen/arch/x86/boot/Makefile
--- a/xen/arch/x86/boot/Makefile        Tue Feb 03 14:06:51 2009 +0000
+++ b/xen/arch/x86/boot/Makefile        Tue Feb 03 18:11:03 2009 +0000
@@ -1,1 +1,7 @@ obj-y += head.o
 obj-y += head.o
+
+head.o: reloc.S
+
+# NB. BOOT_TRAMPOLINE == 0x8c000
+%.S: %.c
+       RELOC=0x8c000 $(MAKE) -f build32.mk $@
diff -r d68178692b7c -r aca402831ac1 xen/arch/x86/boot/build32.mk
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/boot/build32.mk      Tue Feb 03 18:11:03 2009 +0000
@@ -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 $@
diff -r d68178692b7c -r aca402831ac1 xen/arch/x86/boot/head.S
--- a/xen/arch/x86/boot/head.S  Tue Feb 03 14:06:51 2009 +0000
+++ b/xen/arch/x86/boot/head.S  Tue Feb 03 18:11:03 2009 +0000
@@ -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 @@ 2:      cmp     $L1_PAGETABLE_ENTRIES,%e
 
 #include "cmdline.S"
 
+reloc:
+#include "reloc.S"
+
         .align 16
         .globl trampoline_start, trampoline_end
 trampoline_start:
diff -r d68178692b7c -r aca402831ac1 xen/arch/x86/boot/reloc.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/boot/reloc.c Tue Feb 03 18:11:03 2009 +0000
@@ -0,0 +1,80 @@
+/******************************************************************************
+ * 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@xxxxxxxxxx>
+ */
+
+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);
+}
+
+multiboot_info_t *reloc(multiboot_info_t *mbi_old)
+{
+    multiboot_info_t *mbi = reloc_mbi_struct(mbi_old, sizeof(*mbi));
+
+    if ( mbi->flags & MBI_CMDLINE )
+    {
+        char *cmdline_old, *p;
+        cmdline_old = (char *)mbi->cmdline;
+        for ( p = cmdline_old; *p != '\0'; p++ )
+            continue;
+        mbi->cmdline = (u32)reloc_mbi_struct(cmdline_old, p - cmdline_old + 1);
+    }
+
+    if ( mbi->flags & MBI_MODULES )
+        mbi->mods_addr = (u32)reloc_mbi_struct(
+            (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t));
+
+    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;
+}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.