Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

Zynqのqemu (その8)


Zynqのqemu (その7)の続きです。

メモリおよびI/O(レジスタ)の設定が終わると、いよいよ、Linux Kernelの起動です。
xilinx.cの下記の部分です。
 348     xilinx_binfo.ram_size = ram_size;
 349     xilinx_binfo.kernel_filename = kernel_filename;
 350     xilinx_binfo.kernel_cmdline = kernel_cmdline;
 351     xilinx_binfo.initrd_filename = initrd_filename;
 352     xilinx_binfo.dtb_filename = qemu_kerndtb;
 353     xilinx_binfo.nb_cpus = smp_cpus;
 354     xilinx_binfo.board_id = 0xd32;
 355     xilinx_binfo.loader_start = 0;
 356     printf("ram_size %x, board_id %x, loader_start %x\n",
 357             (unsigned)ram_size, (unsigned)xilinx_binfo.board_id,
 358             (unsigned)xilinx_binfo.loader_start);
 359     arm_load_kernel(first_cpu, &xilinx_binfo);
 360
xilinx_binfo変数の各メンバーに値を設定して、arm_load_kernel関数を呼びます。

arm_load_kernel関数は、arm_boot.cで次のように定義されています。

メモリに各種データ(kernel, initrc)をロードし、各CPUにブートアドレスを指定し、リセット後に起動する関数を下記のように設定します。
 300     for (; env; env = env->next_cpu) {
 301         env->boot_info = info;
 302         qemu_register_reset(do_cpu_reset, env);
 303     }
do_cpu_reset関数は、同じファイルに次のように定義されています。
 182 static void do_cpu_reset(void *opaque)
 183 {
 184     CPUState *env = opaque;
 185     const struct arm_boot_info *info = env->boot_info;
 186
 187     cpu_reset(env);
 188     if (info) {
 189         if (!info->is_linux) {
 190             /* Jump to the entry point.  */
 191             env->regs[15] = info->entry & 0xfffffffe;
 192             env->thumb = info->entry & 1;
 193         } else {
 194             if (env == first_cpu) {
 195                 env->regs[15] = info->loader_start;
 196                 if (old_param) {
 197                     set_kernel_args_old(info, info->initrd_size,
 198                                         info->loader_start);
 199                 } else {
 200                     set_kernel_args(info, info->initrd_size,
 201                                     info->loader_start);
 202                 }
 203             } else {
 204                 stl_phys_notdirty(info->smp_bootreg_addr, 0);
 205                 env->regs[15] = info->smp_loader_start;
 206             }
 207         }
 208     }
 209 }

set_kernel_args関数については、次回に。

検証、Verification、FPGA