1FD Linux

なんとなく、前に作ってた1FD Linuxを見てたので、どんな感じで作ってたのかの覚書です。
今時、1FD Linuxを作ろうなんて人はあんまりいないと思うけど・・・

最後に作ったやつの主要モジュールはこんな感じです。

kernel:2.6.13
busybox:1.01
uclibc:0.9.27

bochsで動かしたスクリーンショット

Linuxのブートプロセスは何かしらのルートファイルシステムのマウントがあって、見つからないとカーネルパニックになりますが、
ディストリビューションだと、最初にinitrdをルートとしてマウントしてから、本当の/を再マウントするので、自分でカーネルビルドしたあとにinitrdを作り忘れてるとカーネルパニックになりますよね。
昔のinitrdは何かしらのファイルシステムイメージをgzipで圧縮したものを使ってたけど、最近は変わってきてます。
そのへんのお話は、こちらの記事が詳しいです。

そして話を1FD Linuxに戻すと、initdは単純にext2ファイルシステムのイメージをgzipで固めてました。
なので、ext2カーネルに組み込んでおく必要があります。ローダブルモジュールだと、initrdがマウント出来なくなってしまうので。

ブートプロセスとしては、カーネルがルートFS(まずはinitrd)をマウントしてから処理がユーザランドに移って行きます。
カーネルのinit/main.cのinit_post()から、こんな風にコマンドを試して、見つかったコマンドに処理が遷移します。

        run_init_process("/sbin/init");
        run_init_process("/etc/init");
        run_init_process("/bin/init");
        run_init_process("/bin/sh");

自分のやつは、busyboxを使っていたので、/sbin/initは実際には/bin/busyboxを指してます。

それと、/etc/inittabはこういう感じになっています。

::sysinit:/linuxrc

tty1::respawn:/sbin/getty 38400 tty1
tty2::respawn:/sbin/getty 38400 tty2
tty3::respawn:/sbin/getty 38400 tty3
tty4::respawn:/sbin/getty 38400 tty4
tty5::respawn:/sbin/getty 38400 tty5
tty6::respawn:/sbin/getty 38400 tty6
tty7::respawn:/sbin/getty 38400 tty7
::ctrlaltdel:/sbin/reboot

参考までに、今使ってるDebian sidのinittabのsysinitの部分はこれです。

# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS

で、sysinitはなにかというと、inittab(5)ではこう書かれています

       sysinit
              システムブート中に実行される。 このエントリーはいかなるboot及びbootwaitエントリーよりも 先に実行される。 runlevels欄は無視される。

そして、/linuxrcで色々と処理します。
色々といっても実際に行ってるのは、これだけです。

1./procのマウント
2./sysのマウント
3.ホスト名の設定
4.カーネルモジュールのインストール
5.キーボードの設定(jp106を使うかどうかだけ)
6.ネットワークの設定
 これくらいしかサポートしてなかったですけど、
  Ethernet Pro 100:eepro100
  RTL-8139/8139C:8139too
  AMD:pcnet32
  PCnet LANCE:pcnet32
  Rhine-III:via-rhine
  Davicom Semiconductor:tulip/dmfe

ブート関連の処理はこれくらいです。

その他、必要なものとしてはlibcが必要なので、uclibcのこの辺りを使っています。
$UCLIBC_VERは0.9.27です。

files="ld-uClibc-$UCLIBC_VER.so \
    ld-uClibc.so.0 \
    libc.so \
    libc.so.0 \
    libcrypt-$UCLIBC_VER.so \
    libcrypt.so \
    libcrypt.so.0 \
    libdl-$UCLIBC_VER.so \
    libdl.so \
    libdl.so.0 \
    libuClibc-$UCLIBC_VER.so \
    libutil-$UCLIBC_VER.so \
    libresolv-$UCLIBC_VER.so \
    libresolv.so \
    libresolv.so.0 \
    libm-$UCLIBC_VER.so \
    libm.so \
    libm.so.0 \
    libcrypt-$UCLIBC_VER.so \
    libcrypt.so \
    libcrypt.so.0 \
    libnsl-$UCLIBC_VER.so \
    libnsl.so \
    libnsl.so.0"

/etc以下はこれだけです。

files="fstab \
    group \
    hostname \
    mtab \
    passwd \
    shadow \
    inittab \
    keymap.gz \
    modprobe.conf \
    hosts \
    pcidb \
    nsswitch.conf"

pcidbはネットワークの設定用に別途作ったファイルなので、標準的なファイルではありません。

ネットワーク設定で、DHCPを使う場合用にudhcpcを使ってます。

というわけで、大体これだけあれば動くものにはなります。