web-dev-qa-db-ja.com

カーネルはどのようにルートパーティションをマウントしますか?

私の質問は、別の/ bootパーティションからLinuxシステムをブートすることに関してです。ほとんどの設定ファイルが別の/パーティションにある場合、カーネルは起動時にどのように正しくマウントしますか?

これについての詳細は素晴らしいでしょう。基本的なものが足りないような気がします。私は主に操作のプロセスと順序に関心があります。

ありがとう!

編集:私が尋ねる必要があるのは、ルートカーネルパラメーターで使用されているdevファイルの行に沿っていたと思います。たとえば、ルートパラメータをroot =/dev/sda2と指定するとします。カーネルはどのように/ dev/sda2ファイルのマッピングを持っていますか?

30
Mr. Shickadance

Linuxは最初にRAMディスク(「INITial RamDisk」の場合はinitrdと呼ばれます)を_/_として起動します。このディスクには、実際のルートパーティション(必要なドライバーおよびファイルシステムモジュールを含む)を見つけるのに十分な容量があります。ルートパーティションをinitrdの一時マウントポイントにマウントし、次にpivot_root(8)を呼び出してルートマウントポイントと一時マウントポイントを入れ替え、initrdumountedにする位置に残し、_/_。

20
geekosaur

古代には、カーネルはルート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を実行します。

43
psusi

/ etcの構成ファイルにアクセスせずに、カーネルがどのパーティションがルートパーティションであるかを「知る」のかと聞いているようです。

カーネルは、他のプログラムと同様にコマンドライン引数を受け入れることができます。 GRUB、または他のほとんどのブートローダーは、ユーザー入力としてコマンドライン引数を受け入れるか、それらを保存して、メニューからコマンドライン引数のさまざまな組み合わせを利用できるようにします。ブートローダーは、ロード時にカーネルにコマンドライン引数を渡します(この規則の名前や仕組みはわかりませんが、アプリケーションが実行中のカーネルの呼び出しプロセスからコマンドライン引数を受け取る方法と似ています)。

これらのコマンドラインオプションの1つはrootです。この場合、ルートファイルシステムを指定できます。つまり、root=/dev/sda1

カーネルがinitrdを使用する場合、ブートローダーはカーネルにその場所を通知するか、またはinitrdを標準のメモリ位置に配置する責任があります(私はそう思います)-これは、少なくとも私のGuruplugでの動作です。

ルートファイルシステムが見つからないと不平を言った直後に、それを指定せずにカーネルパニックを起こすことは完全に可能です。

このオプションをカーネルに渡す他の方法があるかもしれません。

3
LawrenceC

Grubは/bootパーティションをマウントしてからカーネルを実行します。 Grubの構成では、ルートデバイスとして何を使用するかをカーネルに指示します。

たとえば、Grubのmenu.lstの場合:

kernel /boot/linux root=/dev/sda2
1
jonescb

C'mon、GRUBは/ bootを「マウント」しません。「menu.lst」といくつかのモジュールを読み取るだけで、LINUXカーネルの一部でもありません。カーネルを呼び出すとき、ルートパーティションに「ルート」引数を渡します。最悪の場合、カーネルは/ bootだけがマウントされたことを認識します(LOL)。

次に:geekosaurが正解です。Linuxは圧縮されたイメージ形式の初期RAMディスクを使用し、pivot_rootを呼び出して実際のルートファイルシステムをマウントします。したがって、Linuxはイメージから実行され、次にローカルディスクドライブから実行されます。

1
D4RIO

ブートローダー(grubやliloなど)は、root=フラグを使用して検索する場所をカーネルに指示し、オプションで、カーネルを起動する前にinitrdを介して初期RAMディスクをメモリにロードします。

次に、カーネルがロードして、ハードウェアとデバイスドライバーをテストし、システムを見て何が見えるかを確認します(dmesgと入力すると、この診断情報を確認できます。現在では、スクロールが速すぎて見えない可能性があります)。 root=パラメータで指定されたパーティションをマウントします。

Initrdが存在する場合は、それが最初にマウントされ、ルートファイルシステムがマウントされる前に、その上のモジュール/デバイスドライバーがロードされてプローブされます。このようにして、ハードドライブのドライバーをモジュールとしてコンパイルし、起動することができます。

1
Shadur