← コース一覧
OSと低レイヤのしくみ
「システムコールを呼ぶと何が起きるのか」「mallocが返したポインタの先には本当にメモリがあるのか」「read()したデータはどこを通ってくるのか」。普段は意識せずに使っているOSの機能について、CPUのレジスタ1本、カーネルの構造体1つのレベルまで降りて、その中で何が起きているかを図で追いかけます。RISC-Vの仕様書とLinuxのman-page・カーネル文書という一次ソースだけを頼りに、丸暗記ではなく「なぜその設計なのか」を再導出できる状態を目指します。
公式ドキュメント: Linux man-pages / RISC-V ISA Specification ↗RISC-V編
- 1RISC-Vの命令フォーマット — なぜ即値のビットは散らばっているのか32ビット命令の中でレジスタ番号と即値がどこに置かれているか、そしてなぜ即値だけが分断されているのかを図で追っていきましょう。
- 2RISC-Vのレジスタ — 32本をどう使い分けるかRISC-Vの32本の整数レジスタが、呼び出し規約(ABI)の上でどう役割分担しているのかを図で追っていきましょう。
- 3RISC-Vのトラップ — 割り込みが起きてから戻るまでの一往復トラップが起きてから mret で元の場所へ帰り着くまでの一往復を、CSRの値の動きとして図で追っていきましょう。
- 4CSR — 特権レジスタを読み書きする専用命令CSR(制御状態レジスタ)が汎用レジスタとは別のアドレス空間に置かれ、専用の6命令だけで読み書きされる仕組みを図で追っていきましょう。
カーネル境界編
メモリ編
- 6ページテーブルウォーク — 仮想アドレスが物理アドレスになるまでRISC-V の Sv39 を例に、1つの仮想アドレスが3段のページテーブルを辿って物理アドレスに変わるまでを図で追っていきましょう。
- 7TLB — なぜ毎回ページテーブルを辿らずに済むのかTLB(Translation Lookaside Buffer)が仮想アドレス変換の結果をキャッシュする仕組みを、図で追っていきましょう。
- 8ページフォルト — 「メモリが無い」ときにカーネルがすることページフォルトが起きてから解決されるまでの流れを図で追っていきましょう。
- 9fork()が速い理由 — コピーオンライトfork()がメモリを複製せずに済ませ、書き込みの瞬間まで複製を先送りする仕組みを図で追っていきましょう。
- 10mallocの内部 — brkとmmapの使い分けglibc の malloc が「ヒープから切り出す」か「mmap で独立した領域を取る」かをどう決めているのか、その判断と理由を図で追っていきましょう。
- 11freeしたメモリはどこへ行くのか — chunkとbinfree() したメモリがOSに返らず、glibc malloc の中でどう分類・保管されて次の malloc に再利用されるのかを図で追っていきましょう。
- 12mallocが成功しても物理メモリはまだ無い — デマンドページング仮想メモリを確保する瞬間と、物理メモリが割り当てられる瞬間がどれだけズレているかを図で追っていきましょう。
- 13カーネル側のメモリ確保 — バディとスラブカーネルが物理ページとカーネルオブジェクトをどう確保するかを、2段構えの仕組みとして図で追っていきましょう。
同期編
- 14futex — 競合しないロックがシステムコールを呼ばない仕組みロックを取るとき、なぜ普段はカーネルに降りなくて済むのかを図で追っていきましょう。
- 15アトミック命令 — なぜCASが同期の土台になるのかcompare-and-swap(CAS)が「比べて、一致したときだけ書き換える」を不可分に行う仕組みを図で追っていきましょう。
- 16読み手を待たせない同期 — seqlockとRCU読み手にロックを取らせない2つの仕組み、seqlockとRCUを図で追っていきましょう。
- 17メモリバリア — 書いた順に見えるとは限らないソースコードに書いた順番と、他のCPUから見える順番がズレる仕組みと、それを止めるメモリバリアを図で追っていきましょう。