Linuxのinitプロセスはシェルスクリプトになることができますか?

Linuxのinitプロセスはシェルスクリプトになることができますか?

私は苦しんでいますカスタムinitramfsを設定するためのチュートリアルそれは次のように言います:

欠けている唯一のものは/ initです。これは、ロードされるとカーネルによって実行される initramfs のルートにある実行可能ファイルです。 sys-apps/busyboxにはフル機能のシェルが含まれているため、これは/ initバイナリを単純なシェルスクリプトで書くことができることを意味します(コンパイルする必要があるアセンブラやCで書かれた複雑なアプリケーションにする代わりに)。

次に始めるシェルスクリプトとしてinitの例を提供します。#!/bin/busybox sh

これまでに私が受けた印象は、initが始まる基本プロセスであり、他のすべてのユーザースペースプロセスは最終的にinitのサブプロセスであるということです。しかし、与えられた例では、最初のプロセスは実際にはbin/busybox/ sh後でinitで作成されます。

これは正しい説明ですか?たとえば、当時通訳を使用できた場合は、Pythonスクリプトなどでinitを作成できますか?

答え1

initは(サブプロセスとして)「生成」されませんが、exec次のようになります。

# Boot the real thing.
exec switch_root /mnt/root /sbin/init

execプロセス全体を交換します。以前はInitramfsのプロセスであったにもかかわらず、最終initはまだ最初のプロセス(pid 1)です。

Initramfsは、pid 1、sをBusybox(現在のpid 1)として/init使用するBusyboxシェルスクリプトです。このプログラムは、マウントポイントを変更することによって新しい 。execswitch_rootswitch_root/mnt/root/

switch_rootこれにより、実際のルートファイルシステムが再びexecアクセスされます/sbin/init。したがって、実際の初期化システムがpid 1の最初のプロセスになり、結果として複数の子プロセスが生成される可能性があります。

もちろん、PythonをInitramfsに書き込むことに成功した場合は、Pythonスクリプトを使用して実行することもできます。とにかくbusyboxを含める予定がない場合は、その機能の一部(switch_root通常は単純なコマンドで実行する他のすべての機能を含む)を再実装する必要があります。

ただし、スクリプトバイナリ()を許可しないカーネルでは機能しませんCONFIG_BINFMT_SCRIPT=y。この場合、インタプリタを直接起動して何らかの方法でスクリプトをロードする必要があります。

答え2

Linuxカーネルのex​​ecシステムコール自体はshebangを理解しています。

実行されたファイルがマジックバイトで始まる場合は、#!カーネルに次のものを使用するように指示します#!/bin/sh

  • doとexecシステムコール
  • 実行可能ファイルがある/bin/sh
  • CLIパラメータを使用します。現在のスクリプトへのパス

これが通常のユーザースペースシェルスクリプトを実行したときに起こるものです。

./myscript.sh

.ELF代わりに、ファイルがマジックバイトで始まる場合、#!カーネルはそれを実行するためにELFローダーを選択します。

詳細については、次を参照してください。人々がPythonスクリプトの最初の行に#!/usr/bin/env python shebangを書くのはなぜですか? |スタックオーバーフロー

/initこれを覚えておくと、カーネルがシェルスクリプトを含む何でも実行できることと、/bin/shこの場合、カーネルが最初の実行可能ファイルになる理由を簡単に受け入れることができます。

試してみたい人のために実行可能な最小の例は次のとおりです。https://github.com/cirosantilli/linux-kernel-module-cheat/tree/cbea7cc02c868711109ae1a261d01fd0473eea0b#custom-init

関連情報