Linuxのブートプロセス
1. システムのスイッチが入る - POST (Power On Self Test) プロセス
2. UEFI ファームウェアがロードされます。ファームウェアは起動に必要なハードウェアを初期化します
3. 次にファームウェアはブートマネージャのデータを読み込みどの UEFI アプリケーションをどこから (つまりどのディスク・パーティションから) 起動するか決定します
4. ファームウェアのブートマネージャのブートエントリに定義されているように UEFI アプリケーションをファームウェアが起動します
5. 起動した UEFI アプリケーションは設定によって他のアプリケーション (UEFI シェルや rEFInd の場合) やカーネルと initramfs (GRUB などのブートローダの場合) を起動します
MBR:先頭セクタの末尾が55 aaだったら0x7c00にコピーして実行
1セクタあたり512バイトだが、後半の方は予約領域やパーティションのテーブルエントリを指定する領域となっているため、コードは440バイトしか書けない
コード512バイト、スタック等のデータ領域512バイトを32KiB (0xFFFF) から引く (0xFFFF - 1024byte) と 0x7c00となり、これによってMBRとデータ領域がメモリの末尾にロードされることになる、というのがこのアドレスである理由
EFI:EFIパーティションを読み込み、どのパーティションもしくはアプリケーションを読み込むかを決定して実行(ここよくわかってない)(EFIシステムパーティションの、/EFI/BOOT/BOOTX64.EFI が読まれる?)
結局GRUB起動すれば変わらない?
GRUBはそのOSのカーネルvmlinuz-* とRAMディスク initramfs-*.img をメモリ上にロードし、カーネルの先頭アドレスにジャンプし、その役目を終える
ブートローダから起動されたカーネルの実行バイナリ vmlinuz は、低レベルな初期化処理を実行した後、カーネルの本体を自己解凍し、メモリにロードする。次に、カーネルの本体の先頭アドレスにジャンプした後、さらに様々な初期化処理を実行する>
カーネルは全ての初期化処理を終えると、初期RAMディスク (initrd) を展開し、仮のルートファイルシステムとしてマウントする。初期RAMディスクには、本番のルートファイルシステムが置いてあるディスクをマウントするために必要なドライバや、各種ユーティリティが含まれている
initrdには、主にinitrdとinitramfsの2形式があり、現在では後者が使われることが多い
GRUB起動→vmlinux展開→initramfs展開→init(systemdとか)がよしなに ということかな
VPS(Arch Linux)で/bootを見ると、initramfs-linux.img と vmlinuz-linux があった
initramfsは見ただけでは全くわからんけど、mkinitcpioとかあるしcpio形式?
cpioのマジックナンバーは0x070707らしいけど、見た感じちがうっぽい
$ od -Ax -tx2z /boot/initramfs-linux.img
000000 b528 fd2f 5804 ca8c ee05 885a 1e05 1052
...
fileコマンドの存在忘れてた Zstandard compressed data らしい
マジックナンバーは0x28b52ffd!
検索した時、Googleが Wikipedia から Zstandard dictionary のマジックナンバーを出してきて焦った vmlinuxはMZ形式?
fileコマンドによれば、Linux kernel x86 boot executable bzImage らしいです
initramfsをいい感じにコピーして展開してみようか
zstd -d initramfs-linux.img -o initramfs-linux として解凍、file initramfs-linux の結果はcpioとなった
cpioコマンドは標準入力から受け取るらしい cpio -idv < initramfs-linux とすると、見慣れたusrやetcなどのディレクトリが!!
sysやdevはからっぽ
ここで死ぬほどわかりやすい記事を見つけた
grubが何をしているのか等
網羅されてる感がある
中国語だけど(cha-boot という文字列がURLに含まれる、中国語で書かれたドキュメントをいくつか見つけた)