Commit 66a93e0f47fa9869178008c7bc38d66a7c5e45f4
1 parent
9ee3c029
ELF loader (Thiemo Seufer)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1860 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
41 additions
and
39 deletions
hw/mips_r4k.c
@@ -5,6 +5,8 @@ | @@ -5,6 +5,8 @@ | ||
5 | #define KERNEL_LOAD_ADDR 0x80010000 | 5 | #define KERNEL_LOAD_ADDR 0x80010000 |
6 | #define INITRD_LOAD_ADDR 0x80800000 | 6 | #define INITRD_LOAD_ADDR 0x80800000 |
7 | 7 | ||
8 | +#define VIRT_TO_PHYS_ADDEND (-0x80000000LL) | ||
9 | + | ||
8 | extern FILE *logfile; | 10 | extern FILE *logfile; |
9 | 11 | ||
10 | static PITState *pit; | 12 | static PITState *pit; |
@@ -101,6 +103,7 @@ void cpu_mips_clock_init (CPUState *env) | @@ -101,6 +103,7 @@ void cpu_mips_clock_init (CPUState *env) | ||
101 | cpu_mips_update_count(env, 1, 0); | 103 | cpu_mips_update_count(env, 1, 0); |
102 | } | 104 | } |
103 | 105 | ||
106 | + | ||
104 | static void io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) | 107 | static void io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) |
105 | { | 108 | { |
106 | #if 0 | 109 | #if 0 |
@@ -189,72 +192,71 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device, | @@ -189,72 +192,71 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device, | ||
189 | const char *initrd_filename) | 192 | const char *initrd_filename) |
190 | { | 193 | { |
191 | char buf[1024]; | 194 | char buf[1024]; |
192 | - target_ulong kernel_base, kernel_size, initrd_base, initrd_size; | 195 | + int64_t entry = 0; |
193 | unsigned long bios_offset; | 196 | unsigned long bios_offset; |
194 | int io_memory; | 197 | int io_memory; |
195 | - int linux_boot; | ||
196 | int ret; | 198 | int ret; |
197 | CPUState *env; | 199 | CPUState *env; |
198 | - | ||
199 | - printf("%s: start\n", __func__); | ||
200 | - linux_boot = (kernel_filename != NULL); | 200 | + long kernel_size; |
201 | 201 | ||
202 | env = cpu_init(); | 202 | env = cpu_init(); |
203 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); | 203 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); |
204 | 204 | ||
205 | /* allocate RAM */ | 205 | /* allocate RAM */ |
206 | cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); | 206 | cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); |
207 | + | ||
208 | + /* Try to load a BIOS image. If this fails, we continue regardless, | ||
209 | + but initialize the hardware ourselves. When a kernel gets | ||
210 | + preloaded we also initialize the hardware, since the BIOS wasn't | ||
211 | + run. */ | ||
207 | bios_offset = ram_size + vga_ram_size; | 212 | bios_offset = ram_size + vga_ram_size; |
208 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME); | 213 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME); |
209 | printf("%s: load BIOS '%s' size %d\n", __func__, buf, BIOS_SIZE); | 214 | printf("%s: load BIOS '%s' size %d\n", __func__, buf, BIOS_SIZE); |
210 | ret = load_image(buf, phys_ram_base + bios_offset); | 215 | ret = load_image(buf, phys_ram_base + bios_offset); |
211 | - if (ret != BIOS_SIZE) { | ||
212 | - fprintf(stderr, "qemu: could not load MIPS bios '%s'\n", buf); | ||
213 | - exit(1); | 216 | + if (ret == BIOS_SIZE) { |
217 | + cpu_register_physical_memory((uint32_t)(0x1fc00000), | ||
218 | + BIOS_SIZE, bios_offset | IO_MEM_ROM); | ||
219 | + env->PC = 0xBFC00000; | ||
220 | + if (!kernel_filename) | ||
221 | + return; | ||
222 | + } else { | ||
223 | + /* not fatal */ | ||
224 | + fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n", | ||
225 | + buf); | ||
214 | } | 226 | } |
215 | - cpu_register_physical_memory((uint32_t)(0x1fc00000), | ||
216 | - BIOS_SIZE, bios_offset | IO_MEM_ROM); | ||
217 | -#if 0 | ||
218 | - memcpy(phys_ram_base + 0x10000, phys_ram_base + bios_offset, BIOS_SIZE); | ||
219 | - env->PC = 0x80010004; | ||
220 | -#else | ||
221 | - env->PC = 0xBFC00004; | ||
222 | -#endif | ||
223 | - if (linux_boot) { | ||
224 | - kernel_base = KERNEL_LOAD_ADDR; | ||
225 | - /* now we can load the kernel */ | ||
226 | - kernel_size = load_image(kernel_filename, | ||
227 | - phys_ram_base + (kernel_base - 0x80000000)); | ||
228 | - if (kernel_size == (target_ulong) -1) { | ||
229 | - fprintf(stderr, "qemu: could not load kernel '%s'\n", | ||
230 | - kernel_filename); | ||
231 | - exit(1); | ||
232 | - } | 227 | + |
228 | + kernel_size = 0; | ||
229 | + if (kernel_filename) { | ||
230 | + kernel_size = load_elf(kernel_filename, VIRT_TO_PHYS_ADDEND, &entry); | ||
231 | + if (kernel_size >= 0) | ||
232 | + env->PC = entry; | ||
233 | + else { | ||
234 | + kernel_size = load_image(kernel_filename, | ||
235 | + phys_ram_base + KERNEL_LOAD_ADDR + VIRT_TO_PHYS_ADDEND); | ||
236 | + if (kernel_size < 0) { | ||
237 | + fprintf(stderr, "qemu: could not load kernel '%s'\n", | ||
238 | + kernel_filename); | ||
239 | + exit(1); | ||
240 | + } | ||
241 | + env->PC = KERNEL_LOAD_ADDR; | ||
242 | + } | ||
243 | + | ||
233 | /* load initrd */ | 244 | /* load initrd */ |
234 | if (initrd_filename) { | 245 | if (initrd_filename) { |
235 | - initrd_base = INITRD_LOAD_ADDR; | ||
236 | - initrd_size = load_image(initrd_filename, | ||
237 | - phys_ram_base + initrd_base); | ||
238 | - if (initrd_size == (target_ulong) -1) { | 246 | + if (load_image(initrd_filename, |
247 | + phys_ram_base + INITRD_LOAD_ADDR + VIRT_TO_PHYS_ADDEND) | ||
248 | + == (target_ulong) -1) { | ||
239 | fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", | 249 | fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", |
240 | initrd_filename); | 250 | initrd_filename); |
241 | exit(1); | 251 | exit(1); |
242 | } | 252 | } |
243 | - } else { | ||
244 | - initrd_base = 0; | ||
245 | - initrd_size = 0; | ||
246 | } | 253 | } |
247 | - env->PC = KERNEL_LOAD_ADDR; | 254 | + |
248 | /* Store command line. */ | 255 | /* Store command line. */ |
249 | strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline); | 256 | strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline); |
250 | /* FIXME: little endian support */ | 257 | /* FIXME: little endian support */ |
251 | *(int *)(phys_ram_base + (16 << 20) - 260) = tswap32 (0x12345678); | 258 | *(int *)(phys_ram_base + (16 << 20) - 260) = tswap32 (0x12345678); |
252 | *(int *)(phys_ram_base + (16 << 20) - 264) = tswap32 (ram_size); | 259 | *(int *)(phys_ram_base + (16 << 20) - 264) = tswap32 (ram_size); |
253 | - } else { | ||
254 | - kernel_base = 0; | ||
255 | - kernel_size = 0; | ||
256 | - initrd_base = 0; | ||
257 | - initrd_size = 0; | ||
258 | } | 260 | } |
259 | 261 | ||
260 | /* Init internal devices */ | 262 | /* Init internal devices */ |