init は (子プロセスとして) 「生成」されませんが、むしろ exec
です。 これが欲しい:
# Boot the real thing.
exec switch_root /mnt/root /sbin/init
exec
プロセス全体を置き換えます。最後の init は、最初のプロセス (pid 1) ですが、Initramfs のプロセスが先行していました。
Initramfs /init
これは、pid 1、exec
の Busybox シェル スクリプトです。 Busybox switch_root
への s (だから今 switch_root
pid 1);このプログラムはマウントポイントを /mnt/root
に変更します 新しい /
になります .
switch_root
そしてまた exec
s から /sbin/init
あなたの本当のルートファイルシステムの;これにより、実際の init システムが pid 1 の最初のプロセスになり、任意の数の子プロセスが生成される可能性があります。
確かに、どうにかして Python を Initramfs に組み込むことができれば、Python スクリプトを使用しても同様に実行できます。とにかくbusyboxを含める予定がない場合は、その機能の一部を苦労して再実装する必要があります( switch_root
など) 、および通常は単純なコマンドで行うすべてのこと)。
ただし、スクリプト バイナリ (CONFIG_BINFMT_SCRIPT=y
) を許可しないカーネルでは機能しません。 )、またはそのような場合は、インタプリタを直接起動して、何らかの方法でスクリプトをロードする必要があります.
Linux カーネルの exec syscall はシバンをネイティブに理解します
実行ファイルがマジックバイト #!
で始まる場合 、カーネルに #!/bin/sh
を使用するように指示します として:
- do と
exec
システムコール - 実行可能
/bin/sh
付き - CLI 引数付き:現在のスクリプトへのパス
これは、通常のユーザーランド シェル スクリプトを実行した場合とまったく同じです:
./myscript.sh
ファイルがマジック バイト .ELF
で始まっていた場合 #!
の代わりに 、カーネルは代わりに ELF ローダーを選択して実行します。
詳細:なぜ人々は Python スクリプトの最初の行に #!/usr/bin/env python シバンを書くのですか? | |スタック オーバーフロー
このことを頭に入れておけば、/init
を受け入れるのは簡単です。 シェルスクリプトを含め、カーネルが実行できるものなら何でもかまいません。また、なぜ /bin/sh
なのか その場合、最初の実行可能ファイルになります。
試してみたい人のための最小限の実行可能な例を次に示します:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/cbea7cc02c868711109ae1a261d01fd0473eea0b#custom-init