QEMU の起動まで

各 machine の init がよばれる。例えばversatile_init。これは main の延長上呼ばれる。ここで、arm_load_kernel が呼ばれる。kernel といいつつ elf と uboot とベタイメージに対応している。必要があれば、linux であると判断されて、initrd が定義されれば、、、initrd がメモリ上に展開される。現在、Linux は cpio 形式の initrd も可能であると思うので(未確認) initrd に cpio を入れることも可能と思われる。単純な elf だと linux とは判断されない。qemu_register_reset でリセット時のコールバックルーチンが登録される。arm の場合 arm_boot.c の do_cpu_reset 最終的には main の qemu_system_reset が呼ばれる。arm の do_cpu_reset では linux じゃなかったら単純に regs[15] に info->entry を入れている。これだけじゃ走り出さない、、、entry は elf の場合、elf_entry、UBOOT の場合は中身を解析している。べたイメージの時は KERNEL_LOAD_ADDR がベースで、それに対して各 machine ごとにoffset をとっている。

resume_all_vcpus で動き出す?は qemu_cpu_kick を呼ぶ。qemu_cpu_kick_thread を呼ぶ。ということで、多分スレッドが動き出す。その前に設定されているはず。

qemu_tcg_init_vcpu かな?qemu_thread_create を呼んでいる。

その前に qemu_init_vcpu が qemu_tcg_init_vcpu を呼ぶ。qemu_init_vcpu はtarget-arm/helper.c の cpu_arm_init から呼ばれている。exec.c が cpu_init を呼ぶが cpu_init は cpu_arm_init にdefine されている。cpu_init は各 machine から呼ばれる。

整理する。versatile_init から cpu_init がよばれてそれは実は cpu_arm_init で qemu_init_vcpu がよばれて qemu_tcg_init_vcpu を呼んでqemu_thread_create を呼ぶ。qemu_thread_create には関数が登録されていて、qemu_tcg_cpu_thread_fn が実は thread の start ルーチンだ。そのなかで qemu_cond_wait でまっている。スタートすると tcg_exec_all を実行する。これでやっと走り出す。

tcg_cpu_exec が中身かな?cpu_exec が呼ばれる模様。おーターゲットごとに処理が違う。でもって、setjmp している、、、どうやら exception を起こした時に long jump するらしい。

やっとたどりついた。tcg_qemu_tb_exec で execute the generated codeらしいぞ。そのままcode_gen_prologue を読んでいる。ということは code_gen_prologue にコードが描かれているのでしょう。誰が描いているか?ここか、グローバル変数を使っているという汚いコードは。

最終的に tb_gen_code が呼ばれて cpu_gen_code = cpu_arm_gen_code が呼ばれる。cpu_arm_gen_code がみつからないが、、、、どうも cpu_gen_code らしい。translate-all.c にある。cpu.h を行くるーどしていて、cpug_arm_gen_code に置き換わる。紛らわしいな。gen_intermediate_code が各 CPU ごとに用意されている。gen_intermediate_code_internal にいきついた。