@@ -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,
@@ -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",
@@ -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
@@ -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[];
@@ -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;
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(-)