kernelはS-modeとU-modeでの挙動が実装されている)。v0.5とする)がどの様になっているのかを追っていきたい。kernelを実行するまでをまとめた。handlerの内部実装を覗くつもりだ。xv6というMIT発の教育用OSでもrisc-v実装が公開されている。kernelとその周辺のコンポーネント実装よりも簡素となっているので、OSの内部実装全体を俯瞰しやすい。これについては、Reference[3]、Reference[4]にて記事にしているので参照されたい。file)がどの様に作成されているかをmakeのコマンド出力(https://gist.github.com/knknkn1162/dab88ab196a1b915469a9e3c03e536a0)をもとに追う。fw_payload.oにassemble。file)も取り込まれる。file)を作成(ld)。scriptはfw_payload.elf.ldS。2.のFW_PAYLOAD_PATHはMakefileでの処理にてgccコマンドのオプションとして、-DFW_PAYLOAD_PATHのかたちで定義されている。-D***はマクロ***を定義する(define)ことを意味する。kernelのentrypointに移動するということです)。"fw_base.ldS"となっており、ほぼほぼfw_base.ldSが実体である。ENTRY(_start)とあるのでentrypointはここ。file)であることを確認しておく。fileで有ることが確認できる。objcopyなお、OBJCOPYFLAGS_**についてもここに記述がある。前章では主にMakefileの構造を探ることで、各種ファイル/パラメタが何を意味しているのかを説明した。この章では、entrypoint(fw_payload.elf.ldSのENTRY(_start)からfw_base.Sの_start関数だった)から順に処理を追っていく。OpenSBIはM-modeにおける実装であることに留意する。見るべきポイントは3つあると思う。handlerが終了した後、どうなるのか?上2つはboot時に設定されるのでboot時の流れを見れば良い。最後の1つは実際にtrapが起こりM-modeに遷移したことを想定してコードリーディングしていけば良さそうだ。handlerについては次の記事に回したい(この記事が長くなりすぎたため)。architecture(特にprivilege周り)の基本的な仕様については本記事では触れないので、Reference[6]の準備と概要をざっと読んでください。boot時の流れ(entrypointからmretまで)fw_base.Sまず、_start関数のあるfw_base.Sから。hart_id(cpuidみたいなもの)2が0のやつがmemory上の構成を行い(cold_start)、1以上のやつがそれを待つ様になっている(warm_start)。cold_startでは、mretで飛ぶ際の仕掛けを作っているのでかなり大事な部分である。sbi_initを呼び出す。この関数は__noreturn=__attribute__((noreturn))がついている3ので戻ってこない。warm_startの処理とcold_startの処理をかんたんに見ていく。両者の処理がfw_base.S内に混じっていてやや読みにくいので、こちらの方で見やすいように分離したコードを挙げている。optionで作成される。Makefileをいじればよい)。_wait_for_boot_hartを考えよう。t1のときに_wait_for_boot_hartにjumpすることを意味する。t1は_link_startのアドレスである。skip0x80000000はすでにALIGN(0x1000)を満たしているので、_text_start=_fw_startである。sectionに配置されるから、_fw_start=_startとなる。_fdt_reloc_doneのa1=0となり、真になるため)。実質やっていることは1のみだ。CSRにセットされる。*scratch)にてこの構造体(のポインタ)がそのまま渡される。sbi_scratchを構成する処理は以下の部分。