initrd の最小化

いまのところ、initrdの中には使っていないがソースが提供できないバイナリが含まれている。
これをクリーンナップする必要がある。
必要なコマンドは、sh, mount, echoくらいだ。


Sargeのbusyboxはさすがに古すぎ。入っているコマンドも少ない。
でも、まぁ、これでもいいか。

# busybox --help
BusyBox v0.60.5 (2004.10.30-03:18+0000) multi-call binary

Currently defined functions:
        [, ar, busybox, cat, chgrp, chmod, chown, chroot, clear, cp, cut,
        df, dirname, dmesg, echo, expr, false, find, free, grep, gunzip,
        gzip, halt, head, hostname, id, ifconfig, init, kill, killall,
        klogd, linuxrc, ln, loadkmap, logger, losetup, ls, md5sum, mkdir,
        mknod, mkswap, more, mount, mv, ping, poweroff, ps, pwd, reboot,
        reset, rm, rmdir, route, sed, sleep, sort, swapoff, swapon, sync,
        syslogd, tail, tar, test, touch, tr, true, tty, umount, uname,
        uniq, uptime, wc, wget, which, whoami, zcat

あれ、shがないな。これでは使えない。
ashのないbusyboxなんて妙だな。それに妙に小さいかな?

# ldd /bin/busybox
        libc.so.6 => /lib/libc.so.6 (0x4001d000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

やっぱり、スタティクじゃないのか。
調べてみると、busybox-staticというのが別パッケージになっている。

# busybox --help
BusyBox v0.60.5 (2004.10.30-03:26+0000) multi-call binary

Currently defined functions:
        [, ar, ash, basename, busybox, cat, chgrp, chmod, chown, chroot,
        chvt, clear, cmp, cp, cpio, cut, date, dc, dd, deallocvt, df,
        dirname, dmesg, dos2unix, dpkg, dpkg-deb, du, dumpkmap, dutmp,
        echo, egrep, env, expr, false, fbset, fdflush, find, free, freeramdisk,
        fsck.minix, getopt, grep, gunzip, gzip, halt, head, hostid, hostname,
        id, ifconfig, init, kill, killall, klogd, length, linuxrc, ln,
        loadacm, loadfont, loadkmap, logger, logname, losetup, ls, lsmod,
        makedevs, md5sum, mkdir, mkfifo, mkfs.minix, mknod, mkswap, mktemp,
        modprobe, more, mount, mt, mv, nc, nslookup, pidof, ping, pivot_root,
        poweroff, printf, ps, pwd, rdate, readlink, reboot, renice, reset,
        rm, rmdir, rmmod, route, rpm2cpio, sed, setkeycodes, sh, sleep,
        sort, stty, swapoff, swapon, sync, syslogd, tail, tar, tee, telnet,
        test, tftp, time, top, touch, tr, traceroute, true, tty, umount,
        uname, uniq, unix2dos, update, uptime, usleep, uudecode, uuencode,
        vi, watchdog, wc, wget, which, whoami, xargs, yes, zcat

こちらには、ashがいる。
これを使うことにする。
Etchではbusybox1.1.3なんだけど、amd64i386しかない。なんでだろう。

# ls -al /bin/busybox
-rwxr-xr-x  1 root root 996392 Oct 30  2004 /bin/busybox

サイズは結構でかいな。


バイスファイルの作成などがめんどくさいので、オリジナルのinitrdをスケルトンに使う。
掃除と、linuxrcの一部変更。

# dd if=initrd.OLP01 bs=64 skip=1 of=initrd.gz
# gzip -d initrd.gz
# mount -o loop initrd /mnt/
# cd /mnt/
# rm linuxrc.gt

# cd bin
# rm busybox cat chgrp chmod chown cp date dd df dmesg egrep false fgrep getopt grep gunzip gzip hostname ip ipaddr ipcalc iplink iproute kill ln login ls mkdir mknod mktemp more mv netstat pidof ping ps pwd rm rmdir sed sh sleep stty su sync tar touch true uname usleep vi zcat
# cp /media/rootfs/bin/busybox /mnt/bin/
# ls -l
total 979
lrwxrwxrwx  1 root root      7 Dec 13 11:57 ash -> busybox
-rwxr-xr-x  1 root root 996392 Apr 19 11:45 busybox
lrwxrwxrwx  1 root root      7 Dec 13 11:57 echo -> busybox
lrwxrwxrwx  1 root root      7 Dec 13 11:57 mount -> busybox
lrwxrwxrwx  1 root root      7 Dec 13 11:57 umount -> busybox
# cd ..

/devは多すぎて気持ち悪いけど、このままで。
etc home lib mnt sbin usr の中は空にする。
devを除くとこんな感じ。

    11   12 drwx------   2 root     root        12288 Aug  9  2005 ./lost+found
  4097    1 drwxr-xr-x   2 root     root         1024 Apr 19 11:45 ./bin
  4098  979 -rwxr-xr-x   1 root     root       996392 Apr 19 11:45 ./bin/busybox
  4099    0 lrwxrwxrwx   1 root     root            7 Dec 13 11:57 ./bin/ash -> busybox
  4109    0 lrwxrwxrwx   1 root     root            7 Dec 13 11:57 ./bin/echo -> busybox
  4131    0 lrwxrwxrwx   1 root     root            7 Dec 13 11:57 ./bin/mount -> busybox
  4149    0 lrwxrwxrwx   1 root     root            7 Dec 13 11:57 ./bin/umount -> busybox
  4154    1 drwxr-xr-x   2 root     root         1024 Apr 19 11:50 ./etc
  4174    1 drwxr-xr-x   2 root     root         1024 Apr 19 11:51 ./home
  4181    1 drwxr-xr-x   2 root     root         1024 Apr 19 11:52 ./lib
  1948    1 -rwxr-xr-x   1 root     root          175 Apr 12 11:03 ./linuxrc
  4226    1 drwxr-xr-x   2 root     root         1024 Apr 19 11:52 ./mnt
  4228    1 drwxr-xr-x   2 root     root         1024 Jun 21  2005 ./proc
  4229    1 drwxr-xr-x   2 root     root         1024 Apr 19 11:54 ./sbin
  4272    1 drwxr-xr-x   2 root     root         1024 Nov 15  2005 ./sys
  4273    1 drwxr-xr-x   2 root     root         1024 Jun 21  2005 ./tmp
  4274    1 drwxr-xr-x   2 root     root         1024 Apr 19 11:56 ./usr
  4275    1 drwxr-xr-x   4 root     root         1024 Jun 26  2006 ./var
  2030    1 drwxr-xr-x   2 root     root         1024 Jun  8  2006 ./var/run
  2031    1 drwxr-xr-x   2 root     root         1024 Jun 26  2006 ./var/lock

ほんとに、なにもない。
linuxrcもashにあわせて安全に書き換え。

# vi linuxrc
#!/bin/ash
#
export PATH=/bin
/bin/mount -t proc proc /proc
ROOT_DEVICE=0x0803
/bin/echo "${ROOT_DEVICE}" > /proc/sys/kernel/real-root-dev
/bin/umount /proc
exit 0

busyboxのmount に -nt ってないかも。削ろう。
exportってのも使えたっけ?chrootしてみる。使えそう。
これで加工は終わり。

# df /mnt
Filesystem           1K-blocks      Used Available Use% Mounted on
/media/initrd            15351      1039     13493   8% /mnt

利用エリアはもったいないな。もっと小さくできるんだけど、めんどくさいのでパス。


圧縮してみる。

# cd /media/
# umount /mnt/
# gzip -9 initrd
# mkimage -A arm -T ramdisk -C none -d initrd.gz initrd.OLP01a
Image Name:
Created:      Thu Apr 19 12:13:11 2007
Image Type:   ARM Linux RAMDisk Image (uncompressed)
Data Size:    3346431 Bytes = 3268.00 kB = 3.19 MB
Load Address: 0x00000000
Entry Point:  0x00000000

# ls -al initrd.OLP01*
-rw-r--r--  1 root root 2856096 Apr 19 11:32 initrd.OLP01
-rw-r--r--  1 root root 3346495 Apr 19 12:13 initrd.OLP01a

うわん、でっかくなっちゃった。
やっぱ、クリーンに作らなかったから、中がゼロになっていない分、圧縮が効かなかったか。


しゃぁなし、クリーンで作る。
サイズは、busyboxが1Mくらいだったから、余裕を見ても2Mあればいいかな。inodeは少し多目にしておく。

# gzip -d initrd.gz
# mount -o loop initrd /mnt/
# cd /mnt/
# tar zcvfp /media/initrd.tgz ./*
# cd /media/
# umount /mnt/
# dd if=/dev/zero of=./initrd.null bs=2M count=1
# mkfs.ext2 -N 4096 -F -L OLPLinux0.1 -m 0 initrd.null
# tune2fs -c 0 -l initrd.null

試しに中身空のまま圧縮してみる。

# cp initrd.null initrd.null.orig
# gzip -9 initrd.null
# ls -al initrd.null.*
-rw-r--r--  1 root root    2392 Apr 19 13:41 initrd.null.gz
-rw-r--r--  1 root root 2097152 Apr 19 13:43 initrd.null.orig
# gzip -d initrd.null.gz

いい感じ。
データを書き込む。

# mount -o loop initrd.null /mnt/
# tar zxvfp initrd.tgz -C /mnt/
# umount /mnt/
# gzip -9 initrd.null
# ls -al initrd.null.*
-rw-r--r--  1 root root  515498 Apr 19 13:41 initrd.null.gz
-rw-r--r--  1 root root 2097152 Apr 19 13:43 initrd.null.orig
# mv initrd.null.gz initrd.OLP01a.gz

これで、小さくなった。
ロード時間が減るから、これで起動も少しは早くなるかもね。


ubootで利用できる形式に変換する。

# mkimage -A arm -T ramdisk -C none -d initrd.OLP01a.gz initrd.OLP01a.uboot
Image Name:
Created:      Thu Apr 19 13:53:44 2007
Image Type:   ARM Linux RAMDisk Image (uncompressed)
Data Size:    515498 Bytes = 503.42 kB = 0.49 MB
Load Address: 0x00000000
Entry Point:  0x00000000
# cp initrd.OLP01a.uboot /boot/
# cp /boot/initrd.OLP01a.uboot /boot/initrd

そんでもって、神頼みの再起動。


起動してきた。あーよかった。
これでinitrdまわりの手順は問題なさそうね。
掃除して終わり。
ようやく、すっかりOSSなコードの環境が出来上がった。