The attached patch by Peter Jones <[EMAIL PROTECTED]> implements
intelligent placement of the ramdisk in memory during boot of an ELF
image created by mkelfimage.
mkelfimage prior to this patch defaults to a hardcoded 1MB which doesn't
quite work in all circumstances. The kernel as it is decompressed can
overwrite part of the ramdisk. Peter says that pretty much all other
boot loaders already do this intelligent detection instead of native
hard coding.
This patch allows a wrapped Fedora i586 kernel to boot on both KVM and
Artec Group's Thincan DBE61C (coreboot). It probably needs more testing
in other circumstances.
Thanks,
Warren Togami
[EMAIL PROTECTED]
diff -up mkelfImage-2.7/linux-i386/convert_params.c.ramdisk_base mkelfImage-2.7/linux-i386/convert_params.c
--- mkelfImage-2.7/linux-i386/convert_params.c.ramdisk_base 2006-03-27 18:44:59.000000000 -0500
+++ mkelfImage-2.7/linux-i386/convert_params.c 2008-05-21 12:55:44.000000000 -0400
@@ -1301,6 +1301,44 @@ static void query_firmware_values(struct
}
+static void relocate_ramdisk(struct param_info *info)
+{
+ struct e820entry *e820_map;
+ struct e820entry *highest = 0;
+ unsigned long load_addr;
+ int i;
+
+ e820_map = info->real_mode->e820_map;
+#if 0
+ printf("initrd_start = 0x%lx\n", info->real_mode->initrd_start);
+ printf("real_mode->e820_map_nr: %d\n", info->real_mode->e820_map_nr);
+#endif
+ for (i = 0; i < info->real_mode->e820_map_nr; i++) {
+ if (e820_map[i].type != E820_RAM)
+ continue;
+#if 0
+ printf("addr: 0x%lx len: %x\n", e820_map[i].addr, e820_map[i].size);
+#endif
+ if (highest && e820_map[i].addr < highest->addr)
+ continue;
+ if (e820_map[i].size < info->real_mode->initrd_size)
+ continue;
+ if (e820_map[i].addr + info->real_mode->initrd_size >= 0x38000000)
+ continue;
+ highest = &e820_map[i];
+ }
+
+ if (highest == 0)
+ return;
+
+ load_addr = highest->addr + highest->size;
+ load_addr -= info->real_mode->initrd_size;
+ load_addr &= ~0xfffUL;
+
+ memcpy((void *)load_addr, (void *)info->real_mode->initrd_start, info->real_mode->initrd_size);
+ printf("relocating ramdisk to 0x%lx\n", load_addr);
+ info->real_mode->initrd_start = load_addr;
+}
/*
* Debug
* =============================================================================
@@ -1533,6 +1571,10 @@ void *convert_params(unsigned type, void
query_firmware_class(&info);
query_firmware_values(&info);
query_bootloader_values(&info);
+ if (info.real_mode->initrd_size) {
+ /* Make sure the initrd is in a relatively safe place. */
+ relocate_ramdisk(&info);
+ }
/* Do the hardware setup that linux might forget... */
hardware_setup(&info);
diff -up mkelfImage-2.7/linux-i386/mkelf-linux-i386.c.ramdisk_base mkelfImage-2.7/linux-i386/mkelf-linux-i386.c
--- mkelfImage-2.7/linux-i386/mkelf-linux-i386.c.ramdisk_base 2006-03-17 09:08:22.000000000 -0500
+++ mkelfImage-2.7/linux-i386/mkelf-linux-i386.c 2008-05-21 10:47:42.000000000 -0400
@@ -352,6 +352,9 @@ int linux_i386_mkelf(int argc, char **ar
*/
params->initrd_start = params->initrd_size = 0;
if (ramdisk_size) {
+ while (ramdisk_base <= kernel_size)
+ ramdisk_base <<= 1;
+
phdr[index].p_paddr = ramdisk_base;
phdr[index].p_vaddr = ramdisk_base;
phdr[index].p_filesz = ramdisk_size;
--
coreboot mailing list
[email protected]
http://www.coreboot.org/mailman/listinfo/coreboot