The second shortest bootloader (hw/arm_boot.c) assumes that the RAM is
mapped at address 0 in the machine (which is false for probably more
than half of the registered ARM machines), so this adds an additional
argument to arm_load_kernel() that should receive the RAM start
address. It will offset the addresses passed in r1 and r2 and in ATAGS
by this value.

Cheers,
Andrew
From 18cc65714e1de31a0060ee81292d75cd0874a849 Mon Sep 17 00:00:00 2001
From: Andrzej Zaborowski <[EMAIL PROTECTED]>
Date: Fri, 16 Mar 2007 17:23:12 +0100
Subject: [PATCH] Account for RAM not mapped at 0x0 in arm_boot.c.

---
 hw/arm_boot.c     |   19 ++++++++++---------
 hw/integratorcp.c |    2 +-
 hw/realview.c     |    2 +-
 hw/spitz.c        |    2 +-
 hw/versatilepb.c  |    2 +-
 target-arm/cpu.h  |    3 ++-
 vl.h              |    2 +-
 7 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index dfc00db..91bd783 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -32,11 +32,12 @@ static void main_cpu_reset(void *opaque)
     if (env->kernel_filename)
         arm_load_kernel(env, env->ram_size, env->kernel_filename, 
                         env->kernel_cmdline, env->initrd_filename, 
-                        env->board_id);
+                        env->board_id, env->loader_start);
 }
 
 static void set_kernel_args(uint32_t ram_size, int initrd_size,
-                            const char *kernel_cmdline)
+                            const char *kernel_cmdline,
+                            target_phys_addr_t loader_start)
 {
     uint32_t *p;
 
@@ -51,12 +52,12 @@ static void set_kernel_args(uint32_t ram_size, int 
initrd_size,
     stl_raw(p++, 4);
     stl_raw(p++, 0x54410002);
     stl_raw(p++, ram_size);
-    stl_raw(p++, 0);
+    stl_raw(p++, loader_start);
     if (initrd_size) {
         /* ATAG_INITRD2 */
         stl_raw(p++, 4);
         stl_raw(p++, 0x54420005);
-        stl_raw(p++, INITRD_LOAD_ADDR);
+        stl_raw(p++, loader_start + INITRD_LOAD_ADDR);
         stl_raw(p++, initrd_size);
     }
     if (kernel_cmdline && *kernel_cmdline) {
@@ -77,7 +78,7 @@ static void set_kernel_args(uint32_t ram_size, int 
initrd_size,
 
 void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename,
                      const char *kernel_cmdline, const char *initrd_filename,
-                     int board_id)
+                     int board_id, target_phys_addr_t loader_start)
 {
     int kernel_size;
     int initrd_size;
@@ -98,6 +99,7 @@ void arm_load_kernel(CPUState *env, int ram_size, const char 
*kernel_filename,
         env->kernel_cmdline = kernel_cmdline;
         env->initrd_filename = initrd_filename;
         env->board_id = board_id;
+        env->loader_start = loader_start;
         qemu_register_reset(main_cpu_reset, env);
     }
     /* Assume that raw images are linux kernels, and ELF images are not.  */
@@ -109,7 +111,7 @@ void arm_load_kernel(CPUState *env, int ram_size, const 
char *kernel_filename,
     if (kernel_size < 0) {
         kernel_size = load_image(kernel_filename,
                                  phys_ram_base + KERNEL_LOAD_ADDR);
-        entry = KERNEL_LOAD_ADDR;
+        entry = loader_start + KERNEL_LOAD_ADDR;
         is_linux = 1;
     }
     if (kernel_size < 0) {
@@ -134,11 +136,10 @@ void arm_load_kernel(CPUState *env, int ram_size, const 
char *kernel_filename,
         }
         bootloader[1] |= board_id & 0xff;
         bootloader[2] |= (board_id >> 8) & 0xff;
-        bootloader[5] = KERNEL_ARGS_ADDR;
+        bootloader[5] = loader_start + KERNEL_ARGS_ADDR;
         bootloader[6] = entry;
         for (n = 0; n < sizeof(bootloader) / 4; n++)
             stl_raw(phys_ram_base + (n * 4), bootloader[n]);
-        set_kernel_args(ram_size, initrd_size, kernel_cmdline);
+        set_kernel_args(ram_size, initrd_size, kernel_cmdline, loader_start);
     }
 }
-
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 5e4c636..cb9469c 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -512,7 +512,7 @@ static void integratorcp_init(int ram_size, int 
vga_ram_size, int boot_device,
     pl110_init(ds, 0xc0000000, pic, 22, 0);
 
     arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
-                    initrd_filename, 0x113);
+                    initrd_filename, 0x113, 0x0);
 }
 
 QEMUMachine integratorcp_machine = {
diff --git a/hw/realview.c b/hw/realview.c
index a5607e7..ca3c0f0 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -129,7 +129,7 @@ static void realview_init(int ram_size, int vga_ram_size, 
int boot_device,
     /* 0x6c000000 PCI mem 2.  */
 
     arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
-                    initrd_filename, 0x33b);
+                    initrd_filename, 0x33b, 0x0);
 }
 
 QEMUMachine realview_machine = {
diff --git a/hw/spitz.c b/hw/spitz.c
index 7ce6497..a434721 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1092,7 +1092,7 @@ static void spitz_common_init(int ram_size, int 
vga_ram_size,
     cpu->env->regs[15] = PXA2XX_RAM_BASE;
 
     arm_load_kernel(cpu->env, ram_size, kernel_filename, kernel_cmdline,
-                    initrd_filename, arm_id);
+                    initrd_filename, arm_id, PXA2XX_RAM_BASE);
     sl_bootparam_write(SL_PXA_PARAM_BASE - PXA2XX_RAM_BASE);
 }
 
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 5d3e857..38c69f7 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -254,7 +254,7 @@ static void versatile_init(int ram_size, int vga_ram_size, 
int boot_device,
     /* 0x101f4000 SSPI.  */
 
     arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
-                    initrd_filename, board_id);
+                    initrd_filename, board_id, 0x0);
 }
 
 static void vpb_init(int ram_size, int vga_ram_size, int boot_device,
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 530acb2..7a37c41 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -143,12 +143,13 @@ typedef struct CPUARMState {
 
     CPU_COMMON
 
-    /* These fields after the common ones so thes are preserved on reset.  */
+    /* These fields after the common ones so they are preserved on reset.  */
     int ram_size;
     const char *kernel_filename;
     const char *kernel_cmdline;
     const char *initrd_filename;
     int board_id;
+    target_phys_addr_t loader_start;
 } CPUARMState;
 
 CPUARMState *cpu_arm_init(void);
diff --git a/vl.h b/vl.h
index 6b1e833..3eb204a 100644
--- a/vl.h
+++ b/vl.h
@@ -1366,7 +1366,7 @@ void *arm_gic_init(uint32_t base, void *parent, int 
parent_irq);
 
 void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename,
                      const char *kernel_cmdline, const char *initrd_filename,
-                     int board_id);
+                     int board_id, target_phys_addr_t loader_start);
 
 /* sh7750.c */
 struct SH7750State;
-- 
1.4.4.3

_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to