With this option board can load U-Boot into address specified through arm_boot_info.uboot_start.
Signed-off-by: Evgeny Voevodin <e.voevo...@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(-) 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; -- 1.7.5.4