Commit a80274c31bd94f7a345934d2544075a6d183ebac

Authored by pbrook
1 parent 0aeaa8ce

Large kernel initrd fix (initial patch by Daniel Jacobowitz).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2562 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 26 additions and 3 deletions
@@ -32,9 +32,11 @@ @@ -32,9 +32,11 @@
32 #define LINUX_BOOT_FILENAME "linux_boot.bin" 32 #define LINUX_BOOT_FILENAME "linux_boot.bin"
33 33
34 #define KERNEL_LOAD_ADDR 0x00100000 34 #define KERNEL_LOAD_ADDR 0x00100000
35 -#define INITRD_LOAD_ADDR 0x00600000 35 +#define MAX_INITRD_LOAD_ADDR 0x38000000
36 #define KERNEL_PARAMS_ADDR 0x00090000 36 #define KERNEL_PARAMS_ADDR 0x00090000
37 #define KERNEL_CMDLINE_ADDR 0x00099000 37 #define KERNEL_CMDLINE_ADDR 0x00099000
  38 +/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
  39 +#define ACPI_DATA_SIZE 0x10000
38 40
39 static fdctrl_t *floppy_controller; 41 static fdctrl_t *floppy_controller;
40 static RTCState *rtc_state; 42 static RTCState *rtc_state;
@@ -452,6 +454,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, @@ -452,6 +454,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
452 char buf[1024]; 454 char buf[1024];
453 int ret, linux_boot, initrd_size, i; 455 int ret, linux_boot, initrd_size, i;
454 ram_addr_t ram_addr, vga_ram_addr, bios_offset, vga_bios_offset; 456 ram_addr_t ram_addr, vga_ram_addr, bios_offset, vga_bios_offset;
  457 + ram_addr_t initrd_offset;
455 int bios_size, isa_bios_size, vga_bios_size; 458 int bios_size, isa_bios_size, vga_bios_size;
456 PCIBus *pci_bus; 459 PCIBus *pci_bus;
457 int piix3_devfn = -1; 460 int piix3_devfn = -1;
@@ -599,8 +602,28 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, @@ -599,8 +602,28 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
599 602
600 /* load initrd */ 603 /* load initrd */
601 initrd_size = 0; 604 initrd_size = 0;
  605 + initrd_offset = 0;
602 if (initrd_filename) { 606 if (initrd_filename) {
603 - initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR); 607 + initrd_size = get_image_size (initrd_filename);
  608 + if (initrd_size > 0) {
  609 + initrd_offset = (ram_size - initrd_size) & TARGET_PAGE_MASK;
  610 + /* Leave space for BIOS ACPI tables. */
  611 + initrd_offset -= ACPI_DATA_SIZE;
  612 + /* Avoid the last 64k to avoid 2.2.x kernel bugs. */
  613 + initrd_offset -= 0x10000;
  614 + if (initrd_offset > MAX_INITRD_LOAD_ADDR)
  615 + initrd_offset = MAX_INITRD_LOAD_ADDR;
  616 +
  617 + if (initrd_size > ram_size
  618 + || initrd_offset < KERNEL_LOAD_ADDR + ret) {
  619 + fprintf(stderr,
  620 + "qemu: memory too small for initial ram disk '%s'\n",
  621 + initrd_filename);
  622 + exit(1);
  623 + }
  624 + initrd_size = load_image(initrd_filename,
  625 + phys_ram_base + initrd_offset);
  626 + }
604 if (initrd_size < 0) { 627 if (initrd_size < 0) {
605 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 628 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
606 initrd_filename); 629 initrd_filename);
@@ -608,7 +631,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, @@ -608,7 +631,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
608 } 631 }
609 } 632 }
610 if (initrd_size > 0) { 633 if (initrd_size > 0) {
611 - stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR); 634 + stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, initrd_offset);
612 stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size); 635 stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
613 } 636 }
614 pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096, 637 pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,