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;