Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Linuxのブートプロセス initramfs編
Search
Satoru Takeuchi
PRO
March 15, 2025
Technology
2
83
Linuxのブートプロセス initramfs編
以下動画のテキストです。
https://youtu.be/Rx9XPkDclkY
Satoru Takeuchi
PRO
March 15, 2025
Tweet
Share
More Decks by Satoru Takeuchi
See All by Satoru Takeuchi
Rook: Intro and Deep Dive With Ceph
sat
PRO
1
110
会社員しながら本を書いてきた知見の共有
sat
PRO
3
780
デバイスにアクセスするデバイスファイル
sat
PRO
1
36
ファイルシステムのデータを ブロックデバイスへの操作で変更
sat
PRO
1
30
デバイスドライバ
sat
PRO
0
47
マルチスレッドの実現方法 ~カーネルスレッドとユーザスレッド~
sat
PRO
2
120
共有メモリ
sat
PRO
3
69
マルチスレッドプログラム
sat
PRO
3
57
Linuxのブートプロセス
sat
PRO
6
190
Other Decks in Technology
See All in Technology
Node-REDのFunctionノードでMCPサーバーの実装を試してみた / Node-RED × MCP 勉強会 vol.1
you
PRO
0
130
ビギナーであり続ける/beginning
ikuodanaka
3
480
あなたの声を届けよう! 女性エンジニア登壇の意義とアウトプット実践ガイド #wttjp / Call for Your Voice
kondoyuko
4
520
生成AI開発案件におけるClineの業務活用事例とTips
shinya337
0
190
タイミーのデータモデリング事例と今後のチャレンジ
ttccddtoki
6
1.9k
開発生産性を組織全体の「生産性」へ! 部門間連携の壁を越える実践的ステップ
sudo5in5k
1
1.4k
「良さそう」と「とても良い」の間には 「良さそうだがホンマか」がたくさんある / 2025.07.01 LLM品質Night
smiyawaki0820
1
450
SpringBoot x TestContainerで実現するポータブル自動結合テスト
demaecan
0
130
ビズリーチが挑む メトリクスを活用した技術的負債の解消 / dev-productivity-con2025
visional_engineering_and_design
1
1.2k
GitHub Copilot の概要
tomokusaba
1
150
Github Copilot エージェントモードで試してみた
ochtum
0
140
無意味な開発生産性の議論から抜け出すための予兆検知とお金とAI
i35_267
2
3.2k
Featured
See All Featured
The Language of Interfaces
destraynor
158
25k
Side Projects
sachag
455
42k
The Pragmatic Product Professional
lauravandoore
35
6.7k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
124
52k
Code Review Best Practice
trishagee
69
18k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
730
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Producing Creativity
orderedlist
PRO
346
40k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
The World Runs on Bad Software
bkeepers
PRO
69
11k
A designer walks into a library…
pauljervisheath
207
24k
Rails Girls Zürich Keynote
gr2m
94
14k
Transcript
Linuxのブートプロセス initramfs編 Mar. 15th, 2025 Satoru Takeuchi X: satoru_takeuchi 1
はなすこと • マシンの電源投入からinitramfsを使った場合にinitが起動するまでの流れ ◦ 使わない場合は前回の動画「 Linuxのブートプロセス」を参照 ◦ Secure Bootは省略(後日別動画で説明するかも )
• 前回との差分を中心に紹介後、改めてinitramfs込のブートの流れを説明 • 環境 ◦ CPUアーキテクチャ: x86_64 ◦ ファームウェア: UEFI BIOS ◦ ブートローダ: GRUB ◦ ディスクが1台あり、GRUBとLinuxをインストールしている ▪ ディスクのドライバはカーネルモジュールとして持つ ▪ カーネルモジュールは rootfsに存在する 2
カーネル機能の提供方法についてのジレンマ • カーネル機能は本体に組み込むか外付けのカーネルモジュールとして提供可能 • カーネル本体のサイズはなるべく小さくしたい ◦ メモリ使用量が減らせる ◦ カーネルのロードが速くなる →起動が速くなる
• なるべく多くのカーネル機能を使いたい ◦ とくにユーザのハードウェア環境がわからない&なるべく多くの環境で動かせるようにしたいディストリビュータに当て はまる • カーネルが提供する機能を多くして、ほとんどをカーネルモジュールで提供すればいいとこどり できる 3
課題と解決方法 • rootfsをmountするまではカーネル本体に組み込まれた機能のみ使用可能 1. カーネルモジュールはディスクのファイルシステム上に存在する 2. モジュールをロードするには rootfs上のmountが必要 3. それにはrootfsがあるディスクのドライバ、
rootfsのファイルシステムドライバなどが必要 4. これらの機能をモジュールとして提供しているとドライバが読めない ▪ 📝 boot中に”VFS: Unable to mount root fs”というログが出る場合、この問題に遭遇してい るの可能性が高い • そこでinitramfsですよ ◦ ブート時に必要なカーネルモジュールを含む仮の rootfs用をcpioで固めて圧縮したファイル ◦ 展開後の仮のrootfsもinitramfsと呼ぶ 4
initramfsがない場合との違い • GRUBはvmlinuzファイルとinitramfsをメモリ上にロード • initramfsを仮のrootfsとしてmount&その上の仮のinitを実行 • 仮のinitがディスクから真のrootfsを読み出しrootfsを切り替え 5
GRUBがvmlinuzファイルとinitramfsをメモリ上にロード • vmlinuzに加えてinitramfsは通常ブートパーティション(“/boot/”)に存在 • ロードの流れ 1. 設定に基づきシステムに存在するカーネルの一覧を取得し、カーネルと initramfsをブートパラメタで 指定する(“root”,”initrd”パラメタ) 2.
vmlinuzファイルとinitramfsをメモリ上にロード 6 物理アドレス空間 カーネル展開 コード カーネル圧縮 イメージ disk GRUB (1) vmlinuzとinitramfsを指定 (2) ロード initramfs
initramfsを仮のrootfsとしてmount&その上のinitを実行 1. カーネルはinitramfsファイルを展開してメモリ上にtmpfsのデータ構造を作る 2. tmpfsを仮のrootfsとしてmount a. この後はカーネルモジュールを読めるのでロード可能 3. tmpfs上のinitを実行 7
物理アドレス空間 カーネル (1) initramfsを展開して tmpfsのデータ構造を作成 仮のrootfs (tmpfs) initramfs (2)(3) tmpfsを仮のrootfsと してmount&init実行
仮のinitがディスクから真のrootfsを読み出しrootfsを切り替え 1. “root”ブートパラメタで指定した真のrootfsをディスクから読み出しmount a. カーネルモジュールをロードできるのでディスクドライバ、ファイルシステムドライバはカーネルモ ジュールとして提供されていても OK 2. rootfsを仮のものから真のものに切り替え 3.
真のrootfs上のinitをメモリマップして実行 8 物理アドレス空間 disk カーネル (1) 真のrootfsを読み出しmount (2)(3) rootfsを切り替え&真のinitを実行 仮のrootfs (tmpfs) 真のrootfs
initramfsを考慮したブート処理の流れ 1. 人間がマシンの電源を入れる 2. マシン上のUEFI BIOSが起動 3. UEFI BIOSがハードウェアを初期化 4.
UEFI BIOSがGRUBをロードして実行 5. GRUBがvmlinuzファイルとinitramfsをメモリ上にロード 6. GRUBがカーネル展開コードを実行 7. 展開コードがカーネルをロードして実行 8. カーネルがシステムを初期化 9. initramfsを仮のrootfsとしてmountして仮のinitを動かす 10. rootfsを仮のものから真のものに切り替える 9
マシン上のUEFI BIOSが起動 • マシンは電源を入れると特定アドレス(0xFFFFFFF0)上に存在するUEFI BIOSプロ グラムを動かすようになっている • UEFI BIOSはマシンの不揮発性メモリ上に存在しており、システム起動時に物理ア ドレス空間の上述のアドレスにマップされている
◦ 📝 つまり物理アドレスが物理メモリ以外のデータを指すことがある ◦ 📝 UEFI BIOS以外にも物理アドレス空間にマップされるデータは他にもあるが、本動画では以下 のようなイメージを持っていればいい 10 物理アドレス空間 0 0xFFFFFFF0 不揮発性メモリ上の UEFI BIOS 物理メモリ 物理メモリ
UEFI BIOSがハードウェアを初期化 • CPUの動作確認、初期化 ◦ ブート直後は機能制限されていて、 UEFI BIOSが制限を外すというイメージ • メモリの動作確認、初期化
◦ これをする前は物理メモリにアクセスできない! • ディスクなどのその他ハードウェアを初期化 • どこの領域にどんなデータがマップされているかを記録 ◦ 📝 後でカーネルが使う 11
UEFI BIOSがGRUBをロードして実行 1. GPT形式のパーティションテーブルでフォーマットされたディスクを探す 2. ESP(EFI System Partition)というGUIDを持つパーティションを見つける a. 📝
このパーティションは FAT32ファイルシステムでフォーマットされている 3. ESPから「UEFIアプリケーション」と呼ばれる実行ファイルを見つける a. 📝 UEFIアプリケーションを実行するのは LinuxではなくUEFI BIOS 4. UEFI BIOSはUEFIアプリケーションであるGRUBをロード&実行 a. 通常はGRUBがデフォルトで動作するように設定されている 12 UEFI BIOS 物理アドレス空間 disk (1)(2)(3)GRUBを見つける GRUB (4) GRUBをロード&実行
GRUBがvmlinuzファイルをロード(前提知識) • ESPはLinux動作時に通常(“/boot/efi/”)にマウントされている ◦ GRUB EFIアプリケーションのファイル名は通常 ”/boot/efi/EFI/BOOT/BOOTX86.EFI” • vmlinuzとinitramfsは通常ブートパーティション(“/boot/”)に存在する ◦
📝 GRUBはLinuxの一部のファイルシステム (e.g. ext4, XFS)を読み出せる ▪ “/boot”はGRUBが読み出せるファイルシステムでなければならない • カーネル圧縮イメージのフォーマット(bzImage形式と呼ばれる): 13 setup header カーネル展開コード カーネル圧縮イメージ カーネル展開コードやカーネルの ロード先メモリアドレス、エントリポイ ントを保持
GRUBがvmlinuzファイルとinitramfsをメモリ上にロード • vmlinuzとinitramfsは通常ブートパーティション(“/boot/”)に存在 • 処理の流れ 1. 設定に基づきシステムに存在するカーネルの一覧を取得し、カーネルと initramfsをブートパラメタで 指定する(“root”,”initrd”パラメタ) 2.
vmlinuzファイルとinitramfsをメモリ上にロード 14 物理アドレス空間 カーネル展開 コード カーネル圧縮 イメージ disk GRUB (1) vmlinuzとinitramfsを読み出し (2) ロード * スペースの都合でsetup headerは省略 initramfs
GRUBがカーネルの展開コードを実行 • カーネル展開コードのエントリポイントにジャンプして実行開始 15 物理アドレス空間 カーネル展開 コード カーネル圧縮 イメージ disk
GRUB ジャンプ initramfs
展開コードがカーネルをメモリマップして実行 1. カーネル展開コードがカーネル圧縮イメージを読み出す 2. 圧縮イメージをメモリ上に展開してメモリ上にマップ 3. カーネルのエントリポイントにジャンプ 16 物理アドレス空間 カーネル展開
コード カーネル圧縮 イメージ disk カーネル (1) 読み出し (2) 展開&マップ (3) エントリポイントにジャンプ initramfs
カーネルがシステムを初期化 • ハードウェアやカーネルそのものの初期設定 ◦ 📝 UEFI BIOSはマシンの起動に必要な最低限の初期化しかしないが、カーネルによるハードウェ アの初期設定はシステムが稼働し続けるために必要な設定をするという違いがある • まだrootfsをmountしていないのでカーネルモジュールは読み出せない
17 物理アドレス空間 カーネル initramfs disk
initramfsを仮のrootfsとしてmountして仮のinitを動かす 1. カーネルはinitramfsファイルを展開してメモリ上にtmpfsのデータ構造を作る 2. tmpfsを仮のrootfsとしてmount a. この後はカーネルモジュールを読めるのでロード可能 3. tmpfs上のinitを実行 18
物理アドレス空間 カーネル (1) initramfsを展開して tmpfsのデータ構造を作成 仮のrootfs (tmpfs) initramfs (2)(3) tmpfsを仮のrootfsと してmount&initを実行 disk
rootfsを仮のものから真のものに切り替える 1. “root”ブートパラメタで指定した真のrootfsをディスクから読み出しmount a. カーネルモジュールをロードできるのでディスクドライバ、ファイルシステムドライバはカーネルモ ジュールとして提供されていても OK 2. 真のrootfs上のinitをメモリマップして実行 19
物理アドレス空間 disk カーネル (1) 真のrootfsを読み出しmount (2) 真のinitプログラムをメモリマップ &実行 仮のrootfs (tmpfs) 真のrootfs
おわりに • initramfsがあるとカーネル本体のサイズを小さく保ったまま多くの機能を提供でき る • 📝 他にも暗号化ディスク上にrootfsがあるような場合にもinitramfsを使う • 処理のステップ数が多い! ◦
技術的に難しいわけではなく単なる覚えゲーなので、何度か見れば多分理解できます 20