OS
nuta氏によるマイクロカーネル本
筆者製のHinaOSとMINIXseL4Hurdを比較しつつマイクロカーネルの設計をみていく
自作OS本とはちょっと違う?
https://github.com/nuta/microkernel-book

HinaOSのブート処理

マイクロカーネルなのでカーネルは最小限の初期化だけを行うだけで(それはそう)あとは vm タスクがやる感じらしい

起動からカーネルまで

  1. kernel/riscv32/boot.Sjal riscv32_boot する
    1. そもそもこれは kernel/riscv32/kernel.ld.template から生成されるリンカスクリプトで 0x8000’0000 に配置されるもので、どうやらこのアドレスから実行が始まるらしい
  2. kernel/riscv32/setup.c : riscv32_boot() が mepc レジスタに riscv32_setup() のアドレスを書き込んで mret によりジャンプ
    1. mepcは Machine Exception Program Counter の略で、[mret は Machine Return from Trap の略]、まあ x86_64 でやるのと似たようなことをしている(mretが pc = mepc を行うのでmepcをいじって任意ジャンプ)
  3. riscv32_setup()bootinfo.boot_elf__boot_elf を格納し、 kernel_main() を呼ぶ
    1. __boot_elfkernel.ld によってリンクされる(.rodataに置かれるっぽい)
  4. kernel/main.c@kernel_main : 諸々の初期化をして、 create_first_task() を呼び、各CPUを初期化して、 idle_task() を呼んでおしまい
  5. kernel/main.c@create_first_task : bootinfo->boot_elf について、ヘッダのマジックナンバーを確かめて、task_create("vm", header->e_entry, NULL) という感じで vm タスクを作成し、
    1. kernel/task.c@task_create : init_task_struct() で構造体を初期化、双方向連結リストである active_tasks に push_back して、 task_resume() により RUNNABLE な状態にして runqueueに push_back し、最後に tid を return
  6. kernel/main.c@idle_task : task_switch() して arch_idle()する。後者はRISC-VだとMPロックを解除して wfi で割り込み待ちをする(Wait For Interrupt?)

vm task

以下、特に指定がない限りファイルは servers/vm/ 下にあるものとする

  1. main.c@main : bootfs を初期化、 bootfs_image.S において .incbin BOOTFS_PATH によって埋め込まれたバイナリをいい感じにパースする
    1. BOOTFS_PATHbuild.mk によって指定されており、これは大本の Makefile によって設定される $(bootfs_bin) と同等
      1. この bootfs_bin は Python スクリプトによって生成される