PK
パーネルカニック研究所
今日もどこかでkernel panic。
root@pk-lab:~#

なぜLinux From Scratchを始めるのか

連載ナビ

この連載は「Linuxを使えるようになる」ではなく、「Linuxがどう動いているのか」を理解するための実践シリーズです。

今回は Linuxを理解する 〜 LFSで学ぶLinux内部構造 〜 の Part 1 / 第1回です。

—

LFSは「Linuxを説明できるエンジニア」になる最短の遠回り

Linux From Scratch(LFS)とは、UbuntuのようなできあいのOSを使わず、コンパイラの構築からカーネルのビルド、ブートローダの設定まで、OSを構成するすべてのソフトウェアをソースコードから自分の手で組み上げる学習プロジェクトです。

結論から言います。LFSに取り組む最大の理由は、Linuxが動く仕組みを「推測」ではなく「自分でやった経験」として説明できるようになるからです。できあがるOSはUbuntuより不便です。それでも、組み上げる過程で得られる理解は、既成のOSを何年使っても手に入りません。

ディストリビューションの「便利さ」が、理解の壁になっているから

なぜわざわざ手作業でOSを作るのか。理由は、普段使っているディストリビューションが優秀すぎて、内部の仕組みを見せてくれないからです。

たとえばUbuntuで apt install nginx と打てば、数十秒でNginxが動き始めます。しかしその裏では、

  • 依存する共有ライブラリの解決と配置
  • 実行ファイル・設定ファイル・ログディレクトリの標準的な場所への展開
  • systemdへのサービス登録と自動起動の設定

がすべて自動で行われています。便利ですが、「何が・どこに・なぜ置かれたのか」は一切見えません。この状態でトラブルが起きると、エラーメッセージを検索して出てきたコマンドを貼り付ける「対症療法」しかできなくなります。

LFSは、この自動化されている部分をすべて手作業に置き換えます。LFSブック(公式の手順書。LFS 12系が現行)では、おおよそ次の工程を踏みます。

1. ホストLinux上でのパーティション作成と作業環境の準備

2. クロスツールチェーンの構築(Binutils → GCC → Glibc の順にビルド)

3. 一時的な最小システムのビルドと、chrootによるホストからの隔離

4. 基本システムを構成する約90個のパッケージを、依存順に1つずつビルド

5. Linuxカーネルのビルドと、GRUB(ブートローダ)の設定

6. 自分で組んだシステムの起動

この工程の一つひとつが「なぜ必要なのか」を突きつけてきます。なぜコマンドより先にコンパイラを作るのか。なぜGCCを一度で済ませず複数回ビルドし直すのか。なぜchrootで隔離しないといけないのか。手を動かすたびに、ツールチェーン・ライブラリ・カーネル・initといった部品同士の依存関係が、体験として頭に入っていきます。

同じエラーでも「見えるもの」が変わる

LFS経験の有無で何が変わるのか、実際によく遭遇するエラーで比べてみます。プログラムを実行したときに出るこのメッセージです。


error while loading shared libraries: libfoo.so.1:
cannot open shared object file: No such file or directory

LFS経験なしの対応:

エラーメッセージでそのまま検索し、出てきた apt install コマンドをコピペする。動けば終わり。なぜ直ったのかは分からない。

LFS経験ありの思考:

LFSでは、Glibcをビルドした直後に動的リンカ(ld-linux)の動作確認を自分で行います。だからこのエラーを見た瞬間に、次のことが分かります。

1. これはコンパイルエラーではなく、実行時に動的リンカが共有ライブラリを見つけられなかったというエラーである

2. 動的リンカは /etc/ld.so.cache(/etc/ld.so.conf から生成されるキャッシュ)と標準パス(/lib、/usr/lib など)を探す

3. だから調査手順はこうなる:


# このプログラムが必要とするライブラリと、解決状況を確認
ldd /path/to/program

# ライブラリがキャッシュに登録されているか確認
ldconfig -p | grep libfoo

# 見つかった場所が標準外なら、一時的に教える(検証用)
LD_LIBRARY_PATH=/opt/foo/lib /path/to/program

# 恒久対応なら、設定ファイルに追記してキャッシュを再生成
echo "/opt/foo/lib" | sudo tee /etc/ld.so.conf.d/foo.conf
sudo ldconfig

「動的リンカがどういう順序でライブラリを探すか」を知っているので、一時対応(LD_LIBRARY_PATH)と恒久対応(ld.so.conf.d + ldconfig)を状況に応じて選べます。これが「対処法を知っている」と「仕組みを理解している」の差です。

作るのは「速いOS」ではなく「説明できる自分」

LFSの目的は、Ubuntuより優れたOSを作ることではありません。完成品を最小の部品から組み上げ直す過程で、「なぜその部品が必要なのか」「なぜその順序なのか」を自分の言葉で説明できるようになることが目的です。

この連載では、いきなりLFSのビルドに入るのではなく、Part 1で前提知識と環境を整え、Part 2でLinuxの基本構造(ディレクトリ、プロセス、ブート)を、Part 3でツールチェーン(GCC・Glibc・Binutils)を理解してから本番に挑みます。

次回は、その第一歩として「ディストリビューションとは何か」を分解します。普段使っているUbuntuが、実は何と何の組み合わせでできているのかを見ていきましょう。