Ubuntu Weekly Recipe

第384回 Initramfsのしくみ

この記事を読むのに必要な時間:およそ 4 分

Ubuntuはカーネルを起動したあと,ルートファイルシステムをマウントするために「Initramfs」というイメージファイルを使用します。今回はこのイメージファイルについて説明しましょう。

Initramfsの役割

Ubuntuはさまざまなディスクデバイスにルートファイルシステムをインストールし,起動するOSです。カーネルはブートローダーによって起動されたあと,ルートファイルシステムをマウントするために,サポートしているすべてのディスクデバイスのドライバを持っている必要があります。

しかしながらこのドライバをすべてカーネルに組み込んでしまうと,カーネルが肥大化してしまいます。しかもそのほとんどは,今使っているディスクデバイスでは不要なドライバです。必要なドライバを必要に応じてロードする仕組みとして「カーネルモジュール」がありますが,今度はその「カーネルモジュール」をどこに保存するのかという問題が発生します。当然のことながら,この時点でルートファイルシステムにはアクセスできません。

そこで出てくるのが「Initramfs」という仕組みです。

Ubuntuに限らずほとんどのLinuxディストリビューションでは,⁠ミニルート」とも呼ばれるメモリ上に展開可能な,小さなサイズのルートファイルシステムを持っています。このミニルートには,ルートファイルシステムをマウントするために必要なカーネルモジュールやスクリプトが保存されているのです。ブートローダーはカーネルと一緒にこのミニルートをメモリ上に展開し,カーネルにそのアドレスを伝えます。カーネルはそのアドレスを元にミニルートをマウントし,その中にあるスクリプトを実行することで本来のルートファイルシステムをマウントします。

「Initramfs」は,現在はデスクトップLinuxでもっとも使われているミニルートのファイルフォーマットの1つです注1)⁠Ubnutuだと「/boot/initrd.img-3.19.0-23-generic」などのカーネルバージョンごとファイルになります。

注1)
以前は「Initrd」という形式も使われていました。フォーマットが異なるだけで,役割は同じです。

図1 Initfamfsの画面

図1 Initfamfsの画面

ディスクの障害などによりルートファイルシステムをマウントできなくなったとき,⁠BusyBoxなんたら」とかいうメッセージとともに「(initramfs)」と表示されることがあります。これはInitramfsの中のBusyBoxのシェルが起動している状態です。普通のシェルに比べると,機能的な制約はありますが,使い方はそれほど変わるわけではありませんので,障害の要因などを追求できます。これもInitramfsの使い方の1つですね。

Initramfsを再構築する

Initramfsはファイルシステムをcpio形式でアーカイブしたうえで,gzipで圧縮したファイルです注2)⁠このため,以下のコマンドでInitramfsの中身を展開できます。

注2)
Ubuntuではgzipを使っていますが,xzやbzip2などもサポートしています。
$ mkdir /tmp/initramfs && cd $_
$ zcat /boot/initrd.img-`uname -r` | cpio -id
111416 ブロック
$ ls
bin  conf  etc  init  lib  lib64  run  sbin  scripts

ちなみにファイルリストを確認したいだけであれば,lsinitramfsという便利なコマンドも存在します。

$ lsinitramfs /boot/initrd.img-`uname -r`

展開したファイルに変更を加えたあと,新しいInitramfsを作成したい場合は次のコマンドを実行します。

$ cd /tmp/initramfs
$ find . | cpio -R 0:0 -o -H newc | gzip > initrd.img

あとはブートローダーにこのInitramfsを使うように設定すれば,新しいInitramfsで起動できるようになります。

カーネルアップデート時のInitramfsの再構築

この「/boot/initrd.img」ですが,dpkgで問い合わせてもどのパッケージにも属していないことがわかります。

$ dpkg -S /boot/initrd.img-`uname -r`
dpkg-query: パターン /boot/initrd.img-3.19.0-23-generic に一致するパスが見つかりません

実はこのファイルは,カーネルパッケージがアップデートされる度に作り直しているファイルです。Initramfsにはカーネルモジュールを保存します。しかしながらカーネルモジュールは全体のサイズも大きく,いくら圧縮したものとは言え,重複したデータを送るのは非効率です。

またカーネルパッケージが提供するカーネルモジュール以外にも,DKMSなどによってインストールされるモジュールもあります。よってカーネルパッケージで完成されたInitramfsを提供するよりは,システムごとに再生成したほうが効率的なのです。カーネルやカーネルモジュールパッケージのアップデート時は,以下のようなログが表示されるはずです。

update-initramfs: Generating /boot/initrd.img-3.19.0-23-generic

これを実現するため,Ubuntuではinitramfs-toolsパッケージにより「update-initramfs」コマンドや「mkinitramfs」コマンドが提供されています。前述のlsinitramfsも同じパッケージに属しています。これらのコマンドは/etc/initramfs-tools以下の設定により,その挙動を変更できます。たとえば圧縮方式,既定のブート方式,起動時にロードすべきモジュールのリスト,その他の設定スクリプトの追加などです。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。

コメント

コメントの記入