On Wed, Mar 28, 2007 at 03:00:08PM +0100, Paul Brook wrote: > On Wednesday 28 March 2007 03:21, Daniel Jacobowitz wrote: > > On Wed, Mar 28, 2007 at 12:35:18AM +0100, Thiemo Seufer wrote: > > > Right, a piggyback-style loader would likely fail in that case. > > > > Which is exactly the interesting case for x86_64. So, since Paul's > > verified that grub and lilo just put them far apart, maybe bumping up > > the size is the right thing to do. Or always putting the initrd at > > the top of emulated RAM. > > I'd prefer the latter, so that both big and small machines work. Linux still > (just about) boots on 8Mb machines.
Like this? I can't reliably test that it fixes the problem - for some bizarre reason, I can now load kernels without this patch. But it looks right and I can load kernels with it, too. -- Daniel Jacobowitz CodeSourcery --- hw/pc.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) Index: qemu/hw/pc.c =================================================================== --- qemu.orig/hw/pc.c 2007-03-31 11:36:34.000000000 -0400 +++ qemu/hw/pc.c 2007-03-31 11:38:24.000000000 -0400 @@ -32,7 +32,6 @@ #define LINUX_BOOT_FILENAME "linux_boot.bin" #define KERNEL_LOAD_ADDR 0x00100000 -#define INITRD_LOAD_ADDR 0x00600000 #define KERNEL_PARAMS_ADDR 0x00090000 #define KERNEL_CMDLINE_ADDR 0x00099000 @@ -452,6 +451,7 @@ static void pc_init1(int ram_size, int v char buf[1024]; int ret, linux_boot, initrd_size, i; ram_addr_t ram_addr, vga_ram_addr, bios_offset, vga_bios_offset; + ram_addr_t initrd_offset; int bios_size, isa_bios_size, vga_bios_size; PCIBus *pci_bus; int piix3_devfn = -1; @@ -599,8 +599,21 @@ static void pc_init1(int ram_size, int v /* load initrd */ initrd_size = 0; + initrd_offset = 0; if (initrd_filename) { - initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR); + initrd_size = get_image_size (initrd_filename); + if (initrd_size > 0) { + initrd_offset = ram_size - initrd_size; + if (initrd_size > ram_size || + initrd_offset < KERNEL_LOAD_ADDR + ret) { + fprintf(stderr, + "qemu: memory too small for initial ram disk '%s'\n", + initrd_filename); + exit(1); + } + initrd_size = load_image(initrd_filename, + phys_ram_base + initrd_offset); + } if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", initrd_filename); @@ -608,7 +621,7 @@ static void pc_init1(int ram_size, int v } } if (initrd_size > 0) { - stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR); + stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, initrd_offset); stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size); } pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,