aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-03-23 07:28:33 +0000
committerKeir Fraser <keir.fraser@citrix.com>2010-03-23 07:28:33 +0000
commit61ecce504bab5f0ec96fde06a8554e5cceabb19e (patch)
tree7044334de464d96f9f5d7edaeab8cd6e498913d2
parent5bc8ad3bb763c0c0d3f0676e586838a1d478fb51 (diff)
downloadxen-61ecce504bab5f0ec96fde06a8554e5cceabb19e.tar.gz
xen-61ecce504bab5f0ec96fde06a8554e5cceabb19e.tar.bz2
xen-61ecce504bab5f0ec96fde06a8554e5cceabb19e.zip
x86_32: Relocate multiboot modules to below 1GB.
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>
-rw-r--r--xen/arch/x86/boot/Makefile2
-rw-r--r--xen/arch/x86/boot/build32.mk2
-rw-r--r--xen/arch/x86/boot/reloc.c20
3 files changed, 22 insertions, 2 deletions
diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile
index 90856f918e..630b19d027 100644
--- a/xen/arch/x86/boot/Makefile
+++ b/xen/arch/x86/boot/Makefile
@@ -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
diff --git a/xen/arch/x86/boot/build32.mk b/xen/arch/x86/boot/build32.mk
index 01f7480b52..0de9c15af2 100644
--- a/xen/arch/x86/boot/build32.mk
+++ b/xen/arch/x86/boot/build32.mk
@@ -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
diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index e3333d36b8..233a94f347 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -70,8 +70,28 @@ multiboot_info_t *reloc(multiboot_info_t *mbi_old)
(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 XEN_BITSPERLONG == 32
+ /*
+ * 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 */
+ static void *mod_alloc = (void *)BOOTMAP_END;
+ u32 mod_len = mods[i].mod_end - mods[i].mod_start;
+ if ( mods[i].mod_end > BOOTMAP_END )
+ {
+ mod_alloc = (void *)
+ (((unsigned long)mod_alloc - mod_len) & ~15ul);
+ 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;
+ }
+#endif
if ( mods[i].string )
mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string);
+ }
}
if ( mbi->flags & MBI_MEMMAP )