initramfsで遊んでみた

初心者がinitramfsで遊んでみました。

# 起動しねぇ！
fstabが見つからない？どういうことだ！
なんか回復シェル的なの動いてるし！
→　もしかして：**「initramfs」**

(試したディストリビューションはalpine)

## 前提知識
initramfs等を知る前に、次の知識を知っておくほうが良いでしょう。

- (linux)
- bios
- gpt/uefi
(mbrも本当は知るべきなんでしょうがよくわからん！ｺﾞﾒﾝ!)
- カーネル
- カーネルモジュール

それでは一つずつ確認していきましょう。

### bios
　basic input output system 略してbios. biosはio規格の一つです。　io規格によってbios規格に準拠しているhwならば、プログラムの変更なしで動くようになります。　ただし、「基本的なこと」だけを規格化(Cでいう標準ライブラリ）されているので、「高度な処理」や、「独自の命令」は後述する**ドライバ**によって、**OSを通じて直接送る**ことになります。　
　話戻して、biosにはもう一つ重要な役割を持ちます。　それは **「補助記憶装置からのプログラム呼び出し」** です。 言い直すと「カーネルの呼び出し」になります。

### gpt/uefi
　上記biosを進化させた規格です。　gpt(GUIDパーティションテーブル)はパーティション規格の一つで、この規格に準拠して管理している補助記憶装置（HDD・SSD）ならば、HWを変更しても問題なくパーティション情報を維持することができます。　GPTは補助記憶装置の先端と後端に置かれ、パーティション情報を記録しています。
　efiには、efi専用のパーティションが規格されていて、ファイルシステムはfat32と決まっています。　efiパーティションにはefiアプリケーションを設置することができます。

### kernel
　カーネルの定義はあいまいです。一つは複数のプログラムを共存させることができるプログラムです。複数プログラムの共存をマルチタスクなどといいますが、それを実装させています。　もう一つは複数のIO機器に対応することです。　linux等のモノリシックカーネルでは、IO制御をとにもかくにもカーネルがやります。そのため独自規格を持つＩＯには、**カーネルが対応できるIOの数を増やす「モジュール」** を追加することで対応を行っています。　一方windows等のハイブリッドカーネルは、特定のIO制御に関しては特定のプログラムに丸投げします。　そのため独自規格を持つＩＯには、**特定のIOを制御することができるプログラム「ドライバ」** を追加することで対応を行っています。

 まとめると「マルチプロセス管理」「ＩＯ制御」をしています。

### カーネルモジュール
前項でも述べた通り、「カーネルに機能を追加する」ものです。
 
## ということで
uefiはまず、**efiパーティション**に入っているefiアプリケーションを起動します。(grubとか) 
このアプリケーションは、**vmlinuz** (linuxカーネル本体)を呼び出します。

linuxカーネルは、initramfsをメモリに展開し、`/`(ルート)にマウントします。

### ところで
initramfsはモジュールを減らし、コマンドも減らした環境。(~~コマンド数ではぶっちゃけalpine linuxだと違いが判らん~~)　
ext4などを使ってるメインのファイルシステムをマウントできることが最低条件です。

:::note warn
つまり、initramfsの環境で操作できない！！！　ときは「**キーボードを操作するためのモジュールが入っていない**可能性が高い」です。
:::

### で？
initramfsは、メインのファイルシステムを読み込みマウントします。
そのあと、`switch-root`コマンド（後述）によってinitramfsはそのままメモリから除去されます。

### そしたら...
systemd や openrcを起動させます。　こいつらがネットワークなどのサービスを起動させ、ユーザーセッション、ログイン画面となるわけです。

# initramfsで遊びたい！

:::note warn
最悪ブートしなくなりますので注意してください
:::
単純に、fstabファイルを改名してあげてください。

# 参考
- [archlinux: mkinitcpio](https://wiki.archlinux.jp/index.php/Mkinitcpio#.E7.94.9F.E6.88.90.E3.81.AE.E3.82.AB.E3.82.B9.E3.82.BF.E3.83.9E.E3.82.A4.E3.82.BA)
- [alpine: Initramfs_init](https://wiki.alpinelinux.org/wiki/Initramfs_init)
- [gentoo: Initramfs(ja)](https://wiki.gentoo.org/wiki/Initramfs/Guide/ja)
- [Wikipedia: GUIDパーティションテーブル](https://ja.wikipedia.org/wiki/GUID%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB)
- [Wikipedia: Basic Input/Output System](https://ja.wikipedia.org/wiki/Basic_Input/Output_System)

# その他

### 今回あったトラブル（本題？）
initramfsがfstabが見つからないとエラーする。

これは、zfsが特殊なマウントシステムを採用しているからです。今回はルートにしたいzfsボリュームのマウントポイントを`/sysroot`に変更することで対処しました。
`zfs set mountpoint=/sysroot <volume名>`

### 回復ディスクは不要？
initramfsではネットワークが使えなかったりするのであんまり使い物になりません。
あくまでメインのfsを読み込むことが目的です。
なので、回復ディスクは一つあるとよいです。 (**[特にarchのインストールディスクが優秀](https://www.archlinux.jp/download/)**)

### initramfsは展開できるの？
やろうと思えばできるらしいです。

### execコマンドって何？
別記事にまとめたいんですが、pidを引き継いでプロセスを動かせます。　よく**Docker PID1問題**とか見ますけれど、実は`exec`コマンドで解決できたりします。　なーぜかあんまり記事を見ないからもっと流行れ（切実）

### switch-rootって何
[初めにmanページを見る](https://www.man7.org/linux/man-pages/man8/switch_root.8.html)

...まとめると、別のファイルシステムをroot(`/`)にしますよっていうらしい。
chrootと違うのは、procとかsysとかシステムに必要なファイルも一緒に移動させることらしいです。