GRUBは、次の行を実行することを考慮してください。
kernel /vmlinuz root=/dev/sda1 ro
initrd /initrd
起動時に、Linuxカーネルはどのようにして/dev/sda1
デバイスノードを検出しますか?
Initrd/initramfsイメージには、ストレージ(など)デバイス用のモジュールが含まれていることを知っています。これらのモジュールは、ストレージへのアクセスを可能にするためにメモリにロードされます。私を悩ませているのは、カーネルパラメータroot=/dev/sda1
がカーネルによってどのように正確に解析されるかです。
Initrd/initramfsの/init
(または/linuxrc
)スクリプトは/dev
ディレクトリを作成し、次にデバイスノード/dev/sda1
を作成しますか?または、/dev/sda1
の「メジャー」番号と「マイナー」番号がカーネルにハードコードされていますか?
Initramfsがある場合、カーネルはinitramfsを解凍してマウントし、その後/init
を実行します。それ以外はすべて/init
実行可能ファイルによって処理されます。これは、カーネルがroot
ブートパラメータで指定されたデバイスをマウントしないことも意味します。
異なるディストリビューションは、たとえば次のような異なるinitramfsフレームワークを使用します。 dracut Fedoraの場合、または initramfs-tools Debianの場合。最も一般的な解決策は、udev
、mdev
、またはdevtmpfs
のようなものを使用することです。 MAKEDEV
を使用して静的レイアウトを生成したり、デバイスファイルをすでにイメージに統合している場合もあります。
Initramfsなしで起動する場合、カーネルは既知のメジャー/マイナー番号を持つデバイスから起動できます。 /dev/sda1
ですが、lvmデバイスからではありません。
最初のコードは、mdev
と呼ばれるプログラムを実行します。これは基本的にudev
の縮小版です。これにより、すべてのデバイスがスキャンされ、/dev
フォルダーの初期コンテンツが作成されます。その後、カーネルはmount /dev/sda1 /
を効果的に実行し、システム全体の検索を開始できます。
ここ を参照してくださいmdev
についてもっと知りたいですか。
メジャーデバイス番号とマイナーデバイス番号は、実際には、デバイスドライバーであり、静的メジャー番号を使用するカーネルモジュールにハードコードされています(たとえば、カーネルソースの Documentation/devices.txt を参照)。ほとんどの(すべて?)ディスクドライバカーネルモジュールは、このカテゴリに分類されます。したがって、@ Ulrich Dangelが言うように、必要なモジュールがカーネルイメージに静的にリンクされている限り、一部のカーネルはinitramfs/initrdなしで起動できます。
ルートデバイスのメジャーとマイナーの番号はカーネルイメージに保存されます(詳細については、rdev
のマンページを参照してください)。
ただし、カーネルのコマンドライン引数はカーネルによって解釈されません。最初のramdisk、initrdには、通常は解釈部分を実行する最小限のLinuxを備えたファイルシステムが含まれています。 initrdがどのように機能するかは、ディストリビューションによって異なります。単にノード/ dev/sda1または実行時にそれを作成するスクリプト/プログラムが含まれている場合があります。
DebianベースのLinuxを使用している場合は、次のようにRAMディスクを解凍できます。
_mkdir /tmp/initrd
cd /tmp/initrd
zcat /boot/path/to/initrd | cpio -iv
_
Debianのinitrdはスクリプトであり、それがどのように機能するかを見ることができます。カーネルがinitrdを解凍した後、スクリプトinit
を起動します。これは、_/tmp/initrd
_にあります。 for x in $(cat /proc/cmdline); do
と書かれているブロックに注意してください。
_/proc/cmdline
_には、Grubを使用して渡された引数があります(シェルで今すぐ確認/確認できます!)。 Debian initrdをもう少し深く掘り下げたい場合は、Grubでオプション_root=/dev/nfs
_を渡すことにより、カーネル/ initrdにルートファイルシステムとしてNFS共有を使用させることができることに気付くでしょう。これを行うと、ノード_/dev/nfs
_は作成またはマウントされません。 initrdに何をすべきかを指示するだけです。
最終的に、そのようなすべてのinitrdは、_init=
_またはデフォルトの_/sbin/init
_などのオプションによって提供されるコマンドを実行します。
見出しの最初の質問に戻ります。はい/ init(ほとんどの場合)は実行時にそのノードを作成します。あらゆる種類のプログラム/ヒューリスティック/ブードゥーを使用して、ルートファイルシステムをマウントする方法を理解します。