組み込みと外部のinitramfsを使用したinitの実行の違い?


10

私は、カーネル(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

次に、カーネル.configのCONFIG_INITRAMFS_SOURCEオプションをinitramfsのすべてのフォルダーを含むディレクトリに設定するか、

find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz

それを構築します。

次に、CONFIG_INITRAMFS_SOURCEが設定されているかどうかに関係なく、カーネルをコンパイルすると、システムの2つのバリアントが作成されます。

  1. initramfsが埋め込まれたbzImage

  2. 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)では、すべてが正常に機能し、「ようこそ」が表示され、プロンプトが表示されます。ただし、バージョン1では(initramfsが埋め込まれている)警告が表示されます

unable to open an initial console

「ようこそ」が表示されず、プロンプトが表示されます。

プロセスを理解している限り、これらの2つのバージョンのinitramfsには同じファイルが含まれているはずです。これは、同じフォルダーからビルドする(またはカーネルにビルドさせる)ためです。

誰かがこの動作の説明を手伝ってくれるだろうか?

*更新*

mikeservがコメントで言ったように、カーネルにはデフォルトで最小限の組み込みinitramfsが含まれています。これは、外部のものを使用する場合にも存在しますが、独自のものを埋め込むと上書きされます。仕様に反して、これは確かに空ではないことがわかりましたが、devフォルダー、ルートフォルダー、および/ dev / consoleデバイスが含まれています。このデバイスは、外部initramfsを使用するときに使用されますが、独自のデバイスを埋め込むと上書きされます。そのため、mknod -m 622 initramfs_src/dev/console c 5 1独自のものを埋め込む場合は、initramfsソースに/ dev / consoleデバイスを含める必要があります。

mikeserv、frostschutz、JdeBPに頭を悩ませてくれてありがとう。


/dev/console組み込みのものに設定されている権限は何ですか?違いは、どちらのケースでが梱包するかということかもしれません。
mikeserv 2015年

同様の質問は、もちろんstackoverflow.com/questions/10437995です。
JdeBP 2015年

@mikeservコンソールデバイスは、両方のビルドで同じ権限と所有権を持っています。
clw

@JdeBPどちらの場合も起動してプロンプトが表示され、コンソールデバイスがあるため、これが似ているかどうかはわかりません。一方のinitでのみエコーが実行され、もう一方では実行できません。
clw

1
initramfsの権限がまったくない場合でも、権限がどのように同じだったのでしょうか?
mikeserv 2015年

回答:


2

それらは本当に同じですか?

/usr/src/linux/usr/initramfs_data.cpio.gzここで説明されているように、bzImageから見つけるか、bzImageから抽出できる組み込みのもの:https : //wiki.gentoo.org/wiki/Custom_Initramfs#Salvaging

その組み込みのものを使用し、代わりに外部のものとして使用する場合、それは機能しますか?

それでも異なる場合、カーネル自体は同じですか?(/proc/config.gz両方を比較)

多少の違いがあるはずです。カーネルがinitramfsがどこから来たかを気にしていることは知りません。パラメータqemuを渡すときに別の設定を使用するのではないかと思ってい-initrdます...

余談ですが、あなた/initは私に無限のシェルを生み出すように見えます。setsidはありませんexec。私が間違っている?


1
この答えはすべての質問のようです。
JdeBP 2015年

1
@JdeBP:あなたは四次元で考えていません!
frostschutz

1
@frostschutzお返事ありがとうございます!カーネルが構築するinitramfs(usr / initramfs_data.cpio.gz)を外部として使用すると、正常に動作します!また、組み込みのinitramfsでコンパイルされたカーネルを外部のカーネルで提供すると、外部が組み込みを上書きする必要があるにもかかわらず警告が表示されます(kernel.org/doc/Documentation/filesystems/…)。したがって、おそらくqemu -initrdではなく、カーネル自体の中にあるものです。私は..かかわらず、他のその後CONFIG_INITRAMFS_SOURCE何も変わっていない
CLW

@frostschutz答えOn a sidenote, your /init looks like its spawning infinite shells to me. setsid is not exec. Am I wrong?shシェルが終了するまでブロックが呼び出されるため、ループはgettyまたは同様のツールを模倣します。
stefanjunker

@stefanjunker、それは問題ありませんが、setsidがまったくブロックしないことを除いて...
frostschutz

1

Buildroot 2018.02がこれをどのように処理するかに興味があるかもしれません。

initramfs(BR2_TARGET_ROOTFS_INITRAMFS=y)またはinitrd(BR2_TARGET_ROOTFS_CPIO=n)を使用する/initと、rootfsに以下が追加されます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

それ以外の場合/initとは異なり、initパスがinitramfs用であることを知ることも役立ちます。カーネルにinit = / path / to / programを渡して、プログラムをinitとして開始できないのはなぜですか?/sbin/init

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.