カーネル+initrd

実はinitrdはカーネルと合体させてひとつのbzImageにすることができる。
カーネルコンフィグのINITRAMFS_SOURCEに.cpioファイルのパスか開発環境で用意したルートファイルシステムのトップディレクトリを指定すれば良いらしい。(細かいことはDocumentation/early-userspace/READMEに書いてある)
ただ、試してみたらcpioを作る環境がなかったのかcpioファイルの生成でコケてしまった。よくわからないが面倒なのでとりあえず自前でcpioファイルを作って試してみた。

するとここでさらに問題が発生した。
カーネルを起動してみると「no cpio magic」とか吐いて死んでしまった。
「!?」とか思いつつカーネルソースをgrepしてみるとinit/initramfs.cのdo_header()関数が吐いているようだ。
どうやら本当にcpioのマジックナンバー"070701"が実際のファイルに入っていないというエラーのようだ。確かに手元のcpioファイルをodコマンドでダンプすると先頭はまったく070701と似つかない。でもfileコマンドでは確かにcpioだと判断している。

不思議に思ったので開発環境で/usr/share/file/magicを除いてみてびっくり。
なんとcpioファイルは5種類もあるようだ!どうやら自分が作っていたのはcpioの「バイナリフォーマット」版らしい。070701のマジックナンバーは「(SVR4) portable」フォーマットでcpioの引数に「--format=newc」が必要らしい。
よく見直すと、さっきのREADMEの上のほうに「The cpio file format used by initramfs is the "newc" (aka "cpio -c")format」とか書いてある。。。
いや、説明資料をそこまで細かく読まないって。。。

気を取り直して再チャレンジしたら、今度は外付けUSBのmountでコケてしまう。何でだろう。ルートファイルシステムにはnashをメインにすえたものを採用したから、mountはnashのスクリプトを/initとしておいておけばスクリプトからmountできるはずなんだけど。う〜ん。