続buildrootによるinitramfsのビルド

udevを使うとカーネルパニックが発生する問題を解決

udevを使うとカーネルパニックが発生する現象に遭遇したので
使用するbuildrootのバージョンを上げた.ステーブルなバージョン(2011.11,2011.08)だとうまく行かないので,スナップショットを持ってきてビルドしたところ起動するようになった.

/initの中で発生するエラー

Arch linuxから持ってきた/initがエラーを吐く
まず/runが無いと怒られる.これはディレクトリがないだけなので作る
次に/configがないと言われる.よくわからんのでconfigを使う箇所をコメントアウト
(その後,Arch linuxのinitramfsを解凍して入手したconfigを入れた)
最大の問題が/dev/disk/by-uuidが作成されないこと

UUIDをサポート

make busybox-menuconfigでいろいろ設定を変更
まずuuid関連を全て'y'にする
でもだめ

findfsを追加.
でもだめ

適当にblockdev,acpid,support for old /etc/mtabを追加
でもだめ

blkidを実行してみると何も結果を返さない!これが諸悪の根源だろう

Print filesystem type ,Filesystem/Volume identificationにextとsysvを追加
blkidが結果を返すようになったが,root=/dev/disk/by-uuid/... は使えない.

Filesystem/Volume identificationにlinux swap filesystemを追加
procも追加

依然として/dev/disk/by-uuidは作成されないが,
findfs UUID="disk uuid"とすれば/dev/sda*と表示されるのでfindfsが問題なく動いている

GRUBの記述方法にはroot=/dev/disk/by-uuid/の他にroot=UUID=という指定方法があるので,
そっちも試してみたがだめ.うーん


Archから持ってきた/initに問題があるかも
/init_functionsというスクリプトファイルの中にあるresolve_devices()を見るとUUID=による記述が使えるきがする.
でも現実はそうじゃない.どういうことだ?

resolve_device() {
    local major minor dev device=$1

    case $device in
        # resolve tag name to block device
        UUID=*|LABEL=*)
            dev=$(blkid -lt "$device" -o device)
            [ -n "$device" ] && device=$dev
            ;;
    esac

    case $device in
        /dev/*)
            if poll_device "$device" "$rootdelay"; then
                echo "$device"
                return 0
            fi

            # block device, e.g. (/dev/sda1) -> /sys/class/block/sda1/dev
            if [ -e /sys/class/block/${device:5}/dev ]; then
                IFS=':' read major minor < "/sys/class/block/${device:5}/dev"
            fi
            ;;
        [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]|[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])
            # hex encoded major/minor, such as from LILO
            major=$(( 0x0$device >> 8 ))
            minor=$(( 0x0$device & 0xff ))
            ;;
        0x[0-9a-fA-F][0-9a-fA-F]*)
            major=$(( $device >> 8 ))
            minor=$(( $device & 0xff ))
            ;;
    esac

    if [ -n "$major" -a -n "$minor" ]; then
        device=$(major_minor_to_device "$major" "$minor" || echo '/dev/root')

        if [ ! -b "$device" ]; then
            msg "Creating device node with major $major and minor $minor." >&2
            mknod "$device" b "$major" "$minor"
        fi
        echo "$device"
        return 0
    fi

    return 1
}

blkidを-ltと-oをつけて使用すると結果がおかしい気がする
まず-o deviceによって本来の結果は

/dev/sda1
/dev/sda2
/dev/sda3
/dev/sda4

と表示されるはずなのにオプションを付けなかった時と同じ表示になってしまう.
"-lt"で値が一致するものだけを表示するはずのところが,付けなかった時と同じ表示になる.
つまりblkidのオプションが全く動作していない.なんてことだ.

オプション群はおそらくlibblkで提供されていると思うので,調べてみるが,驚愕の事実が・・・

$ grep libblkid . -R -I
./output/build/busybox-1.19.3/e2fsprogs/old_e2fsprogs/blkid/tag.c: * Tag iteration routines for the public libblkid interface.
./output/build/busybox-1.19.3/e2fsprogs/old_e2fsprogs/blkid/dev.c: * dev iteration routines for the public libblkid interface.
./output/build/busybox-1.19.3/e2fsprogs/old_e2fsprogs/blkid/blkid.h: * blkid.h - Interface for libblkid, a library to identify block devices
./output/build/busybox-1.19.3/e2fsprogs/old_e2fsprogs/blkid/blkidP.h: * blkidP.h - Internal interfaces for libblkid
./output/build/busybox-1.18.5/e2fsprogs/old_e2fsprogs/blkid/tag.c: * Tag iteration routines for the public libblkid interface.
./output/build/busybox-1.18.5/e2fsprogs/old_e2fsprogs/blkid/dev.c: * dev iteration routines for the public libblkid interface.
./output/build/busybox-1.18.5/e2fsprogs/old_e2fsprogs/blkid/blkid.h: * blkid.h - Interface for libblkid, a library to identify block devices
./output/build/busybox-1.18.5/e2fsprogs/old_e2fsprogs/blkid/blkidP.h: * blkidP.h - Internal interfaces for libblkid
./output/build/udev-173/NEWS:repository. Libvolume_id is merged with libblkid from the util-linux-ng
grep: ./output/target/etc/resolv.conf: No such file or directory
grep: ./output/target/etc/mtab: No such file or directory
grep: ./output/target/dev/log: No such file or directory
./package/util-linux/util-linux.mk:     $(if $(BR2_PACKAGE_UTIL_LINUX_LIBBLKID),,--disable-libblkid) \
./package/util-linux/Config.in: bool "build libblkid and blkid utilities"
grep: ./fs/skeleton/etc/resolv.conf: No such file or directory
grep: ./fs/skeleton/etc/mtab: No such file or directory
grep: ./fs/skeleton/dev/log: No such file or directory

なんと--disable-libblkidとなっている.なんでだ?

findfsコマンドをblkidの代りにしてやるか

resolve_device()を書き換え

- dev=$(blkid -lt "$device" -o device) 
+ dev=$(findfs $device)

GRUBのroot=をroot=UUID=ディスクのUUIDと設定したら起動できるようになった.