前回 は、QEMU で Arm の組み込み Linux(Buildroot+BusyBox)で、U-Boot を追加しました。
今回は、initramfsを追加していきます。
それでは、やっていきます。
はじめに
「QEMUを動かす」の記事一覧です。良かったら参考にしてください。
QEMUを動かすの記事一覧
以下は、Buildroot の Documentation のリンクです。
https://buildroot.org/downloads/manual/manual.html
環境は、VirtualBox に入れた Ubuntu 22.04 です。
Buildroot を使います。Buildroot に含まれている U-Boot と、QEMU を使います。
環境は以下の通りです。
ツール |
設定値 |
Buildroot |
qemu_arm_vexpress_defconfig |
U-Boot |
vexpress_ca9x4 |
QEMU |
vexpress-a9 |
今回は、BusyBox で作る initramfs を追加します。
initramfsの調査
initramfs については、kenerl のドキュメントがあります。
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
「What is initramfs?」を和訳してもらいます(from ChatGPT)。
initramfsとは?
すべての2.6 Linuxカーネルには、gzip圧縮された「cpio」形式のアーカイブが含まれています。カーネルが起動すると、このアーカイブはrootfsに展開(ここで言う展開とは、gzip の解凍や cpio の展開のこと)されます。展開後、カーネルはrootfs内に「init」というファイルがあるかを確認し、あればそれをPID 1として実行します。このinitプロセスはシステムを起動し、実際のルートデバイスを見つけてマウントする役割を担います(このマウントされたものが最終的なルートファイルシステム)。もしinitプログラムが見つからなければ、カーネルは従来の方法でルートパーティションを見つけ、/sbin/initの変種を実行します。
initramfsと旧initrdの違い
旧initrdは常に別ファイルであったが、initramfsアーカイブはLinuxカーネルイメージにリンクされている。
旧initrdはgzippedファイルシステムイメージ(例えばext2)であったが、新しいinitramfsアーカイブはgzipped cpioアーカイブである。
旧initrdのプログラムはカーネルに戻ることを期待されていたが、initramfsのinitプログラムはカーネルに戻ることを期待されていない。
別のルートデバイスに切り替える際、initrdはpivot_rootを使用していたが、initramfsはrootfsであるためpivot_rootもアンマウントもできない。代わりにrootfsの内容を削除し、新しいルートで上書きマウントし、新しいinitを実行する。
このプロセスは複雑なため、klibcパッケージはこれを支援するプログラム(utils/run_init.c)を導入しました。多くのパッケージ(例:busybox)はこのコマンドを「switch_root」と名付けています。
initramfs へのデータ投入
2.6 カーネル ビルド プロセスでは、常に gzip 圧縮された cpio 形式の initramfs アーカイブが作成され、結果のカーネル バイナリにリンクされます。デフォルトでは、このアーカイブは空です (x86 では 134 バイトを消費します)。
構成オプション CONFIG_INITRAMFS_SOURCE (menuconfig の General Setup にあり、usr/Kconfig にあります) を使用すると、結果のバイナリに自動的に組み込まれる initramfs アーカイブのソースを指定できます。
このオプションは、既存の gzip 圧縮された cpio アーカイブ、アーカイブするファイルを含むディレクトリ、または次の例のようなテキスト ファイル指定を指定できます。
内容が少し古いですね。
読んだ後に、丁寧な日本語訳があることを知りました。
http://archive.linux.or.jp/JF/JFdocs/kernel-docs-2.6/filesystems/ramfs-rootfs-initramfs.txt.htmlarchive.linux.or.jp
また、以下のサイトで理解が深まります。
gihyo.jp
initramfs の役割は、カーネルに組み込むカーネルモジュールを減らして、それは initramfs に持たせるということでしょうか。
今回に限って言うと、今回使っているカーネルは、単体でルートファイルシステムを展開できているので、これから initramfs を追加しよう思いますが、「無くてもいいもの」ということになります(必要ではないけど理解するために追加してみるという位置づけ)。
さらに、initramfs の実装面を解説しているサイトもありました。
qiita.com
ここを見ると、カーネルは initramfs を含んでいて、ブートローダーに渡された initramfs があれば、そちらを採用(上書きして使う)するということのようです。
追加の initramfs(ブートローダで渡される方)は、様々なデバイス(に存在するルートファイルシステム)に対応する機能追加の役割ということでしょうか。
さらに詳しいサイトがありました。
www.gcd.org
initramfs は、/init が呼ばれるようです。initramfs に BusyBox が使われるのは特別なことではないようです。
また、他に分かったことがあったら、ここに追記しようと思います。
initramfsの構築
今回も参考にさせて頂くサイトです。
leavatail.hatenablog.com
BusyBox で作れるんですね。では、やっていきます。
BusyBox の公式サイトです。
busybox.net
参考サイトでは 1_32_stable を使われていますが、現在は 1_36_stable が最新です。
Deployment の Source Control を見ます。
Git のクローン方法、チェックアウト方法が書かれています。このチェックアウト方法は補完が効かないんですよね、なんででしょうね、ということで、ここでは補完が効く方法でチェックアウトしてます。
$ git clone git://busybox.net/busybox.git
$ cd busybox/
$ git checkout 1_36_stable
Branch '1_36_stable' set up to track remote branch '1_36_stable' from 'origin'.
Switched to a new branch '1_36_stable'
公式サイトには、明確なビルド手順のページが無く、FAQ にビルド方法が書かれています。
「How do I build Busybox with a cross-compiler?」を見ると、ARCH が使われてないのかと思いましたが、ARCH でページ内検索すると、ARCH=arm をしてるところがあったので、必要そうです。
では、デフォルトのコンフィグを適用します。
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- defconfig
続いて、menuconfig でスタティックリンクの設定を行います。
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
static で検索すると、以下のように出ます。デフォルトは static ではないようです。
Symbol: STATIC [=n]
Prompt: Build static binary (no shared libs)
Defined at Config.in:362
Location:
-> Settings
チェック(*
)を付けて Exit すると .config が更新されます。
では、ビルドします。
$ make -j $(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
(省略)
AR util-linux/lib.a
LINK busybox_unstripped
Static linking against glibc, can't use --gc-sections
Trying libraries: m resolv rt
Library m is needed, can't exclude it (yet)
Library resolv is needed, can't exclude it (yet)
Library rt is not needed, excluding it
Library m is needed, can't exclude it (yet)
Library resolv is needed, can't exclude it (yet)
Final link with: m resolv
最後のメッセージを見ると、エラーが出たのかと思いましたが、正常終了のようです。
$ echo $?
0
make install について、公式サイトを見ましたが、明確には書かれないようです。
FAQ の「I am observing a bug in BusyBox on an obscure platform. Help.」の手順に make install が含まれている程度でしょうか。
まぁ、やってみます。
$ make -j $(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install
./_install//bin/arch -> busybox
./_install//bin/ash -> busybox
(省略)
--------------------------------------------------
You will probably need to make your busybox binary
setuid root to ensure all configured applets will
work properly.
--------------------------------------------------
「設定されたすべてのアプレットが適切に動作することを保証するには、busybox バイナリを setuid root にする必要がある可能性があります。」という注意書きがありました。
_install に作られたようですので、見てみます。
$ cd _install/
$ tree
.
|-- bin
| |-- arch -> busybox
| |-- ash -> busybox
| |-- base32 -> busybox
| |-- base64 -> busybox
(省略)
$ tree -d
.
|-- bin
|-- sbin
`-- usr
|-- bin
`-- sbin
5 directories
それらしい感じに出来てます。
init スクリプトを探します。
$ find . -name *init*
./sbin/run-init
./sbin/init
$ ll sbin/init
lrwxrwxrwx 1 daisuke daisuke 14 7月 6 19:05 sbin/init -> ../bin/busybox*
BusyBox に /sbin/init が用意されているようです。
参考サイトでは、_install 直下に init というスクリプトを用意しているようです(つまり、/init となるはず)。
先ほど見た Qiita の参考サイトでは、カーネルは、/sbin/init、/etc/init、/bin/init、/bin/sh の順に init スクリプトを探す、と書かれていたと思います(さらに調べたところ、/init で正しいようです)。
分からなくなったので、動かしながら確認していこうと思います。
とりあえず、init スクリプトは作らず、このまま initramfs を作ります。
$ find . | cpio -o --format=newc > ../rootfs.img
BusyBox のトップに rootfs.img が生成されました。
では、動かしていきます。
これまでのおさらい
Buildroot のトップディレクトリから output/images に移動したディレクトリで実行するとします。
$ cd output/images
$ ls
rootfs.ext2 start-qemu.sh u-boot.bin vexpress-v2p-ca9.dtb zImage
Buildroot+BusyBoxのみ(U-Boot無し)
実際は1行で入力してますが、見にくいので、ここでは改行を入れています。
$ ../host/bin/qemu-system-arm -M vexpress-a9 -smp 1 -m 256 \
-kernel zImage \
-dtb vexpress-v2p-ca9.dtb \
-drive file=rootfs.ext2,if=sd,format=raw \
-append "console=ttyAMA0,115200 rootwait root=/dev/mmcblk0" \
-net nic,model=lan9118 -net user \
-serial stdio
Buildroot+BusyBox+U-Boot
こちらも実際は1行で入力しています。U-Boot の autoboot を何らかのキーを押して止めて、=> の行を入力します。
$ ../host/bin/qemu-system-arm -M vexpress-a9 -smp 1 -m 256 \
-kernel ../build/uboot-2024.01/u-boot \
-device loader,file=zImage,addr=0x62000000 \
-device loader,file=vexpress-v2p-ca9.dtb,addr=0x63000000 \
-drive file=rootfs.ext2,if=sd,format=raw \
-net nic,model=lan9118 -net user \
-serial stdio
=> setenv bootargs console=ttyAMA0,115200 rootwait root=/dev/mmcblk0
=> bootz 0x62000000 - 0x63000000
Buildroot+BusyBoxのみ(U-Boot無し)にinitramfsを追加する
Buildroot のトップディレクトリ/output/images に、initramfs のイメージの rootfs.img をコピーしておきます。
まずは、U-Boot 無しの環境で動かします。
-initrd rootfs.img を追加しただけです。
$ ../host/bin/qemu-system-arm -M vexpress-a9 -smp 1 -m 256 \
-kernel zImage \
-dtb vexpress-v2p-ca9.dtb \
-initrd rootfs.img \
-drive file=rootfs.ext2,if=sd,format=raw \
-append "console=ttyAMA0,115200 rootwait root=/dev/mmcblk0" \
-net nic,model=lan9118 -net user \
-serial stdio
普通に Buildroot が起動してしまいました。起動ログを確認してみます。
initramfs を追加する前と、追加した後の差分は以下です。
+Unpacking initramfs...
hw perfevents: enabled with armv7_cortex_a9 PMU driver, 7 counters available
workingset: timestamp_bits=30 max_order=16 bucket_order=0
squashfs: version 4.0 (2009/01/31) Phillip Lougher
jffs2: version 2.2. (NAND) c 2001-2006 Red Hat, Inc.
9p: Installing v9fs 9p2000 file system support
io scheduler mq-deadline registered
io scheduler kyber registered
OF: graph: no port node found in /bus@40000000/motherboard-bus@40000000/iofpga@7,00000000/i2c@16000/dvi-transmitter@60
sii902x 0-0060: supply iovcc not found, using dummy regulator
sii902x 0-0060: supply cvcc12 not found, using dummy regulator
+Freeing initrd memory: 2132K
initramfs が動いてるようなログは出ています。
参考サイトをよく見ると、-append に root=/dev/mmcblk0 の指定が削除されていました。これが想定した動きと異なる原因のようです。
これを削除して、もう一度やってみます。
$ ../host/bin/qemu-system-arm -M vexpress-a9 -smp 1 -m 256 \
-kernel zImage \
-dtb vexpress-v2p-ca9.dtb \
-initrd rootfs.img \
-drive file=rootfs.ext2,if=sd,format=raw \
-append "console=ttyAMA0,115200 rootwait" \
-net nic,model=lan9118 -net user \
-serial stdio
(省略)
input: ImExPS/2 Generic Explorer Mouse as /devices/platform/bus@40000000/bus@40000000:motherboard-bus@40000000/bus@40000000:motherboard-bus@40000000:iofpga@7,00000000/10007000.kmi/serio1/input/input2
drm-clcd-pl111 10020000.clcd: DVI muxed to daughterboard 1 (core tile) CLCD
drm-clcd-pl111 10020000.clcd: initializing Versatile Express PL111
Waiting for root device ...
起動せず、止まってしまいました。initramfs に /init のスクリプトが無いためのようです。
では、initramfs に最低限の /init を準備して、動作を確認してみます。
BusyBox の _install 直下に init というファイルを作ります。
「Hello, initramfs」と表示して、1秒ごとに日時を表示し続けるだけです。
echo Hello, initramfs
while true
do
sleep 1
date
done
では、先ほどと同じように、rootfs.img として固めます。
$ find . | cpio -o --format=newc > ../rootfs.img
Buildroot の output/images に移動します。コピーは面倒なので、シンボリックリンクを貼っておきます。
$ cd buildroot-2024.02.3/output/images/
$ ln -s ../../../busybox/rootfs.img
$ ../host/bin/qemu-system-arm -M vexpress-a9
-smp 1 -m 256 -kernel zImage -dtb vexpress-v2p-ca9.dtb -initrd rootfs.img -drive file=rootfs.ext2,if=sd,format=raw -append
"console=ttyAMA0,115200 rootwait" -net nic,model=lan9118 -net user -serial stdio
(省略)
Freeing unused kernel image (initmem) memory: 1024K
Run /init as init process
Failed to execute /init (error -13)
Run /sbin/init as init process
can't run '/etc/init.d/rcS': No such file or directory
can't open /dev/tty2: No such file or directory
can't open /dev/tty4: No such file or directory
can't open /dev/tty3: No such file or directory
can't open /dev/tty2: No such file or directory
can't open /dev/tty4: No such file or directory
can't open /dev/tty3: No such file or directory
can't open /dev/tty2: No such file or directory
うまくいきませんでした。「Hello, initramfs」が表示されませんでした。
/init は実行されたようなのですが、うーん、少し調べてみます。
作成した /init スクリプトに実行権限を付けてなかったことが原因でした。
$ chmod +x ./init
$ find . | cpio -o --format=newc > ../rootfs.img
$ cd -
$ ../host/bin/qemu-system-arm -M vexpress-a9 -smp 1 -m 256 -kernel zImage -dtb vexpress-v2p-ca9.dtb -initrd rootfs.img -drive file=rootfs.ext2,if=sd,format=raw -append "console=ttyAMA0,115200 rootwait" -net nic,model=lan9118 -net user -serial stdio
(省略)
Freeing unused kernel image (initmem) memory: 1024K
Run /init as init process
Hello, initramfs
Sun Jul 7 11:00:38 UTC 2024
Sun Jul 7 11:00:39 UTC 2024
Sun Jul 7 11:00:40 UTC 2024
Sun Jul 7 11:00:41 UTC 2024
(省略)
想定した通りに動いています。
次は、カーネルのブートパラメータの rdinit で、initramfs の /init 以外を実行するようにしてみます。
具体的には、-append に「rdinit=/bin/sh」を追加して、/bin/sh(シェル)を起動してみます。
$ ../host/bin/qemu-system-arm -M vexpress-a9 -smp 1 -m 256 \
-kernel zImage \
-dtb vexpress-v2p-ca9.dtb \
-initrd rootfs.img \
-drive file=rootfs.ext2,if=sd,format=raw \
-append "console=ttyAMA0,115200 rootwait rdinit=/bin/sh" \
-net nic,model=lan9118 -net user \
-serial stdio
(省略)
Freeing unused kernel image (initmem) memory: 1024K
Run /bin/sh as init process
/bin/sh: can't access tty; job control turned off
~ # ls
bin dev init linuxrc root sbin usr
# ls /dev/
console
うまくいきました。
次は、Buildroot(ルートファイルシステム)を起動してみます。
参考サイトによると、/dev、/proc、/sys を作り、Buildroot をマウントし、/dev、/proc、/sys を Buildroot に移動し、switch_root を実行しているようです。
最小限から試してみます。本来なら、/dev/mmcblk0 を適当なディレクトリにマウントし、そこに switch_root する必要があるようですが、もしかしたら出来るかな、と思って試します。
initramfs の /init を以下のようにしました。
echo Hello, initramfs
exec switch_root -c /dev/console /dev/mmcblk0 /sbin/init
-append の「rdinit=/bin/sh」は削除します。
$ find . | cpio -o --format=newc > ../rootfs.img
$ cd -
$ ../host/bin/qemu-system-arm -M vexpress-a9 -smp 1 -m 256 \
-kernel zImage \
-dtb vexpress-v2p-ca9.dtb \
-initrd rootfs.img \
-drive file=rootfs.ext2,if=sd,format=raw \
-append "console=ttyAMA0,115200 rootwait" \
-net nic,model=lan9118 -net user \
-serial stdio
(省略)
Freeing unused kernel image (initmem) memory: 1024K
Run /init as init process
Hello, initramfs
switch_root: can't change directory to '/dev/mmcblk0': No such file or directory
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
CPU: 0 PID: 1 Comm: switch_root Not tainted 6.1.44 #1
Hardware name: ARM-Versatile Express
unwind_backtrace from show_stack+0x10/0x14
show_stack from dump_stack_lvl+0x40/0x4c
dump_stack_lvl from panic+0x108/0x318
panic from make_task_dead+0x0/0x17c
---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100 ]---
さすがにダメでした。では、initramfs の /init を以下のように書き換えます。
echo Hello, initramfs
mount /dev/mmcblk0 /mnt/newroot
exec switch_root -c /dev/console /mnt/newroot /sbin/init
BusyBox の _install に /mnt/newroot というディレクトリを作っておきます。
$ mkdir -p mnt/newroot
$ find . | cpio -o --format=newc > ../rootfs.img
$ cd -
$ ../host/bin/qemu-system-arm -M vexpress-a9 -smp 1 -m 256 -kernel zImage -dtb vexpress-v2p-ca9.dtb -initrd rootfs.img -drive file=rootfs.ext2,if=sd,format=raw -append "console=ttyAMA0,115200 rootwait" -net nic,model=lan9118 -net user -serial stdio
(省略)
Freeing unused kernel image (initmem) memory: 1024K
Run /init as init process
Hello, initramfs
mount: mounting /dev/mmcblk0 on /mnt/newroot failed: No such file or directory
BusyBox v1.36.1 (2024-07-06 18:36:47 JST) multi-call binary.
Usage: switch_root [-c CONSOLE_DEV] NEW_ROOT NEW_INIT [ARGS]
Free initramfs and switch to another root fs:
chroot to NEW_ROOT, delete all in /, move NEW_ROOT to /,
execute NEW_INIT. PID must be 1. NEW_ROOT must be a mountpoint.
-c DEV Reopen stdio to DEV after switch
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
CPU: 0 PID: 1 Comm: switch_root Not tainted 6.1.44
Hardware name: ARM-Versatile Express
unwind_backtrace from show_stack+0x10/0x14
show_stack from dump_stack_lvl+0x40/0x4c
dump_stack_lvl from panic+0x108/0x318
panic from make_task_dead+0x0/0x17c
---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100 ]---
ダメでした。やはり、/dev/mmcblk0 が見つからないということでしょうか。
シェルに戻して、手動でやってみます。
$ ../host/bin/qemu-system-arm -M vexpress-a9 -smp 1 -m 256 \
-kernel zImage \
-dtb vexpress-v2p-ca9.dtb \
-initrd rootfs.img \
-drive file=rootfs.ext2,if=sd,format=raw \
-append "console=ttyAMA0,115200 rootwait rdinit=/bin/sh" \
-net nic,model=lan9118 -net user \
-serial stdio
(省略)
Freeing unused kernel image (initmem) memory: 1024K
Run /bin/sh as init process
/bin/sh: can't access tty; job control turned off
~ # ls
bin dev init linuxrc mnt root sbin usr
~ # mount -t devtmpfs devtempfs /dev
~ # ls /dev
console ptype tty34 tty8
cpu_dma_latency ptypf tty35 tty9
full random tty36 ttyAMA0
gpiochip0 rtc0 tty37 ttyAMA1
gpiochip1 snd tty38 ttyAMA2
gpiochip2 tty tty39 ttyAMA3
gpiochip3 tty0 tty4 ttyp0
hwrng tty1 tty40 ttyp1
input tty10 tty41 ttyp2
kmsg tty11 tty42 ttyp3
mem tty12 tty43 ttyp4
mmcblk0 tty13 tty44 ttyp5
mtd0 tty14 tty45 ttyp6
mtd0ro tty15 tty46 ttyp7
mtd1 tty16 tty47 ttyp8
mtd1ro tty17 tty48 ttyp9
mtdblock0 tty18 tty49 ttypa
mtdblock1 tty19 tty5 ttypb
null tty2 tty50 ttypc
ptmx tty20 tty51 ttypd
ptyp0 tty21 tty52 ttype
ptyp1 tty22 tty53 ttypf
ptyp2 tty23 tty54 ubi_ctrl
ptyp3 tty24 tty55 urandom
ptyp4 tty25 tty56 usbmon0
ptyp5 tty26 tty57 vcs
ptyp6 tty27 tty58 vcs1
ptyp7 tty28 tty59 vcsa
ptyp8 tty29 tty6 vcsa1
ptyp9 tty3 tty60 vcsu
ptypa tty30 tty61 vcsu1
ptypb tty31 tty62 zero
ptypc tty32 tty63
ptypd tty33 tty7
~ # mount /dev/mmcblk0 /mnt/newroot
mount: mounting /dev/mmcblk0 on /mnt/newroot failed: No such file or directory
~ # ls /dev/mmcblk0
/dev/mmcblk0
~ # ls /mnt/newroot
~ # mount -t ext4 /dev/mmcblk0 /mnt/newroot
EXT4-fs (mmcblk0): warning: mounting unchecked fs, running e2fsck is recommended
EXT4-fs (mmcblk0): mounted filesystem without journal. Quota mode: disabled.
~ # ls /mnt/newroot/
bin lib lost+found opt run tmp
dev lib32 media proc sbin usr
etc linuxrc mnt root sys var
~ # umount /mnt/newroot/
EXT4-fs (mmcblk0): unmounting filesystem.
~ # ls /mnt/newroot/
~ # mount -t ext2 /dev/mmcblk0 /mnt/newroot
EXT2-fs (mmcblk0): warning: mounting unchecked fs, running e2fsck is recommended
ext2 filesystem being mounted at /mnt/newroot supports timestamps until 2038 (0x7fffffff)
~ # ls /mnt/newroot/
bin lib lost+found opt run tmp
dev lib32 media proc sbin usr
etc linuxrc mnt root sys var
なぜマウントできないのかな、と思ったら、まず、/dev を devtmpfs としてマウントが必要だったようです。
また、ルートファイルシステムのマウントには、-t の指定が必要なようです。
あと、ext2 なのか、ext4 なのかは、これだけでは判断できません。まずは、ext2 でやってみたいと思います。
では、initramfs の /init を書き換えます。
echo Hello, initramfs
mount -t devtmpfs devtempfs /dev
mount -t ext2 /dev/mmcblk0 /mnt/newroot
exec switch_root -c /dev/console /mnt/newroot /sbin/init
では、やってみます。
$ find . | cpio -o --format=newc > ../rootfs.img
$ cd -
$ ../host/bin/qemu-system-arm -M vexpress-a9
-smp 1 -m 256 -kernel zImage -dtb vexpress-v2p-ca9.dtb -initrd rootfs.img -drive file=rootfs.ext2,if=sd,format=raw -append
"console=ttyAMA0,115200 rootwait" -net nic,model=lan9118 -net user -serial stdio
(省略)
Freeing unused kernel image (initmem) memory: 1024K
Run /init as init process
Hello, initramfs
EXT2-fs (mmcblk0): warning: mounting unchecked fs, running e2fsck is recommended
ext2 filesystem being mounted at /mnt/newroot supports timestamps until 2038 (0x7fffffff)
switch_root: can't open '/dev/console': No such file or directory
can't open /dev/null: No such file or directory
can't open /dev/null: No such file or directory
can't open /dev/null: No such file or directory
can't open /dev/null: No such file or directory
can't open /dev/ttyAMA0: No such file or directory
can't open /dev/ttyAMA0: No such file or directory
can't open /dev/ttyAMA0: No such file or directory
can't open /dev/ttyAMA0: No such file or directory
can't open /dev/ttyAMA0: No such file or directory
/dev を新しいルートに移動してないことが原因のようです。
initramfs の /init に追加します。
echo Hello, initramfs
mount -t devtmpfs devtempfs /dev
mount -t ext2 /dev/mmcblk0 /mnt/newroot
mount -n -o move /dev /mnt/newroot/dev
exec switch_root -c /dev/console /mnt/newroot /sbin/init
では、やってみます。
$ find . | cpio -o --format=newc > ../rootfs.img
$ cd -
$ ../host/bin/qemu-system-arm -M vexpress-a9
-smp 1 -m 256 -kernel zImage -dtb vexpress-v2p-ca9.dtb -initrd rootfs.img -drive file=rootfs.ext2,if=sd,format=raw -append
"console=ttyAMA0,115200 rootwait" -net nic,model=lan9118 -net user -serial stdio
(省略)
Freeing unused kernel image (initmem) memory: 1024K
Run /init as init process
Hello, initramfs
EXT2-fs (mmcblk0): warning: mounting unchecked fs, running e2fsck is recommended
ext2 filesystem being mounted at /mnt/newroot supports timestamps until 2038 (0x7fffffff)
(省略)
Welcome to Buildroot
buildroot login: root
./ 25/ 45/ device-tree@ mtd
../ 26/ 46/ devices net@
1/ 27/ 47/ diskstats pagetypeinfo
10/ 28/ 5/ driver/ partitions
11/ 29/ 51/ execdomains self@
117/ 3/ 52/ fb slabinfo
119/ 30/ 6/ filesystems softirqs
12/ 31/ 7/ fs/ stat
124/ 32/ 73/ interrupts swaps
13/ 33/ 77/ iomem sys/
14/ 34/ 8/ ioports sysrq-trigger
15/ 35/ 9/ irq/ sysvipc/
16/ 36/ asound/ kallsyms thread-self@
17/ 37/ buddyinfo kmsg timer_list
18/ 38/ bus/ kpagecount tty/
19/ 39/ cgroups kpageflags uptime
2/ 4/ cmdline loadavg version
20/ 40/ config.gz locks vmallocinfo
21/ 41/ consoles meminfo vmstat
22/ 42/ cpu/ misc zoneinfo
23/ 43/ cpuinfo modules
24/ 44/ crypto mounts@
./ block/ class/ devices/ fs/ module/
../ bus/ dev/ firmware/ kernel/ power/
無事に、Buildroot が起動しました。特にエラーは見当たりません。
initramfs の /init に、/proc と /sys を追加せずにやりましたが、特に問題なさそうです。
initramfs で、/proc と /sys を使う場合は必要ということだと思います。
最小限の構成で失敗しながら追加していくことで、理解が深まりました。
おわりに
今回は、initramfs についての調査と、実際に BusyBox を使って initramfs を作って動作させてみました。
BusyBox のロゴを探してみたところ、段ボール箱の画像のようです。ありがたく使わせて頂きます。
最後になりましたが、エンジニアグループのランキングに参加中です。
気楽にポチッとよろしくお願いいたします🙇
今回は以上です!
最後までお読みいただき、ありがとうございました。