私の質問は、別の/ bootパーティションからLinuxシステムをブートすることに関してです。ほとんどの設定ファイルが別の/パーティションにある場合、カーネルは起動時にどのように正しくマウントしますか?
これについての詳細は素晴らしいでしょう。基本的なものが足りないような気がします。私は主に操作のプロセスと順序に関心があります。
ありがとう!
編集:私が尋ねる必要があるのは、ルートカーネルパラメーターで使用されているdevファイルの行に沿っていたと思います。たとえば、ルートパラメータをroot =/dev/sda2と指定するとします。カーネルはどのように/ dev/sda2ファイルのマッピングを持っていますか?
Linuxは最初にRAMディスク(「INITial RamDisk」の場合はinitrd
と呼ばれます)を_/
_として起動します。このディスクには、実際のルートパーティション(必要なドライバーおよびファイルシステムモジュールを含む)を見つけるのに十分な容量があります。ルートパーティションをinitrd
の一時マウントポイントにマウントし、次にpivot_root(8)
を呼び出してルートマウントポイントと一時マウントポイントを入れ替え、initrd
をumount
edにする位置に残し、_/
_。
古代には、カーネルはルートfsのデバイスメジャー/マイナー番号を知るようにハードコーディングされており、カーネルに組み込まれているすべてのデバイスドライバーを初期化した後、そのデバイスをマウントしていました。 rdev
ユーティリティを使用すると、カーネルイメージのルートデバイス番号を再コンパイルせずに変更できます。
最終的にブートローダーが登場し、コマンドラインをカーネルに渡すことができました。 root=
引数が渡された場合は、組み込み値の代わりにルートfsがどこにあるかをカーネルに伝えました。これにアクセスするために必要なドライバーは、カーネルに組み込まれている必要がありました。引数は/dev
ディレクトリ内の通常のデバイスノードのように見えますが、ルートfsがマウントされる前に/dev
ディレクトリがないことは明らかなので、カーネルはそこでdevノードを検索できません。代わりに、よく知られている特定のデバイス名がカーネルにハードコードされているため、文字列をデバイス番号に変換できます。このため、カーネルは/dev/sda1
のようなものを認識できますが、/dev/mapper/vg0-root
やボリュームUUIDのようなよりエキゾチックなものは認識できません。
その後、initrd
が登場しました。カーネルとともに、ブートローダーはinitrd
イメージをロードします。これは、ある種の圧縮ファイルシステムイメージです(gzipped ext2イメージ、gzipped romfsイメージ、squashfsが最終的に支配的になりました)。カーネルはこのイメージをramdiskに解凍し、ramdiskをルートfsとしてマウントします。このイメージには、実際のinit
ではなく、いくつかの追加のドライバーとブートスクリプトが含まれていました。これらのブートスクリプトは、ハードウェアを認識し、RAIDアレイやLVMなどをアクティブ化し、UUIDを検出し、カーネルコマンドラインを解析して、UUID、ボリュームラベルなどの高度なもので指定できる実際のルートを見つけるために、さまざまなタスクを実行しました。次に、実際のルートfsを/initrd
にマウントし、次にpivot_root
システムコールを実行してカーネルに/
と/initrd
をスワップさせ、次に/sbin/init
を実行します。実ルート。これにより、/initrd
がアンマウントされ、RAMディスクが解放されます。
最後に、今日はinitramfs
です。これはinitrd
に似ていますが、ramdiskにロードされる圧縮ファイルシステムイメージではなく、圧縮されたcpioアーカイブです。 tmpfsがルートとしてマウントされ、アーカイブがそこに抽出されます。ダーティハックと見なされたpivot_root
を使用する代わりに、initramfs
ブートスクリプトは実際のルートを/root
にマウントし、tmpfsルート内のすべてのファイルを削除してからchroot
を/root
に挿入し、/sbin/init
を実行します。
/ etcの構成ファイルにアクセスせずに、カーネルがどのパーティションがルートパーティションであるかを「知る」のかと聞いているようです。
カーネルは、他のプログラムと同様にコマンドライン引数を受け入れることができます。 GRUB、または他のほとんどのブートローダーは、ユーザー入力としてコマンドライン引数を受け入れるか、それらを保存して、メニューからコマンドライン引数のさまざまな組み合わせを利用できるようにします。ブートローダーは、ロード時にカーネルにコマンドライン引数を渡します(この規則の名前や仕組みはわかりませんが、アプリケーションが実行中のカーネルの呼び出しプロセスからコマンドライン引数を受け取る方法と似ています)。
これらのコマンドラインオプションの1つはroot
です。この場合、ルートファイルシステムを指定できます。つまり、root=/dev/sda1
。
カーネルがinitrdを使用する場合、ブートローダーはカーネルにその場所を通知するか、またはinitrdを標準のメモリ位置に配置する責任があります(私はそう思います)-これは、少なくとも私のGuruplugでの動作です。
ルートファイルシステムが見つからないと不平を言った直後に、それを指定せずにカーネルパニックを起こすことは完全に可能です。
このオプションをカーネルに渡す他の方法があるかもしれません。
Grubは/boot
パーティションをマウントしてからカーネルを実行します。 Grubの構成では、ルートデバイスとして何を使用するかをカーネルに指示します。
たとえば、Grubのmenu.lst
の場合:
kernel /boot/linux root=/dev/sda2
C'mon、GRUBは/ bootを「マウント」しません。「menu.lst」といくつかのモジュールを読み取るだけで、LINUXカーネルの一部でもありません。カーネルを呼び出すとき、ルートパーティションに「ルート」引数を渡します。最悪の場合、カーネルは/ bootだけがマウントされたことを認識します(LOL)。
次に:geekosaurが正解です。Linuxは圧縮されたイメージ形式の初期RAMディスクを使用し、pivot_root
を呼び出して実際のルートファイルシステムをマウントします。したがって、Linuxはイメージから実行され、次にローカルディスクドライブから実行されます。
ブートローダー(grubやliloなど)は、root=
フラグを使用して検索する場所をカーネルに指示し、オプションで、カーネルを起動する前にinitrd
を介して初期RAMディスクをメモリにロードします。
次に、カーネルがロードして、ハードウェアとデバイスドライバーをテストし、システムを見て何が見えるかを確認します(dmesg
と入力すると、この診断情報を確認できます。現在では、スクロールが速すぎて見えない可能性があります)。 root=
パラメータで指定されたパーティションをマウントします。
Initrdが存在する場合は、それが最初にマウントされ、ルートファイルシステムがマウントされる前に、その上のモジュール/デバイスドライバーがロードされてプローブされます。このようにして、ハードドライブのドライバーをモジュールとしてコンパイルし、起動することができます。