続・玩式草子 ―戯れせんとや生まれけん―

第11回 Plamo-7.1とinitrd[2]

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

ドライバ・モジュールのコピー

次に,findcpioを使って,カーネルのドライバ・モジュールを作業用ディレクトリにコピーします。

170  # Install the kernel modules if requested
171  if [ -n "$KERNEL_VERSION" ]; then
172    find                                                                        \
173       /lib/modules/$KERNEL_VERSION/kernel/{crypto,fs,lib}                      \
174       /lib/modules/$KERNEL_VERSION/kernel/drivers/{block,ata,md,firewire,mmc,mtd}      \
175       /lib/modules/$KERNEL_VERSION/kernel/drivers/{scsi,message,pcmcia,virtio} \
176       /lib/modules/$KERNEL_VERSION/kernel/drivers/usb/{host,storage}           \
177       -type f 2> /dev/null | cpio --make-directories -p --quiet $WDIR
178  

このあたり,ちょっと凝ったコードなので多少わかりにくいですが,172~177行は一連のコマンドになっていて,まず"find"コマンドの引数にinitrdに収めたいドライバ・モジュールのあるディレクトリをbashの拡張機能である「ブレース展開("{...}"⁠⁠」で列挙し,"-type f"でそれらディレクトリにある通常ファイル(=ドライバ・モジュール)の一覧を表示します。

一方,そのファイル一覧をパイプ("|")経由で受けとるcpioコマンドは,"-p"オプションの指定でコピーパスモードで動作し,受けとったファイル名を作業用ディレクトリである$WDIR以下にコピーします。その際,"--make-directories"オプションを指定しているので必要なディレクトリも作成され,/lib/modules/$KERNEL_VERSION/kernel 以下のディレクトリ構成が,そのまま作業用ディレクトリの lib/modules/以下に再現されるわけです。

このあたり,cpioコマンドを使わずに書こうとすると,それぞれのドライバ・モジュールごとにdirnameして収められているディレクトリを調べ,mkdir -pでそのディレクトリを作った上で,basenameで調べたドライバ・モジュール名にコピーする,みたいな作業が必要になるでしょう。

cpioはUNIXの初期に開発されたアーカイブツールで,さまざまな機能が追加された長い歴史を持つ分,オプション指定が複雑で,初心者には敬遠されがちなコマンドです。その分,用途にぴったりとハマったこのような使い方を見せられると,⁠⁠なるほど」と感心してしまいます。

ドライバ・モジュールの依存関係の更新とCPIOアーカイブ化

次に,カーネルに組みこんだドライバのリスト(modules.builtin)やドライバ・モジュールの一覧表(modules.order)をコピーし,depmodコマンドで作業用ディレクトリ内のモジュール・ドライバに限定した依存関係データベースを作成します。

179    cp /lib/modules/$KERNEL_VERSION/modules.{builtin,order}                     \
180              $WDIR/lib/modules/$KERNEL_VERSION
181  
182    depmod -b $WDIR $KERNEL_VERSION
183  fi

以上でカーネルのドライバ・モジュールとそれらの依存関係情報,モジュールを組み込むためのコマンドやライブラリ一式が作業用ディレクトリに揃ったので,それらをCPIO形式にまとめてgzipで圧縮すればinitrdイメージが完成します。最後に,不要になった作業用ファイルとディレクトリを削除します。

185  ( cd $WDIR ; find . | cpio -o -H newc --quiet | gzip -9 ) > $INITRAMFS_FILE
...
188  rm -rf $WDIR $unsorted
189  printf "done.\n"

なお,今回紹介したのはmkinitramfs-0.2のコードで,最近更新したmkinitramfs-0.4では,最後の部分にCPU用のfirmwareを追加する処理を加えており,それらについては次回紹介する予定です。

mkinitramfsの特徴

以上,Plamo-7.1で採用した,LFS/BLFS由来のmkinitramfsについて紹介しました。このmkinitramfsは,インストール済のドライバ・モジュールのうち,ルートファイルシステムのマウントに必要なモジュールは,使う使わないに関わらず全て収めてしまおう,という大胆な設計になっているのが特徴です。

この設計方針は従来のinitrdに慣れている人には奇異に見えるかも知れません。というのも,CentOSやArch Linuxなど主要なディストリビューションが採用しているinitrdでは,インストール済のドライバ・モジュールのうち,その環境で実際にカーネルに組み込まれたモジュールのみをinitrdに組み込む,という設計になっているからです。

前者の設計では,その環境には不要なドライバ・モジュールも大量にinitrdに組み込まれるため,起動時の読み込みに余計な時間がかかります。一方,後者の設計ではinitrdのサイズはコンパクトになるものの,動作中のカーネルに組み込まれたドライバ・モジュールのうち,どのモジュールをinitrdに持ち込むかの判断が必要で,その際はモジュールの依存関係にも考慮を払う必要があります。

また,前者の設計ではカーネル毎(ごと)にinitrdを作り置きできるのに対し,後者ではインストール毎にinitrdを作ることになるため,作成されるinitrdは環境によって異なり,トラブル時の対応が難しくなりそうです。

LFS/BLFSの場合,手作りできるシンプルさが何よりも重視されるので,多少initrdのサイズが大きくなっても構わない今回のような設計になったように思うものの,ディストリビューションとして使うには改善の余地がありそうなので,今後の検討課題と考えています。


今回紹介したLFS/BLFS由来のmkinitramfsは,主流のディストリビューションが採用しているmkinitramfsよりも粗い作りになっているものの,その分汎用性は高く,$binfilesや$sbinfilesに使いたいコマンドを追加し,initスクリプトを調整することで,ルートファイルシステムをマウントする以外の機能,たとえばルータやfirewall専用のinitrdイメージも簡単に作れそうです。このように既存ツールの新しい応用方法を考えていくのも,ソースコードが公開されているOSSならではの魅力でしょう。

著者プロフィール

こじまみつひろ

Plamo Linuxとりまとめ役。もともとは人類学的にハッカー文化を研究しようとしていたものの,いつの間にかミイラ取りがミイラになってOSSの世界にどっぷりと漬かってしまいました。最近は田舎に隠棲して半農半自営な生活をしながらソフトウェアと戯れています。

URLhttp://www.linet.gr.jp/~kojima/Plamo/index.html