static void load_kernel (CPUState *env) { int64_t entry, kernel_low, kernel_high; long kernel_size, initrd_size; ram_addr_t initrd_offset; kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND, (uint64_t *)&entry, (uint64_t *)&kernel_low, (uint64_t *)&kernel_high); if (kernel_size >= 0) { if ((entry & ~0x7fffffffULL) == 0x80000000) entry = (int32_t)entry; env->active_tc.PC = entry; } else { fprintf(stderr, "qemu: could not load kernel '%s'\n", loaderparams.kernel_filename); exit(1); } /* load initrd */ initrd_size = 0; initrd_offset = 0; if (loaderparams.initrd_filename) { initrd_size = get_image_size (loaderparams.initrd_filename); if (initrd_size > 0) { initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK; if (initrd_offset + initrd_size > ram_size) { fprintf(stderr, "qemu: memory too small for initial ram disk '%s'\n", loaderparams.initrd_filename); exit(1); } initrd_size = load_image(loaderparams.initrd_filename, phys_ram_base + initrd_offset); } if (initrd_size == (target_ulong) -1) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", loaderparams.initrd_filename); exit(1); } } /* Store command line. */ if (initrd_size > 0) { int ret; ret = sprintf((char *)(phys_ram_base + (16 << 20) - 256), "rd_start=0x" TARGET_FMT_lx " rd_size=%li ", PHYS_TO_VIRT((uint32_t)initrd_offset), initrd_size); strcpy ((char *)(phys_ram_base + (16 << 20) - 256 + ret), loaderparams.kernel_cmdline); } else { strcpy ((char *)(phys_ram_base + (16 << 20) - 256), loaderparams.kernel_cmdline); } *(int32_t *)(phys_ram_base + (16 << 20) - 260) = tswap32 (0x12345678); *(int32_t *)(phys_ram_base + (16 << 20) - 264) = tswap32 (ram_size); }
static void android_load_kernel(CPUOldState *env, int ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename) { int initrd_size; ram_addr_t initrd_offset; uint64_t kernel_entry, kernel_low, kernel_high; unsigned int cmdline; /* Load the kernel. */ if (!kernel_filename) { fprintf(stderr, "Kernel image must be specified\n"); exit(1); } if (load_elf(kernel_filename, VIRT_TO_PHYS_ADDEND, (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low, (uint64_t *)&kernel_high) < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } env->active_tc.PC = (int32_t)kernel_entry; /* load initrd */ initrd_size = 0; initrd_offset = 0; if (initrd_filename) { initrd_size = get_image_size (initrd_filename); if (initrd_size > 0) { initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK; if (initrd_offset + initrd_size > ram_size) { fprintf(stderr, "qemu: memory too small for initial ram disk '%s'\n", initrd_filename); exit(1); } initrd_size = load_image_targphys(initrd_filename, initrd_offset, ram_size - initrd_offset); } if (initrd_size == (target_ulong) -1) { fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } } /* Store command line in top page of memory * kernel will copy the command line to a loca buffer */ cmdline = ram_size - TARGET_PAGE_SIZE; char kernel_cmd[1024]; if (initrd_size > 0) sprintf (kernel_cmd, "%s rd_start=0x" TARGET_FMT_lx " rd_size=%li", kernel_cmdline, (hwaddr)PHYS_TO_VIRT(initrd_offset), (long int)initrd_size); else strcpy (kernel_cmd, kernel_cmdline); cpu_physical_memory_write(ram_size - TARGET_PAGE_SIZE, (void *)kernel_cmd, strlen(kernel_cmd) + 1); #if 0 if (initrd_size > 0) sprintf (phys_ram_base+cmdline, "%s rd_start=0x" TARGET_FMT_lx " rd_size=%li", kernel_cmdline, PHYS_TO_VIRT(initrd_offset), initrd_size); else strcpy (phys_ram_base+cmdline, kernel_cmdline); #endif env->active_tc.gpr[4] = PHYS_TO_VIRT(cmdline);/* a0 */ env->active_tc.gpr[5] = ram_size; /* a1 */ env->active_tc.gpr[6] = 0; /* a2 */ env->active_tc.gpr[7] = 0; /* a3 */ }