qemu load kernel

how does qemu load elf64 file-CSDN博客

./aarch64-softmmu/qemu-system-aarch64 -machine virt -cpu cortex-a57 -m 1024M -kernel ./vmlinux -nographic

info->kernel_filename: ./vmlinux
static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
                                         struct arm_boot_info *info)
{
    hwaddr entry;

    if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
        primary_loader = bootloader_aarch64;
        elf_machine = EM_AARCH64;
    } else {
        primary_loader = bootloader;
        if (!info->write_board_setup) {
            primary_loader += BOOTLOADER_NO_BOARD_SETUP_OFFSET;
        }
        elf_machine = EM_ARM;
    }

    ...code...

    /* Assume that raw images are linux kernels, and ELF images are not.  */
    kernel_size = arm_load_elf(info, &elf_entry, &image_low_addr,
                               &image_high_addr, elf_machine, as);
    entry = elf_entry;
    ...code...

    info->entry = entry;

    ...code...
    info->initrd_start = info->loader_start +
        MIN(info->ram_size / 2, 128 * MiB);
    if (image_high_addr) {
        info->initrd_start = MAX(info->initrd_start, image_high_addr);
    }
    info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start);
    info->is_linux = is_linux;

    for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
        ARM_CPU(cs)->env.boot_info = info;
    }
}

#0  arm_cpu_set_pc (cs=<optimized out>, value=1048576) at /root/doctor/qemu/qemu-4.2.0/target/arm/cpu.c:49
#1  0x0000555555976021 in cpu_set_pc (addr=1048576, cpu=0x55555696bc80)
    at /root/doctor/qemu/qemu-4.2.0/include/hw/core/cpu.h:924
#2  do_cpu_reset (opaque=0x55555696bc80) at /root/doctor/qemu/qemu-4.2.0/hw/arm/boot.c:718
#3  0x0000555555b415c5 in qemu_devices_reset () at /root/doctor/qemu/qemu-4.2.0/hw/core/reset.c:69
#4  0x0000555555aca5aa in qemu_system_reset (reason=SHUTDOWN_CAUSE_NONE) at /root/doctor/qemu/qemu-4.2.0/vl.c:1553
#5  0x0000555555873913 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>)
    at /root/doctor/qemu/qemu-4.2.0/vl.c:4436
 

\hw\arm\boot.c
static void do_cpu_reset(void *opaque)
{
    ARMCPU *cpu = opaque;
    CPUState *cs = CPU(cpu);
    CPUARMState *env = &cpu->env;
    const struct arm_boot_info *info = env->boot_info;

    cpu_reset(cs);
    if (info) {
        if (!info->is_linux) {
            int i;
            /* Jump to the entry point.  */
            uint64_t entry = info->entry;

            switch (info->endianness) {...}

            cpu_set_pc(cs, entry);

qemu-4.2.0\target\arm\cpu.c

static void arm_cpu_set_pc(CPUState *cs, vaddr value)
{
    ARMCPU *cpu = ARM_CPU(cs);
    CPUARMState *env = &cpu->env;

    if (is_a64(env)) {
        env->pc = value;

        env->thumb = 0;
    } else {
        env->regs[15] = value & ~1;
        env->thumb = value & 1;
    }
}

qemu-4.2.0\target\arm\cpu.c

static void arm_cpu_reset(CPUState *s)
{
    ARMCPU *cpu = ARM_CPU(s);
    ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu);
    CPUARMState *env = &cpu->env;

...code...
    if (arm_feature(env, ARM_FEATURE_AARCH64)) {
        /* 64 bit CPUs always start in 64 bit mode */
        env->aarch64 = 1;

#0  cpu_get_tb_cpu_state
    (env=0x555556974db0, pc=pc@entry=0x7fffcbbfb188, cs_base=cs_base@entry=0x7fffcbbfb180, pflags=pflags@entry=0x7fffcbbfb178)
    at /root/doctor/qemu/qemu-4.2.0/target/arm/helper.c:11354
#1  0x00005555558f3813 in tb_lookup__cpu_state
    (cf_mask=524288, flags=0x7fffcbbfb178, cs_base=0x7fffcbbfb180, pc=0x7fffcbbfb188, cpu=0x112e0be826d694b3)
    at /root/doctor/qemu/qemu-4.2.0/include/exec/tb-lookup.h:28
#2  tb_find (cf_mask=524288, tb_exit=0, last_tb=0x0, cpu=0x112e0be826d694b3)
    at /root/doctor/qemu/qemu-4.2.0/accel/tcg/cpu-exec.c:403
#3  cpu_exec (cpu=cpu@entry=0x55555696bc80) at /root/doctor/qemu/qemu-4.2.0/accel/tcg/cpu-exec.c:730
#4  0x00005555558bf4f0 in tcg_cpu_exec (cpu=0x55555696bc80) at /root/doctor/qemu/qemu-4.2.0/cpus.c:1473
#5  0x00005555558c17a4 in qemu_tcg_cpu_thread_fn (arg=arg@entry=0x55555696bc80) at /root/doctor/qemu/qemu-4.2.0/cpus.c:1781
#6  0x0000555555e31533 in qemu_thread_start (args=<optimized out>) at /root/doctor/qemu/qemu-4.2.0/util/qemu-thread-posix.c:519
#7  0x00007ffff5b56609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#8  0x00007ffff5a7b353 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                          target_ulong *cs_base, uint32_t *pflags)
{
    uint32_t flags = env->hflags;
    uint32_t pstate_for_ss;

    *cs_base = 0;

    if (FIELD_EX32(flags, TBFLAG_ANY, AARCH64_STATE)) {
        *pc = env->pc;

\qemu-4.2.0\accel\tcg\cpu-exec.c

static inline TranslationBlock *tb_find(CPUState *cpu,
                                        TranslationBlock *last_tb,
                                        int tb_exit, uint32_t cf_mask)
{
    TranslationBlock *tb;
    target_ulong cs_base, pc;
    uint32_t flags;

    tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask);
    if (tb == NULL) {
        mmap_lock();
        tb = tb_gen_code(cpu, pc, cs_base, flags, cf_mask);
\qemu-4.2.0\accel\tcg\translate-all.c

/* Called with mmap_lock held for user mode emulation.  */
TranslationBlock *tb_gen_code(CPUState *cpu,
                              target_ulong pc, target_ulong cs_base,
                              uint32_t flags, int cflags)
{
    CPUArchState *env = cpu->env_ptr;
    TranslationBlock *tb, *existing_tb;
    tb_page_addr_t phys_pc, phys_page2;

    phys_pc = get_page_addr_code(env, pc);

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值