※小説ではない※専門書 要約資料集 為替(換算)3.9万円でもらう 紐解集生成 専門 初入門 資料 作:{作者名}
> 学問の宇宙・応用の軌道ステーション群「作る力と生きる力シリーズ」計算機文明部 第1巻。ガイド役: Fable 5 監修 / Sonnet 5 執筆(脚本班)
> トーン規約: GAKUMON_UNIVERSE.md準拠。専門用語は初出で必ず説明する。
> **安全枠(§16.18・絶対厳守)**: 本冊はブート・プロセス・メモリ管理・ファイルシステムという「概念」を、教育用の縮小トイOS実装(実運用OSではない)で説明する。実在OSへの侵入・権限昇格・マルウェア作成技術は一切含めない。本冊で紹介するコードはすべて、仮想マシン(エミュレータ)上でのみ動かすことを前提にした学習用の断片であり、実機のハードウェアや他人の管理する計算機を対象にした操作は一切扱わない。
> 接続先: →BOOK-0342(論理回路からCPUへ・ハードウェアの土台。CPUのレジスタや命令実行の仕組みはそちらが土台になっている〈予約番号のみ確定〉)、→BOOK-0343(情報構造の設計・データ構造〈予約番号のみ確定〉)、→BOOK-0066『アルゴリズムとデータ構造』第1巻(情報派生。レシピの比喩やスケジューラの効率を考える土台になっている)。
> 水準: 一〜十二(電源投入とは何が起きるのかという素朴な疑問から、ブートローダ、カーネル、プロセス、メモリ管理、ファイルシステム、仮想メモリ、スケジューラの発展的理解までを扱う)。
# BOOK-0340 作る力と生きる力: OSを作るということ 第1巻 — たまごから芽吹く、小さな計算機の一生
> 学問の宇宙・応用の軌道ステーション群「作る力と生きる力シリーズ」計算機文明部 第1巻。ガイド役: Fable 5 監修 / Sonnet 5 執筆(脚本班)
> トーン規約: GAKUMON_UNIVERSE.md準拠。専門用語は初出で必ず説明する。
> **安全枠(§16.18・絶対厳守)**: 本冊はブート・プロセス・メモリ管理・ファイルシステムという「概念」を、教育用の縮小トイOS実装(実運用OSではない)で説明する。実在OSへの侵入・権限昇格・マルウェア作成技術は一切含めない。本冊で紹介するコードはすべて、仮想マシン(エミュレータ)上でのみ動かすことを前提にした学習用の断片であり、実機のハードウェアや他人の管理する計算機を対象にした操作は一切扱わない。
> 接続先: →BOOK-0342(論理回路からCPUへ・ハードウェアの土台。CPUのレジスタや命令実行の仕組みはそちらが土台になっている〈予約番号のみ確定〉)、→BOOK-0343(情報構造の設計・データ構造〈予約番号のみ確定〉)、→BOOK-0066『アルゴリズムとデータ構造』第1巻(情報派生。レシピの比喩やスケジューラの効率を考える土台になっている)。
> 水準: 一〜十二(電源投入とは何が起きるのかという素朴な疑問から、ブートローダ、カーネル、プロセス、メモリ管理、ファイルシステム、仮想メモリ、スケジューラの発展的理解までを扱う)。
---
## 入口の物語 — たまごOSに宿る、たった一行の"Hello"
新人プログラマーは、計算機文明部の工房に配属された初日、先輩から一台のノートパソコンと、書き込み済みのUSBメモリを渡された。「これを差し込んで、電源を入れてみてくれ」。言われたとおりに電源ボタンを押すと、画面の左上に小さな文字で"Hello, world."とだけ表示され、そこで止まった。マウスも矢印も動かない。ただの黒い画面に白い文字が一行あるだけの、いかにも味気ない光景だった。
新人プログラマーは拍子抜けした。普段使っているパソコンなら、電源を入れれば見慣れたデスクトップの絵柄が現れ、時計が動き、アイコンが並ぶ。ところがこのUSBメモリから起動した画面には、ファイルを開く方法もフォルダを見る方法も、何一つ用意されていない。「これ、壊れてますか」と尋ねると、先輩は笑って言った。「壊れてない。これは"OS"と呼べるかどうかも怪しい、たった数百行のプログラムだ。でも、この一行の"Hello, world."が画面に出るまでに、電源ボタンを押した瞬間から、実はもう何段階もの仕事が積み重なっている」。
先輩は続けた。「普段使っているパソコンの中身は、何十年もかけて積み上げられた巨大な建築物だ。いきなり全体を理解しようとしても、どこから手をつけていいかわからなくなる。だから今日から、この"たまごOS"という小さな教育用のOSを、一緒に一段ずつ育てていこう。電源が入った瞬間に何が起きるか、プログラムがどうやって"プロセス"という生き物のような存在に変わるか、メモリという土地をどう区画整理するか、そしてファイルという記録がディスクのどこにどう眠っているか――この四つを、実際に動く小さなコードを追いながら、自分の手で組み立て直してみよう」。
新人プログラマーは半信半疑のまま、渡された資料の一番上――「たまごOSの設計図」と書かれた一枚の紙――に目を落とした。そこには、電源ボタンのアイコンから始まり、矢印が何本も枝分かれしながら"Hello, world."の一行にたどりつくまでの道筋が、簡単な図で描かれていた。「この矢印一本ずつが、これから学ぶ一つの章になる」と先輩は言った。
この一言が、計算機文明部シリーズの出発点になる。パソコンという機械の中で、電源を入れてから文字が一行表示されるまでの間に何が起きているのか――起動(ブート)・プロセス・メモリ管理・ファイルシステムという四つの土台を、実運用のOSではなく教育用に縮小した「たまごOS」というトイ実装(教育目的に作られた小さな自作OS)を追いながら、一段ずつ積み上げていくのが、この第1巻の仕事である。
---
## 第一章: 電源を入れると何が起きるのか — 起動という謎の入口(水準一)
### ボタンひとつの裏側
パソコンの電源ボタンを押した瞬間、画面には何も映らない。にもかかわらず、その内部では既に仕事が始まっている。電気が流れ始めると、CPU(中央処理装置)はまず、あらかじめ回路の中に焼き付けられた決まった番地の命令を読みにいく。この「電源投入直後に最初に実行される命令が置かれている、あらかじめ決まったメモリ番地」を**リセットベクタ(水準一: CPUが電源投入直後に最初に実行する命令が置かれている、あらかじめ決まったメモリ番地)**と呼ぶ。CPU自身はどのOSを使うかも、どんな画面を映すかも知らない。ただ「決まった番地の命令を読んで実行する」という、単純きわまりない仕事をしているだけである。
### BIOSとUEFI — 最初に目を覚ますプログラム
このリセットベクタが指す先に置かれているのが、**BIOS(バイオス、水準一: Basic Input/Output Systemの略。マザーボード上のチップに書き込まれた、電源投入直後に最初に動き出す基本的なプログラム)**、あるいはその後継として広く普及した**UEFI(ユーイーエフアイ、水準一: BIOSよりも新しく、より多機能なファームウェア規格。2000年代にIntelのEFI仕様を土台として発展し、業界団体〈UEFI Forum〉によって標準化されたとされる)**である。BIOSもUEFIも、OSそのものではなく、OSを呼び出すための最初の案内役を務める**ファームウェア(水準一: ハードウェアに組み込まれた、電源を切っても消えない基本的なプログラム)**という位置づけの存在である。
電源投入後、BIOS・UEFIはまず**POST(ポスト、水準一: Power-On Self Testの略。メモリやキーボードなど主要なハードウェアが正常に動作するかどうかを自己点検する処理)**と呼ばれる自己診断を行う。メモリの一部が壊れていたり、必須の部品が認識できなかったりすると、ここでビープ音や画面表示によって異常が知らされる。POSTを無事に通過すると、ファームウェアは次に**ブートデバイス(水準一: OSを起動するための最初のプログラムが格納されている記憶装置。ハードディスク・SSD・USBメモリなど)**を探しにいく。
### 「見つける」から「委ねる」へ
ブートデバイスが見つかると、ファームウェアはその記憶装置の決まった位置に置かれた小さなプログラムを読み込み、そこへ実行を委ねる。この「読み込んで実行を委ねる」という一連の流れ全体を、一般に**ブート(水準一: 電源投入からOSが使える状態になるまでの、起動の一連の流れ全体。「ブートストラップ〈自分の靴紐を引っ張って自分を持ち上げる〉」という古い言い回しに由来するとされる)**と呼ぶ。「ブートストラップ」という語源は、外部の力を借りずに自力で立ち上がっていく様子を、靴紐を引っ張って自分の体を持ち上げようとする滑稽な比喩にたとえたものだと広く紹介されている。何もない状態から段階を追って少しずつ大きなプログラムを立ち上げていくこの流れこそが、次章から見ていく「たまごOS」の出発点になる。
---
> **定着量の目安(第一章)**: リセットベクタ・BIOS・UEFI・ファームウェア・POST・ブートデバイス・ブートという7つの用語を、意味を混同せず説明できるようにするには、用語を空欄にした穴埋めドリルを20問程度こなすと、ほぼ完全に定着すると見込まれる。
---
## 第二章: ブートローダ — 最初の512バイトに書かれた小さな命令(水準二)
### 512バイトという小さな部屋
ブートデバイスの中で、ファームウェアが最初に読み込む場所は、多くの伝統的な方式(MBR形式)では先頭のちょうど512バイトと決まっている。この512バイトの区画を**ブートセクタ(水準二: ディスクの中で、起動時に最初に読み込まれる先頭512バイトの区画)**と呼び、そこに収められた小さなプログラムを**ブートローダ(水準二: ファームウェアから制御を受け取り、OS本体〈カーネル〉をメモリに読み込んで実行を引き渡す、小さな橋渡し役のプログラム)**と呼ぶ。512バイトという広さは、現代のプログラムからすればごく狭い部屋だが、「次の一手を用意する」だけの仕事に限れば十分な広さである。
古くから使われてきたこの方式を**MBR(エムビーアール、水準二: Master Boot Recordの略。ディスクの先頭に置かれ、パーティション情報とブートコードをあわせて記録する、古くからの方式)**と呼ぶ。1台の記憶装置を複数の独立した区画に論理的に分割したものを**パーティション(水準二: 1台の記憶装置を、複数の独立した区画に論理的に分割したもの)**と呼び、MBRはこのパーティションの配置情報もあわせて記録している。より大きな記憶装置に対応するため、MBRより新しい**GPT(ジーピーティー、水準二: GUID Partition Tableの略。MBRより新しく、より大きなディスクや多くのパーティションに対応した形式で、UEFIの普及とともに広まった)**という形式も現在は広く使われている。
### たまごOSの最初の一行
ブートローダが正しく読み込まれたかどうかを、ファームウェアはどうやって見分けるのだろうか。答えは単純で、512バイトの最後の2バイトに、決まった**マジックナンバー(水準二: あるデータ形式であることを示すために、決まった位置に置かれる特定のビット列の目印)**――`0xAA55`という値――が置かれているかどうかを確認するだけである。この2バイトが正しくなければ、ファームウェアはそのデバイスを「起動可能ではない」と判断する。
「たまごOS」の最初の一行は、この仕組みを使って画面に文字を出すだけの、ごく短いブートローダである。
```
; たまごOSの最初の1行(擬似アセンブリ、教育用に簡略化・仮想マシン上でのみ実行)
org 0x7C00 ; ブートローダが読み込まれる、決まったメモリ番地
mov si, msg ; 表示したい文字列の場所をSIレジスタに入れる
call print_string ; 文字列を1文字ずつ画面に出す手続きを呼ぶ
jmp $ ; その場で無限ループ(処理を終わらせない)
msg db "Hello, world.", 0
times 510-($-$$) db 0 ; 510バイトになるまで0で埋める
dw 0xAA55 ; 最後の2バイト。ここが起動可能な区画である目印
```
このプログラムは、ファームウェアからCPUの実行を受け取ると、`msg`が指す文字列を画面に1文字ずつ表示し、その後は何もせずに無限ループへ入る。実際のOSであれば、この後さらに大きなプログラム(カーネル本体)をディスクから読み込み、そちらへ実行を引き渡す処理が続く。次章では、その「引き渡した先」――カーネル――の仕事を見ていく。
---
> **定着量の目安(第二章)**: ブートセクタ・ブートローダ・MBR・パーティション・GPT・マジックナンバーという6つの用語と、`0xAA55`という目印の役割を説明できるようにするには、用語ドリル20問程度と、たまごOSの最初の一行を自分の手で書き写して仮想マシン上で動かしてみる実践を1回行うと、ほぼ完全に定着すると見込まれる。
---
## 第三章: カーネルへの橋渡し — 割り込みと特権モードの入口(水準三)
### カーネルとは何か
ブートローダが読み込んで実行を引き渡す先が、**カーネル(水準三: OSの中核をなすプログラム。ハードウェアの管理・プロセスの管理・メモリの管理など、OSの最も基本的な仕事を担う部分)**である。普段「OS」と呼んでいるものの中には、デスクトップの絵柄やアイコンなど目に見える部分(シェルやユーザーインターフェース)も含まれるが、その奥でハードウェアと直接やりとりしている中核部分だけを指して、特にカーネルと呼び分ける。
### リアルモードから保護モードへ
x86系と呼ばれる系統のCPU(現在広く使われているパソコン用CPUの主要な系統の一つ)は、電源投入直後、**リアルモード(水準三: x86系CPUが電源投入直後に動作する、16ビットのアドレス指定に制限された古い動作モード)**という制限の多い動作モードで動いている。リアルモードは、1980年代初頭のCPU(Intel 8086など)との互換性を保つために残されている、いわば歴史的な名残りである。カーネルは起動の初期段階で、より広いメモリ空間とメモリ保護機能を使える**保護モード(水準三: リアルモードより新しく、32ビット以上のアドレス空間とメモリ保護の仕組みを使える動作モード)**へCPUを切り替える処理を行う。この切り替えを終えて初めて、カーネルは現代的な広さのメモリを自由に使えるようになる。
### 割り込みという「呼び出しベル」
カーネルが行うもう一つの重要な初期設定が、**割り込み(わりこみ、水準三: CPUが実行中の処理を一時中断し、決まった別の処理〈割り込みハンドラ〉に切り替える仕組み)**の準備である。キーボードが押された、タイマーが一定時間経過した、ディスクの読み込みが完了した――こうした出来事が起きるたびに、CPUはいま実行中の処理を一時中断し、その出来事に対応する処理(割り込みハンドラ)へ飛び移る。どの割り込み番号にどの処理を対応させるかを記録した表を**割り込みベクタテーブル(水準三: どの割り込み番号にどの処理〈割り込みハンドラ〉を対応させるかを記録した表)**と呼び、カーネルは起動の初期段階でこの表を自分の管理下に置き換える。
普段プログラムがOSの機能(画面表示・ファイル操作など)を呼び出すときに使う、決められた窓口を**システムコール(水準三: プログラムがOSの機能を呼び出すための、決められた窓口。多くの実装で割り込みの仕組みを応用して実現される)**と呼ぶ。システムコールもまた、この割り込みの仕組みを応用して実現されていることが多い。この「呼び出しベルを鳴らして、決まった相手に処理を頼む」という発想は、次章で見る「プロセス」という考え方の土台にもつながっている。
### コラム — モノリシックカーネルとマイクロカーネル、そして一つの有名な論争
カーネルの作り方には、大きく分けて二つの設計思想がある。ハードウェア管理・プロセス管理・ファイルシステムなど、OSの主要な機能をひとつの大きなプログラムとしてまとめる**モノリシックカーネル(水準三: OSの主要な機能をひとつの大きなプログラムとしてまとめる設計方式)**と、必要最小限の機能だけをカーネルに残し、残りの機能を独立した小さなプログラム(サーバー)に分離する**マイクロカーネル(水準三: 必要最小限の機能だけをカーネルに残し、残りをサーバーと呼ばれる独立した小さなプログラムに分離する設計方式)**である。1987年に教育用として発表された**MINIX(ミニックス、水準三: オランダの計算機科学者アンドリュー・タネンバウムが1987年に教育用に開発した、マイクロカーネル方式のOS)**はマイクロカーネル方式の代表例として知られ、フィンランドの学生だったリーナス・トーバルズが1991年にモノリシックカーネル方式で開発を始めた**Linux(リナックス、水準三: 1991年にリーナス・トーバルズが開発を始めた、モノリシックカーネル方式のOSカーネル)**とは対照的な設計を採る。両者の設計思想の違いをめぐっては、開発初期にトーバルズとタネンバウムの間で公開の議論が交わされたことが広く知られており、この議論は今もOS設計を学ぶ人の間でしばしば語り継がれている。
---
> **定着量の目安(第三章)**: カーネル・リアルモード・保護モード・割り込み・割り込みベクタテーブル・システムコールという6つの用語の役割を説明できるようにするには、用語ドリル20問程度をこなすと、ほぼ完全に定着すると見込まれる。
---
## 第四章: プロセスとは何か — プログラムとプロセスの違い(水準四)
### レシピと、実際に台所に立つ人
→BOOK-0066『アルゴリズムとデータ構造』第1巻では、アルゴリズムを「レシピ」に例えた。この比喩をそのまま借りるなら、ディスクに保存されたままの**プログラム(水準四: ディスクなどに保存された、実行される前の、静的な命令の集まり)**は、まだ紙に書かれているだけのレシピにすぎない。これに対して、そのレシピをもとに、実際に台所に立って材料を切り、鍋を火にかけている状態――CPU時間とメモリという「体」を割り当てられ、実際に動いている状態――を**プロセス(水準四: プログラムが実行のためにメモリへ読み込まれ、CPU時間や独自のメモリ空間を割り当てられて、実際に動いている状態)**と呼ぶ。同じレシピ(プログラム)からでも、二人の料理人が同時に台所に立てば、それは二つの独立したプロセスになる。
### プロセスの持ち物 — PCB
OSは、いま動いている一つひとつのプロセスについて、「どこまで実行が進んでいるか」「レジスタの値はどうなっているか」「どんな状態にあるか」といった情報を、**プロセス制御ブロック(PCB、水準四: OSがプロセスごとに管理する、プログラムカウンタやレジスタの値、実行状態などをまとめた管理情報のかたまり)**という管理情報にまとめて保持している。PCBの中でも特に重要なのが、**プログラムカウンタ(水準四: CPUが次に実行する命令のメモリ番地を保持しているレジスタ)**――今どの命令を実行中で、次にどの命令へ進むべきかを覚えている値――である。CPU内部にある、ごく少量だが超高速にアクセスできる記憶場所を**レジスタ(水準四: CPU内部にある、ごく少量だが超高速にアクセスできる記憶場所)**と呼び、プログラムカウンタもレジスタの一種である。
### プロセスの一生
プロセスは、生まれてから終わるまでの間、いくつかの状態を行き来する。実行の順番を待っている「実行可能」状態、実際にCPUを使って動いている「実行中」状態、ディスクの読み込み待ちなどでCPUを使えない「待機」状態――たまごOSでも、この三つの状態をPCBの1フィールドとして持たせ、状態が変わるたびにこのフィールドを書き換えるだけの、ごく単純な仕組みでプロセスの一生を表現する。次章では、この状態の切り替えを、限られた1個のCPUの上でどう実現するかを見ていく。
---
> **定着量の目安(第四章)**: プログラム・プロセス・プロセス制御ブロック(PCB)・プログラムカウンタ・レジスタという5つの用語と、プロセスの三つの状態(実行可能・実行中・待機)を説明できるようにするには、用語ドリル20問程度と、身近なパソコンでタスクマネージャー(またはpsコマンド)を開いて実際のプロセス一覧を観察する実践を1回行うと、ほぼ完全に定着すると見込まれる。
---
## 第五章: マルチタスキングとコンテキストスイッチ — 一つのCPUで多くを動かす技(水準五)
### 見かけ上の同時進行
多くのパソコンは、CPUのコア数以上の数のプロセスを同時に動かしているように見せている。実際には、1個のCPUコアは、ある瞬間には1つのプロセスの命令しか実行できない。それでも複数のプロセスが同時に動いているように見えるのは、OSが極めて短い時間ごとにプロセスを目まぐるしく切り替えているからである。この仕組み全体を**マルチタスキング(水準五: 見かけ上、複数のプログラムが同時に動いているように見せる仕組み)**と呼ぶ。
### コンテキストスイッチという早業
あるプロセスの実行を中断し、そのプロセスのPCBにレジスタの値やプログラムカウンタを保存し、次に動かす別のプロセスのPCBから値を読み込んで復元する一連の処理を、**コンテキストスイッチ(水準五: あるプロセスの実行を中断してPCBの内容を保存し、別のプロセスのPCBの内容を復元して実行を切り替える処理)**と呼ぶ。「次にどのプロセスへCPU時間を割り当てるか」を決めるOSの部品を**スケジューラ(水準五: 次にどのプロセスにCPU時間を割り当てるかを決めるOSの部品)**と呼び、たまごOSでは、待機中でないプロセスのPCBを並べたリストの先頭から順番に選ぶという、もっとも単純な方式を採用する。
### 協調的方式とプリエンプティブ方式
初期のOS(古い時代のMac OSやWindowsの一部バージョンなど)では、各プロセスが自分から進んでCPUを手放すことに頼る**協調的マルチタスキング(水準五: 各プロセスが自分から進んでCPUを手放すことに頼る、古い方式のマルチタスキング)**が使われていた。この方式では、1つのプロセスが手放すのを忘れる(バグで無限ループに入るなど)と、他のすべてのプロセスが動けなくなってしまう弱点があった。現代の主要なOSの多くは、タイマー割り込みを利用し、プロセスの同意を待たずに強制的にCPUを切り替える**プリエンプティブマルチタスキング(水準五: OSがタイマー割り込みなどを使い、プロセスの同意なしに強制的にCPUを切り替える方式のマルチタスキング)**を採用している。
たまごOSでも、タイマー割り込みが起きるたびにスケジューラを呼び出し、次のプロセスのPCBへコンテキストスイッチする、簡易なプリエンプティブ方式を実装する。2つのトイプロセス(画面に交互に"A"と"B"を出すだけの単純なプロセス)を用意し、タイマー割り込みのたびに交互に実行が切り替わる様子は、マルチタスキングの原理を最も小さな形で確かめられる、教育用の定番の題材である。
---
> **定着量の目安(第五章)**: マルチタスキング・コンテキストスイッチ・スケジューラ・協調的マルチタスキング・プリエンプティブマルチタスキングという5つの用語と、両方式の違い・弱点を説明できるようにするには、用語ドリル20問程度をこなすと、ほぼ完全に定着すると見込まれる。
---
## 第六章: メモリ管理の基礎 — アドレス空間・スタック・ヒープ(水準六)
### プロセスごとの「自分だけの土地」
各プロセスは、自分専用のメモリの範囲を持っているかのように振る舞う。このプロセスからアクセスできるメモリ番地の範囲全体を**アドレス空間(水準六: プログラムやプロセスからアクセスできるメモリ番地の範囲全体)**と呼ぶ。プロセスが実際に扱う番地と、メモリチップ上の実際の番地である**物理アドレス(水準六: 実際のメモリチップ上の番地)**は、必ずしも一致しない――この不一致の理由は第十章の仮想メモリで詳しく扱うので、ここではまず、プロセスに与えられたアドレス空間の中身がどう区画分けされているかを見ていく。
### スタック — 後入れ先出しの土地
アドレス空間の中には、関数を呼び出すたびに戻り先やローカル変数を積み重ねて記録していく**スタック(水準六: 関数呼び出しの際に戻り先やローカル変数を積み重ねて記録する、後入れ先出し〈LIFO〉のメモリ領域)**という区画がある。「後入れ先出し(LIFO、Last In First Out)」とは、最後に積んだものを最初に取り出す、という積み重ねの規則である。関数Aが関数Bを呼び、Bが関数Cを呼んだとすると、Cが終わればB、Bが終わればAへと、呼び出した順序とちょうど逆順に戻っていく。この「積んだ順と逆順に返す」性質が、スタックという名前(積み重ねという意味)の由来になっている。スタックの現在の先頭位置を指しているレジスタを**スタックポインタ(水準六: スタックの現在の先頭位置を指しているレジスタ)**と呼び、関数呼び出しのたびにこの値が上下する。
### ヒープ — 必要な分だけ切り出す土地
これに対して、プログラムが実行中に必要な分だけ動的に確保し、使い終わったら解放できるメモリ領域を**ヒープ(水準六: プログラムが実行中に必要な分だけ動的に確保・解放できるメモリ領域)**と呼ぶ。スタックが「決まった順序で積んで崩す」規則正しい区画であるのに対し、ヒープは「必要なときに必要な分だけ、順不同で切り出す」自由な区画である。この自由さゆえに、ヒープの管理には専用の仕組みが必要になる――それが次章で扱う、メモリアロケータの仕事である。
---
> **定着量の目安(第六章)**: アドレス空間・物理アドレス・スタック・スタックポインタ・ヒープという5つの用語と、スタックの後入れ先出し(LIFO)の性質を説明できるようにするには、用語ドリル15問程度と、関数呼び出しのネスト(入れ子)をスタックの絵に書き起こす演習を5例ほどこなすと、ほぼ完全に定着すると見込まれる。
---
## 第七章: 単純なメモリアロケータを設計する — たまごOSのmalloc(水準七)
### 空き地の台帳を作る
ヒープから必要な大きさのメモリブロックを切り出し、使い終わったら回収する仕組みを**メモリアロケータ(水準七: ヒープ領域から必要な大きさのメモリブロックを切り出し、使い終わったら回収する仕組み)**と呼ぶ。たまごOSのアロケータは、まだ使われていない(解放されている)メモリブロックをつなぎ合わせて管理する**フリーリスト(水準七: まだ使われていない〈解放されている〉メモリブロックをつなぎ合わせて管理する一覧)**という考え方を使う、もっとも単純な部類の実装を採用する。
### 検算6 — 1024バイトのヒープを使い回す
1024バイトのヒープを持つたまごOSで、次の順に確保・解放を行う場面を考える。
```
手順:
1. alloc(100) → 100バイトの区画Aを確保(残り空き: 924バイト)
2. alloc(200) → 200バイトの区画Bを確保(残り空き: 724バイト)
3. free(A) → 区画Aを解放し、フリーリストへ戻す(空き: 100バイト+724バイト)
4. alloc(150) → 150バイトを要求。区画A跡地(100バイト)には収まらないため、
フリーリストの724バイト側から切り出して区画Cを確保
```
手順4を見ると、区画A跡地の100バイトは、150バイトの要求には小さすぎるため使われず、そのまま空き地として残ってしまう。このように、メモリの確保と解放を繰り返すうちに、合計では十分な空きがあっても、小さく分断されて大きな一続きの領域が確保できなくなる現象を**メモリの断片化(だんぺんか、水準七: メモリの確保と解放を繰り返すうちに、空き領域が小さく分断されてしまい、合計では十分な空きがあっても大きな一続きの領域が確保できなくなる現象)**と呼ぶ。実際のOSやプログラミング言語のメモリ管理では、断片化を減らすための工夫(隣接する空き区画の結合など)がさまざまに研究されてきた。
たまごOSのアロケータは、解放時に隣接する空き区画があれば結合する、という最小限の工夫だけを実装する。これだけでも、区画A跡地(100バイト)の隣にさらに空きができれば結合されて再利用しやすくなる、という基本的な効果を確認できる。
---
> **定着量の目安(第七章)**: メモリアロケータ・フリーリスト・メモリの断片化という3つの用語と、検算6の手順をノート上でトレースする演習を5例ほどこなすと、ほぼ完全に定着すると見込まれる。
---
## 第八章: ファイルシステムの正体 — ブロック・inode・ディレクトリという発想(水準八)
### ディスクは「ただの棚」でしかない
ハードディスクやSSDそのものは、名前のついた「ファイル」という単位を知らない。ディスクが物理的に扱えるのは、一定サイズごとに区切られた**ブロック(水準八: ディスクを一定サイズごとに区切った、データ読み書きの最小単位)**という棚の一区画だけである。この「ただの棚」に、名前をつけたファイルとして整理し、名前で探し出せるようにする仕組み全体を**ファイルシステム(水準八: 記憶装置の中に、ファイルやディレクトリという単位でデータを整理し、名前で探し出せるようにする仕組み)**と呼ぶ。
### inode — 中身ではなく「中身の在りか」を記録する台帳
多くのファイルシステムでは、ファイルの実体データ(中身そのもの)とは別に、そのファイルのサイズ・所有者・作成日時・そして「どのブロックに中身が格納されているか」といった管理情報を、**inode(アイノード、水準八: ファイルの実体データそのものではなく、そのファイルのサイズ・所有者・格納されているブロックの場所などの管理情報〈メタデータ〉を記録した構造)**という別の構造に記録する。データそのものではなく、データについての情報(サイズ・作成日時・場所など)を**メタデータ(水準八: データそのものではなく、データについての情報)**と呼ぶ。
ファイル名とinode番号などの対応関係を記録した、特殊な種類のファイルを**ディレクトリ(水準八: ファイル名とinode番号などの対応関係を記録した、特殊な種類のファイル)**と呼ぶ。「フォルダを開く」という操作は、実はこのディレクトリという特殊なファイルの中身(名前とinode番号の対応表)を読んでいるだけなのである。
### よくある誤解 — 「削除すればすぐに完全に消える」という思い込み
ファイルを「削除」する操作の多くは、実際にはディスク上のデータそのものを即座に上書きして消すわけではない。多くのファイルシステムでは、削除操作は「ディレクトリの中の対応表からその名前を外し、使っていたブロックを"空き"として印をつけ直す」だけの、比較的軽い処理で済ませていることが多い。データの実体は、別のファイルによって上書きされるまで、ディスク上にそのまま残っていることがある。これは実装や設定によって差があるため一律には言えないが、「削除=即座に完全消去」という思い込みは、ファイルシステムの仕組みを正しく反映していない誤解であることが多い、という点は押さえておきたい。
---
> **定着量の目安(第八章)**: ブロック・ファイルシステム・inode・メタデータ・ディレクトリという5つの用語を説明できるようにするには、用語ドリル20問程度をこなすと、ほぼ完全に定着すると見込まれる。
---
## 第九章: トイファイルシステムを設計する — 簡易ファイル管理表の実装(水準九)
### FATという古典的な方式
ファイルの中身がディスク上のどのブロックに散らばっているかを記録する方式の一つに、**FAT(ファット、水準九: File Allocation Tableの略。ディスクをクラスタという単位に分け、各クラスタが次にどのクラスタへ続くかを記録した表形式で、ファイルの位置を管理する古くからの方式)**がある。FAT形式のファイルシステムにおける、複数のセクタをまとめた記憶割り当ての単位を**クラスタ(水準九: FAT形式のファイルシステムにおける、複数のセクタをまとめた記憶割り当ての単位)**と呼ぶ。
### 検算7 — 3つのクラスタにまたがるファイル
たまごOSの簡易ファイルシステムで、あるファイルがクラスタ5・クラスタ8・クラスタ2の順に格納されている場面を考える。この場合、FAT風の管理表(配列)は次のような形で、各クラスタの「次の行き先」を記録する。
```
管理表(添字=クラスタ番号、値=次のクラスタ番号。EOFはファイルの終わりの印):
表[5] = 8 ; クラスタ5の次はクラスタ8
表[8] = 2 ; クラスタ8の次はクラスタ2
表[2] = EOF ; クラスタ2でファイルは終わり
読み出し手順:
1. ディレクトリからこのファイルの先頭クラスタ番号(5)を得る
2. クラスタ5の中身を読む → 表[5]を見て次はクラスタ8とわかる
3. クラスタ8の中身を読む → 表[8]を見て次はクラスタ2とわかる
4. クラスタ2の中身を読む → 表[2]がEOFなので読み出し終了
```
この管理表さえたどっていけば、ディスク上でファイルの中身が飛び飛びの場所に散らばっていても、正しい順番でつなぎ合わせて読み出せる。ファイルを新規に作るときは、空いているクラスタをこの管理表に順番につなぎ、削除するときは管理表のエントリを「空き」の印に戻すだけでよい――第八章末の「よくある誤解」で触れた、削除操作が意外と軽い処理で済んでいるという事実は、この管理表の書き換えだけで削除が完了する、という具体的な仕組みに裏付けられている。
### コラム — 実在するファイルシステムの名前
本冊のたまごOSが扱う簡易FAT風の仕組みは、あくまで教育用に単純化したものである。実在のOSでは、Windowsで長く使われてきた**NTFS(水準九: Windowsで広く使われている、ジャーナリング機能などを備えたファイルシステム)**、多くのLinuxディストリビューションで標準的に使われる**ext4(水準九: 多くのLinuxディストリビューションで標準的に使われるファイルシステム)**、Appleの現行OSで使われる**APFS(水準九: Appleの現行OSで使われるファイルシステム)**など、それぞれに異なる設計上の工夫を持つ方式が使われている。これらの多くは、ファイルシステムへの変更操作をあらかじめログとして記録しておき、電源断などの異常終了からの復旧を容易にする**ジャーナリング(水準九: ファイルシステムへの変更操作をあらかじめログとして記録しておき、異常終了からの復旧を容易にする仕組み)**という工夫を備えている点で、本冊のたまごOSより一歩進んだ設計になっている。
---
> **定着量の目安(第九章)**: FAT・クラスタ・NTFS・ext4・APFS・ジャーナリングという用語と、検算7の管理表をたどってファイルを読み出す手順を、クラスタの数や順番を変えて自分の手で3例ほどトレースすると、ほぼ完全に定着すると見込まれる。
---
## 第十章: 仮想メモリ入門 — ページングとアドレス変換(水準十)
### 「自分専用の広い土地」という幻想
第六章で触れたとおり、プロセスが扱う番地と、実際のメモリチップ上の番地(物理アドレス)は一致しない。この不一致を利用して、各プロセスに「実際の物理メモリの配置を意識させない、独立した仮想的なアドレス空間」を見せる仕組みを**仮想メモリ(水準十: 各プロセスに、実際の物理メモリの配置を意識させない、独立した仮想的なアドレス空間を見せる仕組み)**と呼ぶ。複数のプロセスが同時に動いていても、それぞれのプロセスからは「自分だけが広いメモリを独占している」かのように見える――この幻想を支えているのが、仮想メモリの仕組みである。
### ページングという区画整理
仮想メモリを実現する代表的な方式が、仮想アドレス空間と物理メモリを、どちらも同じ固定サイズの単位に区切って対応づける**ページング(水準十: 仮想アドレス空間と物理メモリを、ページと呼ばれる固定サイズの単位に区切って対応づける方式)**である。この固定サイズの区画を**ページ(水準十: ページングにおける固定サイズのメモリ区画。実装によって幅があるが、4KB程度が広く使われる)**と呼び、どの仮想ページがどの物理ページに対応しているかを記録した表を**ページテーブル(水準十: 仮想ページ番号から物理ページ番号への対応を記録した表)**と呼ぶ。
仮想アドレスから物理アドレスへの変換を、CPUの命令を実行するたびに毎回ソフトウェアで計算していては遅すぎるため、多くのCPUには、ページテーブルを参照しながらこの変換を高速に行う専用のハードウェアである**MMU(エムエムユー、水準十: Memory Management Unitの略。ページテーブルを参照しながら仮想アドレスを物理アドレスに変換する専用のハードウェア)**が搭載されている。
### 検算8 — 仮想アドレスの変換
ページサイズを4KB(4096バイト)とするたまごOSで、仮想アドレス`10,000`番地へのアクセスが発生した場面を考える。まず、この番地がどのページの何バイト目かを求める。
```
仮想ページ番号 = 10,000 ÷ 4,096 = 2 余り 1,808
(10,000を4,096で割ると、商2・余り1,808)
→ 仮想ページ番号は2、そのページ内でのオフセット(ずれ)は1,808バイト目
```
ページテーブルを調べ、仮想ページ番号2が物理ページ番号7に対応しているとわかれば、実際にアクセスすべき物理アドレスは「物理ページ番号7の先頭 + オフセット1,808バイト」として求められる。プロセス自身は「仮想アドレス10,000番地」としか意識しておらず、実際にどの物理ページに置かれているかは、MMUとページテーブルの仕事として隠されている。
---
> **定着量の目安(第十章)**: 仮想メモリ・ページング・ページ・ページテーブル・MMUという5つの用語と、検算8の仮想アドレス変換(番地÷ページサイズで商と余りを求める手順)を、数値を変えて5問ほど自分の手で計算すると、ほぼ完全に定着すると見込まれる。
---
## 第十一章: ページフォールトとスワッピング — 仮想メモリの発展(水準十一)
### 「今そこにない」ときに起きること
ページテーブルを調べても、アクセスしようとした仮想ページが現在物理メモリ上に存在しない――そんな場面が起こりうる。このとき発生する例外を**ページフォールト(水準十一: アクセスしようとした仮想ページが、現在物理メモリ上に存在しないときに発生する例外)**と呼ぶ。「フォールト(fault)」という語は「誤り」も意味するが、ページフォールトは必ずしも異常事態やバグではなく、多くの場合、OSが正常に処理して対応する、想定内の出来事である。
### スワッピングという「一時退避」
物理メモリが足りなくなったとき、OSは使用頻度の低いページを選び、ディスクの一部に一時的に追い出すことで空き容量を作り出す。この仕組みを**スワッピング(水準十一: 物理メモリが足りなくなったとき、使用頻度の低いページをディスクの一部〈スワップ領域〉へ一時的に退避させ、メモリを空ける仕組み)**と呼び、退避先として使われる専用のディスク領域を**スワップ領域(水準十一: ページの退避先として使われる、ディスク上の専用領域)**と呼ぶ。退避されたページに再びアクセスが発生すると、そこでページフォールトが起こり、OSはスワップ領域からそのページをディスクから読み戻し、物理メモリに再配置する。
### TLB — 変換結果を覚えておく仕組み
ページテーブルを毎回律儀に参照していては、変換のたびに余計な手間がかかる。そこで多くのCPUは、最近使ったページテーブルの変換結果をキャッシュしておく、高速な専用の記憶装置である**TLB(ティーエルビー、水準十一: Translation Lookaside Bufferの略。最近使ったページテーブルの変換結果をキャッシュしておく、高速な専用の記憶装置)**を備えている。同じページへのアクセスが繰り返されるプログラムでは、TLBに変換結果が残っている限り、ページテーブルを参照し直す手間が省け、変換が速く済むという利点がある。
スワッピングは、ディスクへの読み書きという、メモリへのアクセスに比べてはるかに時間のかかる処理を伴うため、スワッピングが頻繁に発生する状態は、システム全体の体感速度を大きく低下させる原因になることがある。物理メモリを増設すると体感速度が改善しやすいとされる背景には、こうしたスワッピングの発生頻度が下がるという事情が関わっていることが多い。
---
> **定着量の目安(第十一章)**: ページフォールト・スワッピング・スワップ領域・TLBという4つの用語と、ページフォールトが起きてからページが再配置されるまでの流れを、自分の言葉で説明できるようにするには、用語ドリル15問程度をこなすと、ほぼ完全に定着すると見込まれる。
---
## 第十二章: スケジューラの発展的理解 — 優先度・プリエンプション・タイムスライス(水準十二)
### ラウンドロビン — 平等に順番を回す
第五章で扱ったたまごOSの簡易スケジューラは、待機中でないプロセスのPCBを順番に選ぶだけの単純な方式だった。これをさらに発展させ、各プロセスに一定時間ずつ順番にCPUを割り当てる方式を**ラウンドロビンスケジューリング(水準十二: 各プロセスに一定時間〈タイムスライス〉ずつ順番にCPUを割り当てる方式)**と呼ぶ。1つのプロセスに割り当てられる一回あたりのCPU使用時間を**タイムスライス(水準十二: ラウンドロビン方式で、1つのプロセスに割り当てられる一回あたりのCPU使用時間)**と呼び、タイムスライスを使い切ったプロセスは列の最後尾に回され、次のプロセスにCPUが渡される。
### 優先度という重みづけ
すべてのプロセスを平等に扱うラウンドロビンに対して、プロセスごとに優先度を設定し、優先度の高いプロセスを優先的に実行する**優先度スケジューリング(水準十二: プロセスごとに優先度を設定し、優先度の高いプロセスを優先的に実行する方式)**という考え方もある。ただし、優先度の高いプロセスばかりが実行され続けると、優先度の低いプロセスがいつまでもCPU時間を得られない**飢餓状態(きがじょうたい、水準十二: 優先度の低いプロセスが、優先度の高いプロセスに割り込まれ続けて、いつまでもCPU時間を得られない状態)**に陥ることがある。
この弱点への対策として研究されてきた方式の一つが、優先度の異なる複数のキュー(待ち行列)を用意し、プロセスの実行の様子に応じてキュー間を移動させる**マルチレベルフィードバックキュー(水準十二: 優先度の異なる複数のキューを用意し、プロセスの実行の様子に応じてキュー間を移動させる、より洗練されたスケジューリング方式)**である。諸説あるが、この方式の源流は1960年代初頭のCTSS(Compatible Time-Sharing System、マサチューセッツ工科大学で開発された初期のタイムシェアリングシステム)やMulticsの研究にまでさかのぼるとされる。
### たまごOSから、その先へ
たまごOSのスケジューラは、ここまで見てきたラウンドロビンの考え方をひとまずの到達点とする。実際のOS(Linux・Windows・macOSなど)のスケジューラは、CPUコアが複数ある環境での負荷分散、省電力のための工夫、リアルタイム性が求められる処理の優先扱いなど、本冊で扱った基礎の上に、さらに何層もの工夫を積み重ねた、はるかに複雑な仕組みになっている。しかし、その複雑な仕組みの土台にあるのは、結局のところ本冊で追ってきた「電源を入れる」「ブートローダに引き渡す」「カーネルが割り込みを整える」「プロセスを切り替える」「メモリを区画整理する」「ファイルを台帳で管理する」という、ごく基本的な考え方の積み重ねである。
---
> **定着量の目安(第十二章)**: ラウンドロビンスケジューリング・タイムスライス・優先度スケジューリング・飢餓状態・マルチレベルフィードバックキューという5つの用語を説明できるようにするには、用語ドリル20問程度と、優先度の異なる3プロセスを紙の上でスケジューリングし、飢餓状態が起きる条件を自分で作ってみる演習を3例ほどこなすと、水準十二の内容がほぼ完全に定着すると見込まれる。
---
## 三つの実践解(§16.21) — 安全に手を動かして確かめる方法
理論と計算を、実際に手を動かして確かめる方法を三つ紹介する。いずれも、実在のOSへの侵入・改造や、他人の管理する計算機を対象にした操作を一切含まない、観察と学習だけの安全な実践解である。
1. **プロセス一覧の観察実践**: 自分が管理しているパソコンで、タスクマネージャー(Windows)や`ps`・`top`コマンド(Linux・macOS)を開き、実際に動いているプロセスの一覧を観察する。第四章・第五章で扱ったプロセスの状態(実行中・待機など)が、実際の画面上でどう表示されているかを見比べる、読むだけの安全な実践である。
2. **仮想マシン上でのトイOS起動実践**: QEMUなどのエミュレータ(実機を模した仮想的な計算機環境)を使い、第二章で紹介したような簡単なブートローダを、あくまで仮想マシンの中だけで起動して動作を確かめる。実機のハードウェアには一切書き込まず、仮想環境の中で完結させることが、この実践の安全上の前提である。マサチューセッツ工科大学で教育用に公開されている**xv6(エックスブイシックス、水準二: マサチューセッツ工科大学の授業〈6.828/6.S081〉で教材として使われている、教育目的の小型Unix系OS)**のような、実在する教育用トイOSのソースコードを読んでみるのも、良い次のステップになる。
3. **ファイルシステムの実測実践**: 自分が管理しているフォルダの中のファイルについて、プロパティ画面や`ls -l`コマンドでファイルサイズを確認し、第九章の考え方(ブロック・クラスタ単位での割り当て)にもとづいて、実際に何ブロック分の記憶領域が使われているかを計算し、表示されている「サイズ」と「ディスク上のサイズ」の違いを見比べる。
---
## まとめ — たまごから、一人前の計算機へ
本冊では、真っ黒な画面に"Hello, world."とだけ表示されたたまごOSを渡された新人プログラマーの物語から出発し、電源投入直後のリセットベクタとBIOS・UEFI(第一章)、512バイトのブートセクタに書かれたブートローダ(第二章)、カーネルへの橋渡しと割り込みの仕組み(第三章)、プログラムとプロセスの違い(第四章)、マルチタスキングとコンテキストスイッチ(第五章)、アドレス空間・スタック・ヒープ(第六章)、単純なメモリアロケータの設計(第七章)、ファイルシステムの正体としてのブロック・inode・ディレクトリ(第八章)、FAT風の簡易ファイルシステムの実装(第九章)、仮想メモリとページング(第十章)、ページフォールトとスワッピング(第十一章)、そしてスケジューラの発展的理解(第十二章)までをたどってきた。
電源ボタンを押した瞬間から、たった一行の文字列が画面に表示されるまでの間には、これほど多くの段階が積み重なっている。そして、プロセス・メモリ管理・ファイルシステムという三つの仕組みは、その一行が表示された後も、パソコンが動いている限りずっと働き続けている縁の下の力持ちである。本冊で追ってきたたまごOSは、実運用のOSと比べればごく小さな卵のような存在にすぎないが、その卵の中には、現在広く使われているOSの中核にある考え方の種が、確かに詰まっている。次巻(→BOOK-0342、CPUのレジスタや命令実行の仕組みを扱う予定・予約番号のみ確定)では、この冊子で「与えられたもの」として扱ってきたCPUそのものの内部――論理回路がどう組み合わさって命令を実行しているか――へと、話を一段掘り下げていく予定である。
---
## 章末: 簡易起動シーケンス図とまとめの階段図
まず、第一章から第三章で追った起動シーケンスを、ASCII図で表してみよう。
```
[電源ON] → [リセットベクタ] → [BIOS/UEFIがPOSTを実行]
→ [ブートデバイスを探索] → [ブートセクタ(512バイト)を読み込み]
→ [ブートローダが実行開始] → [カーネルをメモリへ読み込み]
→ [カーネルが割り込みベクタテーブル等を初期化] → ["Hello, world."表示]
```
続いて、本冊全体の歩みを階段図としてまとめる。
```
[水準十二] スケジューラの発展的理解
ラウンドロビン・優先度・マルチレベルフィードバックキュー
▲
│ 平等さと優先度のバランスを取る
[水準十・十一] 仮想メモリ・ページング・スワッピング
検算8: 仮想アドレス10,000番地 → ページ番号2・オフセット1,808
▲
│ 「自分専用の広い土地」という幻想を支える
[水準八・九] ファイルシステムとFAT風の管理表
検算7: クラスタ5→8→2→EOFをたどって読み出す
▲
│ ディスクという「ただの棚」に名前をつける
[水準六・七] メモリ管理とアロケータ
検算6: 1024バイトのヒープでの断片化
▲
│ プロセスに「自分だけの土地」を用意する
[水準四・五] プロセスとマルチタスキング
PCB・コンテキストスイッチ・プリエンプティブ方式
▲
│ レシピ(プログラム)を実際に動かす
[水準一〜三] 起動(ブート)・ブートローダ・カーネル
電源投入からHello, world.まで
安全枠: 教育用の縮小トイOS実装に限定。実在OSへの侵入・権限昇格・マルウェア作成技術は一切扱わない。
```
---
## 参照文献(定番教科書・一般規格)
1. オペレーティングシステムの標準的な教科書群(大学初年次・情報工学系で広く使われている、プロセス・メモリ管理・ファイルシステムを扱う定番の入門教科書)。
2. マサチューセッツ工科大学 6.828/6.S081 教材、教育用OS「xv6」のソースコードと解説資料。
3. アンドリュー・タネンバウムによるMINIXおよびモノリシック/マイクロカーネル論争に関する著作・記録群。
4. Intel/AMD系CPU(x86系)アーキテクチャの一般公開されている技術資料(リアルモード・保護モード・割り込み・ページングの仕様に関する部分)。
5. UEFI Forumによる仕様公開資料(UEFI・GPTの一般的な仕様に関する部分)。
---
(本冊子は現代学問宇宙図鑑シリーズ BOOK-0340。応用の軌道ステーション群・「作る力と生きる力シリーズ」計算機文明部の第1巻(OSを作るということ 第1巻)。次巻(→BOOK-0342『論理回路からCPUへ』・予約番号のみ確定)では、CPU内部の論理回路と命令実行の仕組みを扱う予定。GAKUMON_UNIVERSE.md 進捗台帳を参照。)
# BOOK-0340 作る力と生きる力: OSを作るということ 第1巻 — たまごから芽吹く、小さな計算機の一生