]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
x86_32: Relocate multiboot modules to below 1GB.
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 24 Mar 2010 11:19:55 +0000 (11:19 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 24 Mar 2010 11:19:55 +0000 (11:19 +0000)
Otherwise Xen cannot access them later during boot. GRUB2 places
modules as high as possible below 4GB, which has been causing boot
failure.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen-unstable changeset:   21051:bcc09eb7379f
xen-unstable date:        Tue Mar 23 07:28:33 2010 +0000

Fix 21051:bcc09eb7379f "x86_32: Relocate multiboot modules to below 1GB."

Copy the modules in ascending order in memory, rather than decsending
order. This reduces the likelihood of the second relocation (in
setup.c) corrupting modules through accidental overwriting.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen-unstable changeset:   21060:377433a77d70
xen-unstable date:        Wed Mar 24 11:06:48 2010 +0000

xen/arch/x86/boot/Makefile
xen/arch/x86/boot/build32.mk
xen/arch/x86/boot/reloc.c

index 90856f918e77ce8ffb91467905ebe397a57360e7..630b19d027d8ce5d968c491a7c28d8d63fd6af0a 100644 (file)
@@ -4,6 +4,6 @@ head.o: reloc.S
 
 BOOT_TRAMPOLINE := $(shell sed -n 's,^\#define[[:space:]]\+BOOT_TRAMPOLINE[[:space:]]\+,,p' $(BASEDIR)/include/asm-x86/config.h)
 %.S: %.c
-       RELOC=$(BOOT_TRAMPOLINE) $(MAKE) -f build32.mk $@
+       RELOC=$(BOOT_TRAMPOLINE) XEN_BITSPERLONG=$(patsubst x86_%,%,$(TARGET_SUBARCH)) $(MAKE) -f build32.mk $@
 
 reloc.S: $(BASEDIR)/include/asm-x86/config.h
index 01f7480b52e23b8746dc8e59b0e4e723d65a944b..0de9c15af2878cca6dea96eb7f996e8e2c8c83ef 100644 (file)
@@ -22,6 +22,6 @@ CFLAGS += -Werror -fno-builtin -msoft-float
        $(LD) $(LDFLAGS_DIRECT) -N -Ttext $(RELOC) -o $@ $<
 
 %.o: %.c
-       $(CC) $(CFLAGS) -c $< -o $@
+       $(CC) $(CFLAGS) -DXEN_BITSPERLONG=$(XEN_BITSPERLONG) -c $< -o $@
 
 reloc.o: $(BASEDIR)/include/asm-x86/config.h
index e3333d36b8880e145a6fe64f258472561b898c28..47b558b29cd3d468d15c9d6319657c9ec5f0f40a 100644 (file)
@@ -68,10 +68,38 @@ multiboot_info_t *reloc(multiboot_info_t *mbi_old)
     {
         module_t *mods = reloc_mbi_struct(
             (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t));
+        u32 max_addr = 0;
+
         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 ( mods[i].mod_end > max_addr )
+                max_addr = mods[i].mod_end;
+        }
+
+        /*
+         * 32-bit Xen only maps bottom 1GB of memory at boot time. Relocate 
+         * modules which extend beyond this (GRUB2 in particular likes to 
+         * place modules as high as possible below 4GB).
+         */
+#define BOOTMAP_END (1ul<<30) /* 1GB */
+        if ( (XEN_BITSPERLONG == 32) && (max_addr > BOOTMAP_END) )
+        {
+            char *mod_alloc = (char *)BOOTMAP_END;
+            for ( i = 0; i < mbi->mods_count; i++ )
+                mod_alloc -= mods[i].mod_end - mods[i].mod_start;
+            for ( i = 0; i < mbi->mods_count; i++ )
+            {
+                u32 mod_len = mods[i].mod_end - mods[i].mod_start;
+                mods[i].mod_start = (u32)memcpy(
+                    mod_alloc, (char *)mods[i].mod_start, mod_len);
+                mods[i].mod_end = mods[i].mod_start + mod_len;
+                mod_alloc += mod_len;
+            }
+        }
     }
 
     if ( mbi->flags & MBI_MEMMAP )