わたすけです。
このブログを見ている人の中にはArch Linuxをライブ起動して、pacstrapとかでインストールした人も居るかと思います。
その中でブートローダーをインストールする時、このようなコマンドを入力したのではないでしょうか?
grub-mkconfig -o /boot/grub/grub.cfg
今回は、この/bootディレクトリに迫っていこうと思います。
環境
Arch Linuxで解説します。よくあるLinuxならおおよそ同じだと思いますが、一応環境を限定しておきます。
/bootを見てみる
まずは/bootにあるファイルを見ていきましょう。
$ ls -l /boot
total 52428
drwxr-xr-x 6 root root 4096 Jul 31 2020 grub
-rw------- 1 root root 34072789 Jan 28 16:19 initramfs-linux-fallback.img
-rw------- 1 root root 9069823 Jan 28 16:19 initramfs-linux.img
-rw-r--r-- 1 root root 10531168 Jan 28 16:19 vmlinuz-linux
色々ありますね。
今回は、このinitramfs-linux.imgと、vmlinuz-linuxについて解説します。
initramfs
これはその名の通り、初期化(init)時にRAM上に展開されるファイルシステム(fs)です。
fileコマンドで見てみましょう。
$ file /boot/initramfs-linux.img
/boot/initramfs-linux.img: Zstandard compressed data (v0.8+), Dictionary ID: None
Zstandart compressed data
、つまりzstd形式で圧縮されたものです。odコマンド等でバイナリを覗いてみても、zstdのマジックナンバー(0x28 b5 2f fd)を見ることが出来ます。
展開してみる
それでは展開してみましょう。一応ホームディレクトリなり何なりにコピーしてから、zstd
コマンドで展開してみます。
$ ls
initramfs-linux.img
$ zstd -d initramfs-linux.img -o initramfs-linux
$ ls
initramfs-linux initramfs-linux.img
ちょっと分かりづらいですが、.imgという拡張子が付いていないほうが展開したものになります。
これもfileコマンドで見てみましょう。
$ file initramfs-linux
initramfs-linux: ASCII cpio archive (SVR4 with no CRC)
cpioアーカイブファイルでした。
この名前、聞き覚えがある人も多いと思います。そう、Arch Linuxにおいてmkinitcpioコマンドを実行したことがある人は多いでしょう。
Arch Linuxにおけるmkinitcpioというコマンドは、ほぼ名前の通り、cpioファイルを作成するというコマンドです。
cpioとは?
そもそもcpioというのはアーカイブファイルのフォーマットです。複数ファイルおよびディレクトリを単一のファイルに格納するというのがアーカイブファイルの役割で、tarと似たような用途です。cpioもtarも、まとめるだけで圧縮されないという特徴もあります。
cpioファイルも展開してみる
こっちも展開してみましょう。cpio
コマンドを使いますが、zstd
コマンドとは異なり、ファイルの中身を標準入力から渡します。
$ cpio -idv < initramfs-linux
$ ls
bin config etc init initramfs-linux lib new_root run sys usr VERSION
buildconfig dev hooks init_functions initramfs-linux.img lib64 proc sbin tmp var
binやlib、etcやdevなど、Linuxで見慣れたディレクトリがたくさんあります。
起動時は、initramfsファイルをRAM上に展開します。つまり、RAM上にこれらのファイルを展開しているということです。
展開されてどうなるのかについては、以下の記事で解説されています。これは「GRUBがどう扱うか」についての解説ですが・・・
余談
余談ですが、lsinitcpio
というコマンドを使うことで、展開をせずとも直接ファイルの中身を覗くことが出来ます。
Arch Linuxにおいて、このコマンドは mkinitcpio
パッケージに含まれています。mkinitcpio
パッケージはLinuxカーネルの依存パッケージなので、まあどの環境でも使えると思います。
$ lsinitcpio initramfs-linux.img
bin
buildconfig
config
dev/
etc/
etc/fstab
etc/initrd-release
etc/ld.so.cache
etc/ld.so.conf
etc/modprobe.d/
etc/mtab
hooks/
hooks/udev
init
init_functions
lib
lib64
(略)
vmlinuz-linux
さて、/bootにあったもう一つのファイル、vmlinuz-linuxについて解説していきます。
とりあえず挨拶がてらfileコマンドで覗いてみましょうか。
$ file vmlinux-linux
vmlinuz-linux: Linux kernel x86 boot executable bzImage, version 5.16.2-arch1-1 (linux@archlinux) #1 SMP PREEMPT Thu, 20 Jan 2022 16:18:29 +0000, RO-rootFS, swap_dev 0XA, Normal VGA
Linux kernel x86 boot executable bzImage
らしいです。
bzImageはbig zImageのことで、zlibアルゴリズムによって圧縮されたものです。
このbzImage、なかなか複雑なフォーマットをしています。まずマジックナンバーを見ると、0x5a 4dとなっており、MZ形式であるように見えます。
しかし実態はそうではありません。実はこのbzImage、複数のファイルから成る形式なのです。
正直このあたりはよくわかってないことが多いのであまり触れないでおきます。Wikipediaには以下のような図があります。
bzImage = setup.bin + vmlinux.bin
setup.bin <---(raw binary)--- setup.elf <--- header.o + main.o + more...
vmlinux.bin <---(raw binary)--- head_(BITS).o + misc.o + more... + piggy.o
piggy.o <---(compressed + embedded)--- vmlinux <--- vmlinux.o + .tmp_kallsyms2.o <--- *.o *.a
`|
System.map
initramfs-linux.imgはファイルを含むバイナリだったのに対し、vmlinuz-linuxはLinuxカーネルを含む実行ファイルです。起動時はvmlinuz-linuxが自分自身を解凍し、Linuxカーネルを取り出します。
終わりに
fileコマンドはべんりだなあとおもいました
vmlinuz-linuxの仕組みを解明することが、Linuxブートプロセスに関する理解を深める一歩になると考えています。これからもちまちま調べていこうと思っています。
コメント