]> git.proxmox.com Git - qemu.git/commitdiff
Fix loading of ELF multiboot kernels
authorKevin Wolf <kwolf@redhat.com>
Fri, 4 Dec 2009 16:19:25 +0000 (17:19 +0100)
committerAnthony Liguori <aliguori@us.ibm.com>
Sat, 19 Dec 2009 14:26:20 +0000 (08:26 -0600)
The multiboot implementation assumed that there is only one program header
(which contains the entry point) and that the entry point is at the start of
the code. This doesn't hold true generally and caused too little data to be
loaded.

Fix the loading code to pass the whole loaded data to the Multiboot Option ROM.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 092493be3caab1ac77f4223b4c3fb0975d1ed490)

hw/loader.c
hw/pc.c

index 2d7a2c49541524040d873f808303c100baf43477..4c6981fc40c3eeb14e25b24c066dd9b92414d8eb 100644 (file)
@@ -718,8 +718,6 @@ int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
     QTAILQ_FOREACH(rom, &roms, next) {
         if (rom->max)
             continue;
-        if (rom->min > addr)
-            continue;
         if (rom->min + rom->romsize < addr)
             continue;
         if (rom->min > end)
diff --git a/hw/pc.c b/hw/pc.c
index 147a9a70220f0d935993907e16afecd260cf76d1..e8db664115652c2a1fc460540ad85c67e7ad7f20 100644 (file)
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -560,19 +560,21 @@ static int load_multiboot(void *fw_cfg,
     }
     if (!(flags & 0x00010000)) { /* MULTIBOOT_HEADER_HAS_ADDR */
         uint64_t elf_entry;
+        uint64_t elf_low, elf_high;
         int kernel_size;
         fclose(f);
-        kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
+        kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_low, &elf_high,
                                0, ELF_MACHINE, 0);
         if (kernel_size < 0) {
             fprintf(stderr, "Error while loading elf kernel\n");
             exit(1);
         }
-        mh_load_addr = mh_entry_addr = elf_entry;
-        mb_kernel_size = kernel_size;
+        mh_load_addr = elf_low;
+        mb_kernel_size = elf_high - elf_low;
+        mh_entry_addr = elf_entry;
 
         mb_kernel_data = qemu_malloc(mb_kernel_size);
-        if (rom_copy(mb_kernel_data, elf_entry, kernel_size) != kernel_size) {
+        if (rom_copy(mb_kernel_data, mh_load_addr, mb_kernel_size) != mb_kernel_size) {
             fprintf(stderr, "Error while fetching elf kernel from rom\n");
             exit(1);
         }