aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc_oldworld.c
diff options
context:
space:
mode:
authoraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2009-01-26 10:22:15 +0000
committeraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2009-01-26 10:22:15 +0000
commit36bee1e3a4bce569e3f3ab4627e5a379a717bc48 (patch)
treeed3d0f40830db3a1f01cda7be610d8fb39bd59b7 /hw/ppc_oldworld.c
parent947f5fcbde4836d22386bb83e6839322912979a6 (diff)
target-ppc: always load kernel to KERNEL_LOAD_ADDR
Linux changed its physical address location in the elf header from 0xc0000000 to 0 on 2.6.25, causing later kernels to fail booting with the -kernel option. This patch assures that the lowest segment in the elf binary is loaded to KERNEL_LOAD_ADDR, which is where the firmware expects it. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6437 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/ppc_oldworld.c')
-rw-r--r--hw/ppc_oldworld.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 042a40feea..fa8d106c83 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -207,10 +207,16 @@ static void ppc_heathrow_init (ram_addr_t ram_size, int vga_ram_size,
}
if (linux_boot) {
+ uint64_t lowaddr = 0;
kernel_base = KERNEL_LOAD_ADDR;
- /* now we can load the kernel */
- kernel_size = load_elf(kernel_filename, kernel_base - 0xc0000000ULL,
- NULL, NULL, NULL);
+ /* Now we can load the kernel. The first step tries to load the kernel
+ supposing PhysAddr = 0x00000000. If that was wrong the kernel is
+ loaded again, the new PhysAddr being computed from lowaddr. */
+ kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL);
+ if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) {
+ kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
+ NULL, 0, NULL);
+ }
if (kernel_size < 0)
kernel_size = load_aout(kernel_filename, kernel_base,
ram_size - kernel_base);