From daf90626beeb5f20504c593f01604a554f7ef232 Mon Sep 17 00:00:00 2001 From: pbrook Date: Tue, 16 Jan 2007 18:54:31 +0000 Subject: ARM ELF loader. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2320 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/arm_boot.c | 54 ++++++++++++++++++++++++++++++++---------------------- hw/integratorcp.c | 2 +- hw/realview.c | 2 +- hw/versatilepb.c | 2 +- 4 files changed, 35 insertions(+), 25 deletions(-) (limited to 'hw') diff --git a/hw/arm_boot.c b/hw/arm_boot.c index 0e28d4a..f62f0f6 100644 --- a/hw/arm_boot.c +++ b/hw/arm_boot.c @@ -64,42 +64,52 @@ static void set_kernel_args(uint32_t ram_size, int initrd_size, stl_raw(p++, 0); } -void arm_load_kernel(int ram_size, const char *kernel_filename, +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 kernel_size; int initrd_size; int n; + uint64_t entry; /* Load the kernel. */ if (!kernel_filename) { fprintf(stderr, "Kernel image must be specified\n"); exit(1); } - kernel_size = load_image(kernel_filename, - phys_ram_base + KERNEL_LOAD_ADDR); - if (kernel_size < 0) { - fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); - exit(1); - } - if (initrd_filename) { - initrd_size = load_image(initrd_filename, - phys_ram_base + INITRD_LOAD_ADDR); - if (initrd_size < 0) { - fprintf(stderr, "qemu: could not load initrd '%s'\n", - initrd_filename); + + kernel_size = load_elf(kernel_filename, 0, &entry); + if (kernel_size) { + /* An ELF image. Jump to the entry point. */ + env->regs[15] = entry & 0xfffffffe; + env->thumb = entry & 1; + } else { + /* Raw binary image. Assume it is a Limux zImage. */ + kernel_size = load_image(kernel_filename, + phys_ram_base + KERNEL_LOAD_ADDR); + if (kernel_size < 0) { + fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } - } else { - initrd_size = 0; + if (initrd_filename) { + initrd_size = load_image(initrd_filename, + phys_ram_base + INITRD_LOAD_ADDR); + if (initrd_size < 0) { + fprintf(stderr, "qemu: could not load initrd '%s'\n", + initrd_filename); + exit(1); + } + } else { + initrd_size = 0; + } + bootloader[1] |= board_id & 0xff; + bootloader[2] |= (board_id >> 8) & 0xff; + bootloader[5] = KERNEL_ARGS_ADDR; + bootloader[6] = KERNEL_LOAD_ADDR; + 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); } - bootloader[1] |= board_id & 0xff; - bootloader[2] |= (board_id >> 8) & 0xff; - bootloader[5] = KERNEL_ARGS_ADDR; - bootloader[6] = KERNEL_LOAD_ADDR; - 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); } diff --git a/hw/integratorcp.c b/hw/integratorcp.c index 17dca28..4e5f4ac 100644 --- a/hw/integratorcp.c +++ b/hw/integratorcp.c @@ -509,7 +509,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(ram_size, kernel_filename, kernel_cmdline, + arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline, initrd_filename, 0x113); } diff --git a/hw/realview.c b/hw/realview.c index 6d057ce..ea42705 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -127,7 +127,7 @@ static void realview_init(int ram_size, int vga_ram_size, int boot_device, /* 0x68000000 PCI mem 1. */ /* 0x6c000000 PCI mem 2. */ - arm_load_kernel(ram_size, kernel_filename, kernel_cmdline, + arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline, initrd_filename, 0x33b); } diff --git a/hw/versatilepb.c b/hw/versatilepb.c index 12b7303..bc42472 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -250,7 +250,7 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device, /* 0x101f3000 UART2. */ /* 0x101f4000 SSPI. */ - arm_load_kernel(ram_size, kernel_filename, kernel_cmdline, + arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline, initrd_filename, board_id); } -- cgit v1.1