私はカーネル(v4.1-rc5)とbusybox(v1.23.2)で満たされたinitramfsで構成された非常に小さなLinuxシステムを構築しています。ほとんどの場合、うまく動作しますが、組み込みのinitramfsを使用するか外部initramfsを使用するか、/ initのコマンド実行が異なる動作をすることが観察されました。
/initスクリプトは次のとおりです。
#!/bin/sh
dmesg -n 1
mount -t devtmpfs none /dev
mount -t sysfs none /sys
mount -t proc none /proc
echo "Welcome"
while true
do
setsid cttyhack /bin/sh
done
次に、kernel.configのCONFIG_INITRAMFS_SOURCEオプションをinitramfsのすべてのフォルダを含むディレクトリに設定するか、次を実行します。
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz
それを構築します。
その後、カーネルをコンパイルすると、CONFIG_INITRAMFS_SOURCEが設定されているかどうかにかかわらず、システムの2つのバリエーションが生成されます。
initramfsに含まれるbzImage
bzImage + rootfs.cpio.gz(外部 initramfs)
今それを使い始めるとqemu
qemu-system-x86_64 -enable-kvm -kernel bzImage
または
qemu-system-x86_64 -enable-kvm -kernel bzImage -initrd rootfs.cpio.gz
次の行動の違いがあります。
バージョン2(外部initramfs)では、すべてがうまく機能し、「Welcome」と表示され、プロンプトが表示されます。ただし、バージョン1(embedded initramfs)の場合は警告が表示されます。
unable to open an initial console
「ようこそ」は表示されませんが、メッセージが表示されます。
プロセスについて私が理解したように、initramfsの両方のバージョンが同じフォルダにビルドされたので(またはカーネルがビルドするようにしたため)、同じファイルを含める必要があります。
この動作を説明するのに役立つ人がいるかどうか疑問に思います。
*更新*
mikeservがコメントで述べたように、カーネルには基本的に最小限の組み込みinitramfsが含まれています。外部アイテムを使用している場合はまだ存在しますが、自分のアイテムを含めると上書きされます。私は標準とは異なり、これは実際には空ではなく、devフォルダ、ルートフォルダ、および/dev/consoleデバイスが含まれていることを発見しました。その後、このデバイスは外部initramfsを使用するときに使用されますが、直接挿入するとオーバーライドされます。したがって、mknod -m 622 initramfs_src/dev/console c 5 1
自分のデバイスを組み込むときは、initramfsソースに/ dev / consoleデバイスを含める必要があります。
この問題を解決するのに役立つmikeserv、Frostschutz、JdeBPに感謝します!
答え1
本当に同じですか?
/usr/src/linux/usr/initramfs_data.cpio.gz
次のようにbzImageで埋め込み画像を検索または抽出できます。https://wiki.gentoo.org/wiki/Custom_Initramfs#Salvaging
内装を使用して外装として使用すると動作しますか?
それでも違うとカーネル自体は同じですか? (/proc/config.gz
両方を比較してみてください)
少し違いがあるはずです。カーネルがinitramfsのソースにどこで興味を持っているかわかりません。qemu
パラメータを渡すときに別の設定を使用する方が疑わしいです-initrd
...
ところで、/init
私にとっては、無限の殻に卵を産むようです。setsid
いいえexec
。私は間違っていますか?
答え2
Buildroot 2018.02でこの問題を処理する方法に興味があるかもしれません。
BR2_TARGET_ROOTFS_INITRAMFS=y
initramfs( ) または initrd( ) を使用するたびに、rootfs にBR2_TARGET_ROOTFS_CPIO=n
以下が追加されます。/init
https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/init
#!/bin/sh
# devtmpfs does not get automounted for initramfs
/bin/mount -t devtmpfs devtmpfs /dev
exec 0</dev/console
exec 1>/dev/console
exec 2>/dev/console
exec /sbin/init "$@"
コピーは以下によって作成されます。https://github.com/buildroot/buildroot/blob/2018.02/fs/cpio/cpio.mk:
# devtmpfs does not get automounted when initramfs is used.
# Add a pre-init script to mount it before running init
define ROOTFS_CPIO_ADD_INIT
if [ ! -e $(TARGET_DIR)/init ]; then \
$(INSTALL) -m 0755 fs/cpio/init $(TARGET_DIR)/init; \
fi
endef
他の場合とは異なり、initramfsの初期化パスを知ることも/init
便利です。/sbin/init
initのようなプログラムを起動するのではなく、init = / path / to / programがカーネルに渡されるのはなぜですか?