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,42 +64,52 @@ static void set_kernel_args(uint32_t ram_size, int initrd_size, | ||
64 | stl_raw(p++, 0); | 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 | const char *kernel_cmdline, const char *initrd_filename, | 68 | const char *kernel_cmdline, const char *initrd_filename, |
69 | int board_id) | 69 | int board_id) |
70 | { | 70 | { |
71 | int kernel_size; | 71 | int kernel_size; |
72 | int initrd_size; | 72 | int initrd_size; |
73 | int n; | 73 | int n; |
74 | + uint64_t entry; | ||
74 | 75 | ||
75 | /* Load the kernel. */ | 76 | /* Load the kernel. */ |
76 | if (!kernel_filename) { | 77 | if (!kernel_filename) { |
77 | fprintf(stderr, "Kernel image must be specified\n"); | 78 | fprintf(stderr, "Kernel image must be specified\n"); |
78 | exit(1); | 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 | exit(1); | 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,7 +509,7 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device, | ||
509 | } | 509 | } |
510 | pl110_init(ds, 0xc0000000, pic, 22, 0); | 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 | initrd_filename, 0x113); | 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,7 +127,7 @@ static void realview_init(int ram_size, int vga_ram_size, int boot_device, | ||
127 | /* 0x68000000 PCI mem 1. */ | 127 | /* 0x68000000 PCI mem 1. */ |
128 | /* 0x6c000000 PCI mem 2. */ | 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 | initrd_filename, 0x33b); | 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,7 +250,7 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device, | ||
250 | /* 0x101f3000 UART2. */ | 250 | /* 0x101f3000 UART2. */ |
251 | /* 0x101f4000 SSPI. */ | 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 | initrd_filename, board_id); | 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,7 +1317,7 @@ void *arm_gic_init(uint32_t base, void *parent, int parent_irq); | ||
1317 | 1317 | ||
1318 | /* arm_boot.c */ | 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 | const char *kernel_cmdline, const char *initrd_filename, | 1321 | const char *kernel_cmdline, const char *initrd_filename, |
1322 | int board_id); | 1322 | int board_id); |
1323 | 1323 |