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 | ... | ... |