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
48
Linuxのブートプロセス initramfs編
以下動画のテキストです。
https://youtu.be/Rx9XPkDclkY
Satoru Takeuchi
PRO
March 15, 2025
Tweet
Share
More Decks by Satoru Takeuchi
See All by Satoru Takeuchi
マルチスレッドの実現方法 ~カーネルスレッドとユーザスレッド~
sat
PRO
2
41
共有メモリ
sat
PRO
3
47
マルチスレッドプログラム
sat
PRO
3
40
Linuxのブートプロセス
sat
PRO
6
150
シェルのジョブ
sat
PRO
1
28
常駐サービスを実現するデーモンプロセス
sat
PRO
0
35
絶対殺すSIGKILLシグナルと絶対死なないプロセス
sat
PRO
3
120
シェルのセッション
sat
PRO
2
36
RubyでKubernetesプログラミング
sat
PRO
4
190
Other Decks in Technology
See All in Technology
Creating Awesome Change in SmartNews
martin_lover
1
270
LLM as プロダクト開発のパワードスーツ
layerx
PRO
1
240
開発視点でAWS Signerを考えてみよう!! ~コード署名のその先へ~
masakiokuda
3
160
Spring Bootで実装とインフラをこれでもかと分離するための試み
shintanimoto
7
800
Les nouveautés d'OKDP - Open Kubernetes Data Platform
bluehats
0
110
CloudWatch 大好きなSAが語る CloudWatch キホンのキ
o11yfes2023
0
160
AIコーディングの最前線 〜活用のコツと課題〜
pharma_x_tech
1
620
Recap of Next - Google Cloud で実践する クラウドネイティブ最前線 / The Frontlines of Cloud-Native with Insights from Google Cloud
aoto
PRO
1
100
Webアプリを Lambdaで動かすまでに考えること / How to implement monolithic Lambda Web Application
_kensh
7
1.3k
3月のAWSアップデートを5分間でざっくりと!
kubomasataka
0
120
Spice up your notifications/try!Swift25
noppefoxwolf
2
350
ワールドカフェI /チューターを改良する / World Café I and Improving the Tutors
ks91
PRO
0
110
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
49
7.7k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
13
1.4k
Being A Developer After 40
akosma
91
590k
Rebuilding a faster, lazier Slack
samanthasiow
80
8.9k
The Invisible Side of Design
smashingmag
299
50k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.2k
Designing for humans not robots
tammielis
252
25k
KATA
mclloyd
29
14k
BBQ
matthewcrist
88
9.6k
Optimising Largest Contentful Paint
csswizardry
36
3.2k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
119
51k
Testing 201, or: Great Expectations
jmmastey
42
7.5k
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