initramfsを研究する

qemuでinitramfsを実験する。

まずは実験用カーネルを用意する。

$ make  allnoconfig
$ make menuconfig

General setup  ---> Initial RAM filesystem and RAM disk (initramfs/initrd) support
Executable file formats  ---> Kernel support for ELF binaries

この二つのみをONにして後は全てOFF

$time make bzImage
$cd 作業用ディレクトリ
$ln -s /usr/src/linux/arch/i386/boot/bzImage 作業用ディレクトリ

つぎにダミー用のrawディスクを用意

$qemu-img create dummy_dsk.img 1K

initプログラムを用意

ここではhelloworldをだすか。

$ echo -e '#include <stdio.h>\nint main(){printf("HelloWorld\\n");sleep(999999);}'>a.c;gcc -static -o init a.c;wc -c init;./init
495600 init
HelloWorld
^C
$

initramfsを用意

$ echo init|cpio -o -Hnewc|gzip > helloworld.initramfs
969 blocks

追記:一行で今までの作業をかく

echo -e '#include <stdio.h>\nint main(){printf("helloworld\\n");}'>a.c;gcc -static a.c -o init;echo init|cpio -o -Hnewc|gzip>initrd.gz;rm init a.c

qemuで立ち上げてみる

$qemu -kernel bzImage -initrd helloworld.initramfs dummy_dsk.img

おっと、カーネルにタイマー入れてなかったからエラーが出てるがきちんとhelloworldを出すinitramfsが出来たということで終了。


busyboxでashの入ったinitramfsをつくる

まずはbusybox-staticの取得

#aptitude install busybox-static
# ldd /bin/busybox
        not a dynamic executable

これでbusyboxの準備完了。(まじかよ)

フォルダを準備する。
debianbusybox-staticは--installが入っていないみたいなので力業でリンクを張る。

$ rm -r root
$ mkdir -p root/bin
$ cd root/bin
$ cp /bin/busybox .
$ cp /bin/busybox .; ./busybox --help | ruby -e 'STDIN.read.split(/functions:$/m)[1].split(/,/).each{|i|`ln -s busybox #{i.strip}` unless i=~/busybox/}'
$ cd ..
$ rm init;echo -e '#!/bin/sh\nexec /bin/sh\n' > init ; chmod +x init
$ find . | cpio -o -H newc | gzip > ../busybox.initramfs
2358 blocks

/initを実行可能にするのを忘れないように。(はまった)

以上で完成。ファイルシステムも組み込んでないので何も出来ないけど、取りあえず立ち上がる。

はじめてここでrm -r /* をやってみた。
今まで、やっちゃあいけないと思ってやってなかったが故になかなか感慨深い。