2012年03月12日
Buildrootで作ったルートファイルシステムをカーネルと別々にロードして動かす(initrd)
前回の「Buildrootで作ったルートファイルシステムをinitramfsでカーネルに組み込む」では、ルートファイルシステムとカーネルが一体化しているので、扱いは簡単ですが、ルートファイルシステムの内容を変更するたびにカーネルを再ビルドしなければなりません。カーネルはもう変更の必要がないのならば、カーネルとルートファイルシステムを別々にしておくほうがよい場合もあります。
initrd
組み込みシステムではブートするデバイスはあらかじめ決まっているため、カーネルのブートパラメータで直接ルートファイルシステムのデバイスを指定して起動することが多いと思います。PCのLinuxシステムでは起動時にデバイスを認識して、条件判断し、必要なデバイスドライバをローダブルモジュールとしてロードするなど、より柔軟な構成になっています。これを実現するために本当のルートファイルシステムをマウントする前にRAM Diskから小さなルートファイルシステムを使用するようになっています。これが、initrd(Initial Ram Disk)です。
initrdのファイルのフォーマットやしくみに関しては歴史的な変遷があり、ネットで検索すると古い情報もでてきますが、最近のkernelではinitrdはcpio形式のアーカイブをgzipで圧縮したものがよく使われています。
initrdをサポートするためのカーネルコンフィグ
General setup ---> [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support () Initramfs source file(s)
前回のものと似ています。カーネルにルートファイルシステムを組み込まないので、Initramfs source file(s)のところは空にしておきます。
Buildrootで作ったファイルシステムをカーネルと別々にロードして動かす
前回、Buildrootで作成した output/images/rootfs.cpio が非圧縮のcpio形式のアーカイブです。
これをKZM-A9-Dualボードにロードして動かしてみます。
PARTNER-Jetがつながっていれば、rdコマンドを使ってファイルをターゲットのメモリ上に簡単に書き込むことができます。
>rd N:\opt\koba\work\buildroot\buildroot-2012.02\output\images\rootfs.cpio,0x40d00000 Read N:\opt\koba\work\buildroot\buildroot-2012.02\output\images\rootfs.cpio 40D00000 - 40FB01FF Complete Read memory : 2.402 sec 2752 Kbyte (1145 Kbyte/sec) >
ロードするアドレスはカーネルと重なっていないRAMのエリアならどこでも大丈夫です。
カーネルのブートパラメータに、initrd=<address>,<size>を追加して、どこにinitrdがあるのかをカーネルに教えます。
initrd=0x40d00000,0x00300000 mem=129M@0x40000000 mem=256M@0x50000000 console=ttyS1,115200n8n
( root=/dev/ram0 は不要でした。)
起動ログ。
... [ 1.490000] TCP cubic registered [ 1.490000] NET: Registered protocol family 17 [ 1.500000] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 1 [ 1.500000] emxx-rtc 0-0051: setting system clock to 2000-01-01 04:35:51 UTC (946701351) [ 1.510000] Freeing init memory: 128K Starting logging: [ 1.570000] usb 1-1: new high speed USB device using emxx-ehci-driver and address 2 [ 1.570000] mmc0: new high speed MMC card at address 0001 [ 1.570000] mmcblk0: mmc0:0001 000000 3.82 GiB [ 1.570000] mmcblk0: p1 p2 p3 OK Starting mdev... Initializing random number generator... done. Starting network... Welcome to Buildroot buildroot login:
圧縮したinitrdをロードする
手動で圧縮して試してみます。
$ cd output/images $ gzip -c rootfs.cpio > rootfs.cpio.gz $ file * rootfs.cpio: ASCII cpio archive (SVR4 with no CRC) rootfs.cpio.gz: gzip compressed data, was "rootfs.cpio", from Unix, last modified: Fri Mar 9 17:48:18 2012
これで、output/images/rootfs.cpioの代わりに、output/images/rootfs.cpio.gz をターゲットのメモリのロードするだけで、後は何も変更する必要はありません。
Buildrootのmenuconfigで圧縮を指定するには
Filesystem images ---> [*] cpio the root filesystem Compression method (gzip) --->
initrdの展開と再作成
gzip圧縮されたcpioアーカイブであるinitrdを手動で展開、および再作成する方法
展開
$ mkdir root; cd root; zcat ../initrd | cpio -i
再作成
以下のようなshellスクリプトを書いておいて
$ cat ./make_initrd cd root; find . | cpio --quiet -o -H newc | gzip -9 -c > ../initrd
fakerootでこれを実行する。
$ fakeroot ./make_initrd