私はLinuxカーネルが起動時に必要なrootfsの場所をどのように知っているかを理解しようとしています。
私はこの記事を読んだ。
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
興味のある内容は次のとおりです。
すべての2.6 Linuxカーネルには、カーネルの起動時にrootfsで抽出されるgzipで圧縮された「cpio」形式のアーカイブが含まれています。組み込みのcpioアーカイブが抽出された後、rootfsにinitプログラムが含まれていないと、カーネルは失敗します。古いコードルートパーティションを見つけてマウントするには
私たちのカーネルは4.Xですが、これはまだ適用されていると思いますか?すべてのカーネルに「cpio」rootfsが組み込まれているようです。
実際に私たちが読んだように:
2.6カーネルビルドプロセスは、常にgzipで圧縮されたcpio形式のinitramfsアーカイブを作成し、生成されたカーネルバイナリにリンクします。デフォルトでは、このアーカイブは空です...設定オプションCONFIG_INITRAMFS_SOURCE...を使用してinitramfsアーカイブのソースを指定できます。
これにより、いくつかの質問がさらに提起されます。
CONFIG_INITRAMFS_SOURCE
したがって、私のrootfsをRAMに入れるには、私のrootfs(おそらくcpio形式)を指すように設定する必要があります。
しかし、これは私のカーネルとrootfsがもう分離できないという意味ですか?再構築せずにRootFSを少し調整するにはどうすればよいですか? rootfsをカーネルとは別に保存するにはどうすればよいですか?私のrootfsの場所をカーネルにどのように伝えますか?
- また、私のrootfsをRAMの代わりに物理ストレージ(例えばeMMC、フラッシュドライブなど)に置くにはどうすればよいですか?
前述の内容は次のとおりです。
組み込みのcpioアーカイブをrootfsに抽出した後、rootfsにinitプログラムがない場合、カーネルは以前のコードを使用してルートパーティションを見つけてマウントします。
しかし…どうですか? rootfsがどこにあるのか、どうすればわかりますか? eMMCにいる場合は、どういうわけかカーネルに教えてください。
私が使用するブートローダはU-bootです。 U-boot環境変数を調べて、どういうわけかrootfsの場所をカーネルにブート引数として渡していることを確認しましたが、そうではありません...
編集する:
コメントで指摘したように、rootfsの位置はboot argを介してカーネルに渡されます。私の場合、u-bootはroot=/dev/mmcblk0p4 rw
ブート引数としてカーネルに渡されます。これは私の質問の1つに対する答えです。解凍された rootfs にブート引数として位置を渡すことができます。
rootfs.tar.gz
カーネルとは別のものを考えると、カーネルにそれをRAMに解凍し、rootfsとして使用するように指示する方法はまだ明確ではありません。たぶんこれは不可能かもしれませんが、単に使用する必要がありますかCONFIG_INITRAMFS_SOURCE
?とにかく4.Xのドキュメントを読んでみましょう。
ベストアンサー1
まず、カーネル文書の「2.6」参照に恐れないでください。現在、カーネルはまだ「2.6」シリーズのメンバーですが、「マーケティング目的」のために2回にわたって番号を付け直しました(したがって、2.6.40は3.0になり、3.20は4.0になりました)。 4.19カーネルには通常2.6.79というラベルが付いています。
ここで「rootfs」の意味について若干の混乱があるようです。 「rootfs」は、カーネルで内部的に使用される特別なRAMベースのファイルシステムです。これは通常、にマウントされている「tmpfs」ファイルシステムとまったく同じです/run
。 (まあ、「tmpfs」機能がカーネルにコンパイルされていない限り、この場合は「ramfs」と呼ばれる単純な「tmpfs」が使用されます。)これらのファイルシステムはページキャッシュにのみ存在し、デバイスramfsをサポートしません。 tmpfsはスワップ(利用可能な場合)としてサポートされています。/dev/shm
/tmp
したがって、カーネルは「rootfs」を「見つける」ことを心配する必要はありませんが、起動時にページ全体のキャッシュが空であるため、何らかの方法でそれを埋める必要があります。これが「initramfsファイル」が動作する場所です。これはカーネルによって空の「rootfs」に解凍されたcpio
(tar
文書に記載されている理由のためではなく)(圧縮された)アーカイブだけです。このアーカイブは、CONFIG_INITRAMFS_SOURCE
ビルド中の設定を介してカーネルイメージに直接含めることも、ブートローダで提供することもできます(initrd
GRUBのオプションが実行するアクション)。アーカイブは通常、dracut
(混乱しても)などのユーザースペースツールを使用して作成されますmkinitrd
。
cpioイメージが利用できない場合、または実行可能ファイルが含まれていない場合、/init
カーネルはコマンドライン引数を見て、root=
それを実際のルートファイルシステムの場所として解釈し、マウントして/
直接実行する別の方法に置き換えますinit
。しかし、このアプローチは、必要なすべてのリポジトリとファイルシステムドライバをカーネルに直接コンパイルする必要があるため、今日ではほとんど使用されていません。ほとんどのシステムでは、このroot=
パラメータはカーネルでは使用されず、/init
initramfsで処理されます。これは/init
(通常はsystemd
シェルスクリプト)必須モジュールのロード、実際のルートファイルシステムのマウント、および移行を担当します。
長い間、「initrd」という別のメカニズムが現代の「initramfs」を置き換えるために使用されていました。 「initrd」(「init ramdisk」)は、実際のファイルシステム(ext2など)で初期化され、そのイメージが最新のアーカイブのように提供されるRAMベースのブロックデバイスですcpio
。これが、多くの場所でこれらの初期起動項目を指すためにまだ「initrd」という名前を使用する理由です。