Commit 66a93e0f47fa9869178008c7bc38d66a7c5e45f4

Authored by bellard
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 5 #define KERNEL_LOAD_ADDR 0x80010000
6 6 #define INITRD_LOAD_ADDR 0x80800000
7 7  
  8 +#define VIRT_TO_PHYS_ADDEND (-0x80000000LL)
  9 +
8 10 extern FILE *logfile;
9 11  
10 12 static PITState *pit;
... ... @@ -101,6 +103,7 @@ void cpu_mips_clock_init (CPUState *env)
101 103 cpu_mips_update_count(env, 1, 0);
102 104 }
103 105  
  106 +
104 107 static void io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
105 108 {
106 109 #if 0
... ... @@ -189,72 +192,71 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
189 192 const char *initrd_filename)
190 193 {
191 194 char buf[1024];
192   - target_ulong kernel_base, kernel_size, initrd_base, initrd_size;
  195 + int64_t entry = 0;
193 196 unsigned long bios_offset;
194 197 int io_memory;
195   - int linux_boot;
196 198 int ret;
197 199 CPUState *env;
198   -
199   - printf("%s: start\n", __func__);
200   - linux_boot = (kernel_filename != NULL);
  200 + long kernel_size;
201 201  
202 202 env = cpu_init();
203 203 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
204 204  
205 205 /* allocate RAM */
206 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 212 bios_offset = ram_size + vga_ram_size;
208 213 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
209 214 printf("%s: load BIOS '%s' size %d\n", __func__, buf, BIOS_SIZE);
210 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 244 /* load initrd */
234 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 249 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
240 250 initrd_filename);
241 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 255 /* Store command line. */
249 256 strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline);
250 257 /* FIXME: little endian support */
251 258 *(int *)(phys_ram_base + (16 << 20) - 260) = tswap32 (0x12345678);
252 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 262 /* Init internal devices */
... ...