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の準備完了。(まじかよ)
フォルダを準備する。
debianのbusybox-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 /* をやってみた。
今まで、やっちゃあいけないと思ってやってなかったが故になかなか感慨深い。