Commit a80274c31bd94f7a345934d2544075a6d183ebac
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
hw/pc.c
@@ -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, |