Patchwork [1/2] ARM: Add "-uboot" option.

login
register
mail settings
Submitter Evgeny Voevodin
Date Feb. 22, 2012, 6:58 a.m.
Message ID <1329893896-28459-2-git-send-email-e.voevodin@samsung.com>
Download mbox | patch
Permalink /patch/142400/
State New
Headers show

Comments

Evgeny Voevodin - Feb. 22, 2012, 6:58 a.m.
With this option board can load U-Boot into address specified
through arm_boot_info.uboot_start.

Signed-off-by: Evgeny Voevodin <e.voevodin@samsung.com>
---
 hw/arm-misc.h   |    1 +
 hw/arm_boot.c   |   51 ++++++++++++++++++++++++++++++++++++++-------------
 qemu-options.hx |    8 ++++++++
 sysemu.h        |    1 +
 vl.c            |    4 ++++
 5 files changed, 52 insertions(+), 13 deletions(-)

Patch

diff --git a/hw/arm-misc.h b/hw/arm-misc.h
index 306013a..54a9450 100644
--- a/hw/arm-misc.h
+++ b/hw/arm-misc.h
@@ -29,6 +29,7 @@  struct arm_boot_info {
     const char *kernel_filename;
     const char *kernel_cmdline;
     const char *initrd_filename;
+    target_phys_addr_t uboot_start;
     target_phys_addr_t loader_start;
     /* multicore boards that use the default secondary core boot functions
      * need to put the address of the secondary boot code, the boot reg,
diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 2ef25ca..0700884 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -15,6 +15,7 @@ 
 
 #define KERNEL_ARGS_ADDR 0x100
 #define KERNEL_LOAD_ADDR 0x00010000
+#define UIMAGE_LOAD_ADDR 0x00007fc0
 #define INITRD_LOAD_ADDR 0x00d00000
 
 /* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
@@ -236,7 +237,7 @@  static void do_cpu_reset(void *opaque)
 
 void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
 {
-    int kernel_size;
+    int kernel_size, uboot_size;
     int initrd_size;
     int n;
     int is_linux = 0;
@@ -266,19 +267,43 @@  void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
     big_endian = 0;
 #endif
 
-    /* Assume that raw images are linux kernels, and ELF images are not.  */
-    kernel_size = load_elf(info->kernel_filename, NULL, NULL, &elf_entry,
-                           NULL, NULL, big_endian, ELF_MACHINE, 1);
-    entry = elf_entry;
-    if (kernel_size < 0) {
-        kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
-                                  &is_linux);
-    }
-    if (kernel_size < 0) {
-        entry = info->loader_start + KERNEL_LOAD_ADDR;
-        kernel_size = load_image_targphys(info->kernel_filename, entry,
-                                          ram_size - KERNEL_LOAD_ADDR);
+    if (uboot_name != NULL) {
+
+        entry = info->uboot_start;
+
+        if (!entry) {
+            fprintf(stderr, "Entry point for u-boot must be specified\n");
+            exit(1);
+        }
+
+        uboot_size =
+                load_image_targphys(uboot_name, entry, info->ram_size);
+        if (uboot_size < 0) {
+            fprintf(stderr, "qemu: could not load u-boot '%s'\n", uboot_name);
+            exit(1);
+        }
+
+        kernel_size = load_image_targphys(info->kernel_filename,
+                info->loader_start + UIMAGE_LOAD_ADDR,
+                info->ram_size - uboot_size);
         is_linux = 1;
+
+    } else { /* uboot_name == NULL */
+
+        /* Assume that raw images are linux kernels, and ELF images are not.  */
+        kernel_size = load_elf(info->kernel_filename, NULL, NULL, &elf_entry,
+                NULL, NULL, big_endian, ELF_MACHINE, 1);
+        entry = elf_entry;
+        if (kernel_size < 0) {
+            kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
+                    &is_linux);
+        }
+        if (kernel_size < 0) {
+            entry = info->loader_start + KERNEL_LOAD_ADDR;
+            kernel_size = load_image_targphys(info->kernel_filename, entry,
+                    ram_size - KERNEL_LOAD_ADDR);
+            is_linux = 1;
+        }
     }
     if (kernel_size < 0) {
         fprintf(stderr, "qemu: could not load kernel '%s'\n",
diff --git a/qemu-options.hx b/qemu-options.hx
index b129996..d498fbb 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2336,6 +2336,14 @@  STEXI
 Set the filename for the BIOS.
 ETEXI
 
+DEF("uboot", HAS_ARG, QEMU_OPTION_uboot, \
+    "-uboot file     set the filename for the U-Boot\n", QEMU_ARCH_ARM)
+STEXI
+@item -uboot @var{file}
+@findex -uboot
+Set the filename for the U-Boot.
+ETEXI
+
 DEF("enable-kvm", 0, QEMU_OPTION_enable_kvm, \
     "-enable-kvm     enable KVM full virtualization support\n", QEMU_ARCH_ALL)
 STEXI
diff --git a/sysemu.h b/sysemu.h
index 9d5ce33..116a4ff 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -13,6 +13,7 @@ 
 /* vl.c */
 
 extern const char *bios_name;
+extern const char *uboot_name;
 
 extern const char *qemu_name;
 extern uint8_t qemu_uuid[];
diff --git a/vl.c b/vl.c
index d8a521a..b3c68cb 100644
--- a/vl.c
+++ b/vl.c
@@ -176,6 +176,7 @@  int main(int argc, char **argv)
 
 static const char *data_dir;
 const char *bios_name = NULL;
+const char *uboot_name = NULL;
 enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
 DisplayType display_type = DT_DEFAULT;
 int display_remote = 0;
@@ -2617,6 +2618,9 @@  int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_bios:
                 bios_name = optarg;
                 break;
+            case QEMU_OPTION_uboot:
+                uboot_name = optarg;
+                break;
             case QEMU_OPTION_singlestep:
                 singlestep = 1;
                 break;