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
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 042a40f..fa8d106 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -207,10 +207,16 @@
     }
 
     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);