Commit daf90626beeb5f20504c593f01604a554f7ef232
1 parent
5856de80
ARM ELF loader.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2320 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
36 additions
and
26 deletions
hw/arm_boot.c
| ... | ... | @@ -64,42 +64,52 @@ static void set_kernel_args(uint32_t ram_size, int initrd_size, |
| 64 | 64 | stl_raw(p++, 0); |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | -void arm_load_kernel(int ram_size, const char *kernel_filename, | |
| 67 | +void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename, | |
| 68 | 68 | const char *kernel_cmdline, const char *initrd_filename, |
| 69 | 69 | int board_id) |
| 70 | 70 | { |
| 71 | 71 | int kernel_size; |
| 72 | 72 | int initrd_size; |
| 73 | 73 | int n; |
| 74 | + uint64_t entry; | |
| 74 | 75 | |
| 75 | 76 | /* Load the kernel. */ |
| 76 | 77 | if (!kernel_filename) { |
| 77 | 78 | fprintf(stderr, "Kernel image must be specified\n"); |
| 78 | 79 | exit(1); |
| 79 | 80 | } |
| 80 | - kernel_size = load_image(kernel_filename, | |
| 81 | - phys_ram_base + KERNEL_LOAD_ADDR); | |
| 82 | - if (kernel_size < 0) { | |
| 83 | - fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); | |
| 84 | - exit(1); | |
| 85 | - } | |
| 86 | - if (initrd_filename) { | |
| 87 | - initrd_size = load_image(initrd_filename, | |
| 88 | - phys_ram_base + INITRD_LOAD_ADDR); | |
| 89 | - if (initrd_size < 0) { | |
| 90 | - fprintf(stderr, "qemu: could not load initrd '%s'\n", | |
| 91 | - initrd_filename); | |
| 81 | + | |
| 82 | + kernel_size = load_elf(kernel_filename, 0, &entry); | |
| 83 | + if (kernel_size) { | |
| 84 | + /* An ELF image. Jump to the entry point. */ | |
| 85 | + env->regs[15] = entry & 0xfffffffe; | |
| 86 | + env->thumb = entry & 1; | |
| 87 | + } else { | |
| 88 | + /* Raw binary image. Assume it is a Limux zImage. */ | |
| 89 | + kernel_size = load_image(kernel_filename, | |
| 90 | + phys_ram_base + KERNEL_LOAD_ADDR); | |
| 91 | + if (kernel_size < 0) { | |
| 92 | + fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); | |
| 92 | 93 | exit(1); |
| 93 | 94 | } |
| 94 | - } else { | |
| 95 | - initrd_size = 0; | |
| 95 | + if (initrd_filename) { | |
| 96 | + initrd_size = load_image(initrd_filename, | |
| 97 | + phys_ram_base + INITRD_LOAD_ADDR); | |
| 98 | + if (initrd_size < 0) { | |
| 99 | + fprintf(stderr, "qemu: could not load initrd '%s'\n", | |
| 100 | + initrd_filename); | |
| 101 | + exit(1); | |
| 102 | + } | |
| 103 | + } else { | |
| 104 | + initrd_size = 0; | |
| 105 | + } | |
| 106 | + bootloader[1] |= board_id & 0xff; | |
| 107 | + bootloader[2] |= (board_id >> 8) & 0xff; | |
| 108 | + bootloader[5] = KERNEL_ARGS_ADDR; | |
| 109 | + bootloader[6] = KERNEL_LOAD_ADDR; | |
| 110 | + for (n = 0; n < sizeof(bootloader) / 4; n++) | |
| 111 | + stl_raw(phys_ram_base + (n * 4), bootloader[n]); | |
| 112 | + set_kernel_args(ram_size, initrd_size, kernel_cmdline); | |
| 96 | 113 | } |
| 97 | - bootloader[1] |= board_id & 0xff; | |
| 98 | - bootloader[2] |= (board_id >> 8) & 0xff; | |
| 99 | - bootloader[5] = KERNEL_ARGS_ADDR; | |
| 100 | - bootloader[6] = KERNEL_LOAD_ADDR; | |
| 101 | - for (n = 0; n < sizeof(bootloader) / 4; n++) | |
| 102 | - stl_raw(phys_ram_base + (n * 4), bootloader[n]); | |
| 103 | - set_kernel_args(ram_size, initrd_size, kernel_cmdline); | |
| 104 | 114 | } |
| 105 | 115 | ... | ... |
hw/integratorcp.c
| ... | ... | @@ -509,7 +509,7 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device, |
| 509 | 509 | } |
| 510 | 510 | pl110_init(ds, 0xc0000000, pic, 22, 0); |
| 511 | 511 | |
| 512 | - arm_load_kernel(ram_size, kernel_filename, kernel_cmdline, | |
| 512 | + arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline, | |
| 513 | 513 | initrd_filename, 0x113); |
| 514 | 514 | } |
| 515 | 515 | ... | ... |
hw/realview.c
| ... | ... | @@ -127,7 +127,7 @@ static void realview_init(int ram_size, int vga_ram_size, int boot_device, |
| 127 | 127 | /* 0x68000000 PCI mem 1. */ |
| 128 | 128 | /* 0x6c000000 PCI mem 2. */ |
| 129 | 129 | |
| 130 | - arm_load_kernel(ram_size, kernel_filename, kernel_cmdline, | |
| 130 | + arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline, | |
| 131 | 131 | initrd_filename, 0x33b); |
| 132 | 132 | } |
| 133 | 133 | ... | ... |
hw/versatilepb.c
| ... | ... | @@ -250,7 +250,7 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device, |
| 250 | 250 | /* 0x101f3000 UART2. */ |
| 251 | 251 | /* 0x101f4000 SSPI. */ |
| 252 | 252 | |
| 253 | - arm_load_kernel(ram_size, kernel_filename, kernel_cmdline, | |
| 253 | + arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline, | |
| 254 | 254 | initrd_filename, board_id); |
| 255 | 255 | } |
| 256 | 256 | ... | ... |
vl.h
| ... | ... | @@ -1317,7 +1317,7 @@ void *arm_gic_init(uint32_t base, void *parent, int parent_irq); |
| 1317 | 1317 | |
| 1318 | 1318 | /* arm_boot.c */ |
| 1319 | 1319 | |
| 1320 | -void arm_load_kernel(int ram_size, const char *kernel_filename, | |
| 1320 | +void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename, | |
| 1321 | 1321 | const char *kernel_cmdline, const char *initrd_filename, |
| 1322 | 1322 | int board_id); |
| 1323 | 1323 | ... | ... |