なぜinitramfsが必要なのですか?


16

ファイルシステムとして(initramfsではなく)jffsまたはsdを選択すると、カーネルサイズが非常に小さい(initramfs-3.4MBと比較して1.4 MB)ことがわかりました。initramfsがかなり大きなスペースを取ることを示しています。だから私はそれを完全に削除することができます、私は非常に小さなカーネルを持っているでしょう、それは私が欲しいものです。

だから私の頭に浮かぶ基本的な質問は:なぜinitramfsが必要なのか?Linuxカーネルは、初期ファイルシステムがなくても起動しないのですか?

私の最終アプリケーションは、計算とコミュニケーションのみを行います。したがって、ファイルシステムのないOSは理にかなっています-少なくとも私のアプリケーションにとっては。


2
initramfsなしではできません。追加のinitramfsファイルがなくても実行できますが、何をするかに関係なく、カーネルには独自の空または空のファイルが含まれます。だから私はあなたの質問を理解していません-あなたはどのディストリビューションについて話しているのですか カーネルをどのように構築していますか?カーネルの.configファイルを提供できますか?これらは非常に重要です。あなたのディストリビューションはinitramfsをカーネルに直接コンパイルしているので、それ以外の場合は空のinitramfsを埋めているのではないかと思いますが、あなたが提供した情報に基づいて知ることはできません。
mikeserv 14年

2
@mikeserv、明らかに組み込まれているが空の/未使用のinitramfsはカウントされません。
psusi

さて、カーネルドキュメントの@psusiは同意しません。そして、私はそれについてとても頑固です。なぜなら、ミステリーを必要としないからです-ただ/root- それだけです。唯一異なるのはswitch_root、ロードされた特定のカーネルモジュールで適切な予防措置が取られていれば、いつでも実行できることです。Initramfsはディスクイメージにすぎません-あふれているかどうか、そこにあります。そして、あなたはそれなしではありません-それは結局あなたのルートです。それは単にミステリーであってはならない、私が思うことであり、私はそれを取り巻く不必要な混乱のすべてを嫌います。
mikeserv 14年

2
@mikeserv、いいえ、/ rootはルートユーザーのホームディレクトリです。rootfsは/で、その上に実際のルートがマウントされます。あなたはセマンティクスを主張しているだけです。この説明の目的上、initramfsがないということは、ブートローダーがカーネルにロードして渡す必要があるディスクにファイルがないことを意味します。
psusi

それは本当です、私は明確にするために/ rootを使用しましたが、私はあなたにそれを与えます。しかし、いや、セマンティクスではなく、Linuxカーネルの基本的な仕組みです。これらは基本的なものです。それらを正しくしようとします。
mikeserv 14年

回答:


10

initramfsのサイズの増加は、ramfsドライバー(数kBのみであり、とにかく他のものに必要)によるものではなく、initramfs自体によるものです。initramfsには、実際のルートファイルシステムをアセンブルおよびマウントするために必要なプログラムが含まれています。

Initramfsを使用すると/、システムの起動が非常に簡単になり、場合によっては(暗号化など)可能になります。多くのホットプラグ可能な周辺機器を備えたPCスタイルのハードウェアに保管することを強くお勧めします。一方、initramfsを使用せずに組み込みデバイスをブートすることは、ビルド対象の特定のハードウェア構成のみをサポートするカーネルを使用するのが理にかなっています。

もちろん、カーネルはファイルシステムから起動する必要があります。実行したいアプリケーションをロードするための何らかの方法が必要です。何も実行しない場合は、マシンの電源をオフのままにしておくこともできます。

initramfsを使用したくない場合は、ブートローダーにパスしないように伝えてください。例えば、すべてのアーキテクチャー別およびブートローダに依存している場合、この問題が発生したか-もちろんのカーネル構築の出力では、1つが含まれていないvmlinuxbzImage(彼らはそれぞれの生と圧縮されたカーネルだinitramfsが含まれていません)、ただしuImage(U-Bootの場合)カーネルとinitramfsがあればそれを両方パックします。

(技術的には、mikeservが指摘しているように、常にinitramfsがありますが、デフォルトでは、空の134バイトのアーカイブです。ビルドプロセスと、ルートファイルシステムのマウントに使用されるツールを含む)

心に留めておいてください。initramfsは、永続的なデータを持たない単一アプリケーションシステムを作成する合理的な方法です。すべてのアプリケーションをinitramfsに入れ、それを起動して保持します。これにより、永続ストレージまたはブートイメージを整理しやすくなります(必要なのは、バンドルできるカーネルとinitramfsだけです)。ただし、このアプローチには欠点があります。initramfsのすべてのデータは永久にRAMに保存され、ブートイメージのファイルを簡単に変更することはできません。アーカイブを再構築する必要があります。


2.6以降のLinuxカーネルを使用している場合は、initramfsがあります。通常のように、セカンダリinitramfsイメージを使用するかどうかは別の問題ですが、initramfsはオプションではありません。
mikeserv 14年

2
@mikeserv 1つあります、はい。しかし、空のinitramfsはピーナッツです。使用する必要はありません(実際のルートをマウントするのに十分なプログラムが含まれている必要があり、典型的な組み込みシステムでは無視できないほどサイズが大きくなります)。
ジル 'SO-悪であるのをやめる'

とにかく強制的なピーナッツ。そして、私がそうでないと言ったとき、私は知らない!質問者は、ファイルシステムとしてそれを削除する方法に関する情報を要求していました-これは不可能です。
mikeserv 14年

そして、はい、使用する必要があります-initramfsなしではルートはありません。今まで。
mikeserv 14年

8

LFSから:

initramfsの唯一の目的は、ルートファイルシステムをマウントすることです。initramfsは、通常のルートファイルシステムにあるディレクトリの完全なセットです。単一のcpioアーカイブにバンドルされ、いくつかの圧縮アルゴリズムのいずれかで圧縮されます。

...

LFS環境でinitramfsを使用する主な理由は、ネットワークからrootfsを読み込む、LVM論理ボリュームから読み込む、パスワードが必要な暗号化されたrootfsを持つ、またはrootfsをLABELまたはUUID。それ以外は通常、カーネルが適切に構成されなかったことを意味します。

...

ほとんどのディストリビューションでは、カーネルモジュールがinitramfsを持つ最大の理由です。一般的な配布では、ファイルシステムの種類やディスクレイアウトなど、多くの未知の要素があります。ある意味では、これはシステムの機能とレイアウトが既知であり、通常はカスタムカーネルが構築されるLFSの反対です。この状況では、initramfsはほとんど必要ありません。

別のソースwww.kernel.org

このほかに、initramfsを使用しないルーターが好きなLinuxシステムがたくさんあります。


1

ネットワークブート、lvmまたはraidなど、より複雑なセットアップにはinitramfsが必要です。ルートfsへのアクセスを設定するには、いくつかのユーザーモードユーティリティが必要になるためです。ディスク上の単純な従来のパーティションの場合、カーネルにディスクドライバーを組み込み、UUIDではなくデバイスパスでルート引数を指定する限り、initramfsなしで実行できます。もちろん、接続したプラグアンドプレイ(つまりusb)デバイス、または単にランダムなタイミングの違いによって、デバイスパスは変更される場合があります。そのため、ほとんどの人が信頼性のためにuuidとinitramfsを使用しています。


これも間違っています。
mikeserv 14年

6
@mikeserv、あなたのコメントは役に立たない。あなたがそれを主張するつもりなら、あなたはその理由を説明する必要があります。
psusi

私の答えの99%を構成するカーネルのドキュメントを作成しました。
mikeserv 14年

@mikeserv、それは正しいです。私は何年もGenito Linuxをinitramfsなしで実行しています。
ティム

1

これは古い質問ですが、まだ受け入れられているようには見えないので、そこに投げます(私はここでは専門家ではありません、自分でこれを理解しようとしています)。

https://www.kernel.org/doc/Documentation/early-userspace/READMEから(2004年以降更新されていないという一番下の部分)

カーネルには現在、ルートファイルシステムをマウントする3つの方法があります。

a)カーネルにコンパイルされたすべての必要なデバイスおよびファイルシステムドライバー、initrdなし。init / main.c:init()は、root =オプションとオプションのinit =に基づいてprepare_namespace()を呼び出して、最終的なルートファイルシステムをマウントし、init / main.c:initの最後にリストされている他のinitバイナリを実行します()。

b)モジュールとして構築され、initrdに保存されているデバイスおよびファイルシステムドライバー。initrdには、これらのドライバーモジュールをロードすることになっているバイナリ「/ linuxrc」が含まれている必要があります。また、linuxrcを介して最終ルートファイルシステムをマウントし、pivot_root syscallを使用することもできます。initrdはprepare_namespace()を介してマウントおよび実行されます。

c)initramfsを使用します。prepare_namespace()の呼び出しはスキップする必要があります。これは、バイナリがすべての作業を行う必要があることを意味します。このバイナリは、usr / gen_init_cpio.cを変更するか、新しいinitrd形式(cpioアーカイブ)を介してinitramfsに保存できます。「/ init」と呼ばれる必要があります。このバイナリは、prepare_namespace()が実行するすべての処理を実行します。

下位互換性を維持するために、/ initバイナリは、initramfs cpioアーカイブ経由でのみ実行されます。そうでない場合、init / main.c:init()はprepare_namespace()を実行して最終ルートをマウントし、定義済みのinitバイナリの1つを実行します。

Raspberry Piなどのデバイス/ディストリビューションでは、initramfsを使用しないと信じています。場合によっては、カーネルはルートパーティション(必要なfsモジュールがあるブートローダーによってマウントされます)上にあります。カーネルがたとえば/bootパーティション上にある場合、rootfsを他のようにマウントする前に同じパーティションのinitramfsに直接アクセスできます。述べています。

場合によっては、initramfs カーネルと同じファイルに組み込むことできますが、常にそうであるとは限りません。(a)initramfsが必要でない場合があることをかなり明確に述べているようです。


0

私は次の説明をより明確にし、

initramfsカーネルに埋め込まれ、ブートプロセスの初期段階でロードされるルートファイルシステムです。これはinitrdの後継です。カーネルが起動プロセス中に単独では簡単に実行できないことを実行できる初期のユーザー空間を提供します。

initramfsの使用はオプションです。デフォルトでは、カーネルは組み込みドライバーを使用してハードウェアを初期化し、指定されたルートパーティションをマウントし、インストールされたLinuxディストリビューションのinitシステムをロードします。その後、initシステムは追加のモジュールをロードし、最終的にログインを許可するまでサービスを開始します。これは、デフォルトの動作であり、多くのユーザーにとって十分なものです。initramfsは、高度な要件を持つユーザー向けです。ルートパーティションがマウントされる前であっても、できるだけ早く物事を行う必要があるユーザー向け。

initramfsでできることの例を次に示します。

  • ルートパーティションをマウントします(暗号化、論理、およびその他の特別なパーティション用)。
  • (何かがうまくいかない場合)最小限のレスキューシェルを提供します。
  • ブートプロセスをカスタマイズします(たとえば、ウェルカムメッセージの印刷、ブートスプラッシュなど)。
  • ロードモジュール(サードパーティのドライバーなど)。
  • カーネルができないこと(たとえば、コマンドを実行するなどしてユーザー空間でできる限り)。高度な要件がない場合は、initramfsは必要ありません。

-1

あなたが何をしても、あなたは持っていinitramfsます。それなしでやることはありません-それはあなたに課せられた唯一のファイルシステムです。kernel.orgから:

rootfsとは何ですか?

Rootfs特別なインスタンスであるramfs(またはtmpfsである、というのが有効な場合) 2.6システムで常に存在。 あなたはアンマウントすることはできませんrootfsあなたがinitプロセスを殺すことができない、ほぼ同じ理由で、空のリストをチェックして処理する特別なコードを用意するのではなく、特定のリストが空にならないことを確認するだけでカーネルがより小さく簡単になります。

ほとんどのシステムは、単に別のファイルシステムをマウントしrootfsて無視します。ramfsの空のインスタンスが占めるスペースはごくわずかです。

* CONFIG_TMPFS *が有効になっている場合、デフォルトでrootfstmpfsなくが使用ramfsされます。力にramfs追加"rootfstype=ramfs"のカーネルコマンドラインに。

initramfsとは何ですか?

2.6のすべてのLinuxカーネルには、gzip圧縮された"cpio"形式のアーカイブが含まれており、カーネルの起動時に展開されrootfsます。 抽出した後ならば、カーネルかどうかを確認しrootfs、ファイルが含まれている"init"としてそれを実行している場合、PID 1. もしが見つかっ、このinitプロセスは、位置と実際のルートデバイスを取り付け、システムの道までの残りの部分をもたらすなどのために責任があります(もしあれば)。埋め込みアーカイブが抽出された後、プログラムrootfsが含まれていない 場合、カーネルは古いコードに移動してルートパーティションを見つけてマウントし、その中からいくつかのバリアントを実行します。initcpio/sbin/init

これらはすべて、いくつかの点で古いinitrdと異なります。

  • 古いinitrdは常に別のファイルでしたが、initramfsアーカイブはLinuxカーネルイメージにリンクされています。 (ディレクトリlinux-* / usrは、ビルド中にこのアーカイブを生成するために使用されます。)

  • 古いinitrdファイルはgzip圧縮されたファイルシステムイメージ(カーネルに組み込まれたドライバーを必要とするext2などの一部のファイル形式)でしたが、新しいinitramfsアーカイブはgzip圧縮されたcpioアーカイブです(tarのように単純で、cpio(1)を参照)およびDocumentation / early-userspace / buffer-format.txt)。カーネルのcpio抽出コードは非常に小さいだけでなく、ブートプロセス中に破棄できる__initテキストとデータでもあります。

  • 古いinitrd(/ initではなく/ initrdと呼ばれる)によって実行されるプログラムは、セットアップを行ってからカーネルに戻りましたが、initramfsからのinitプログラムはカーネルに戻ることはありません。(/ initが制御を渡す必要がある場合、新しいルートデバイスで/をオーバーマウントし、別のinitプログラムを実行できます。以下のswitch_rootユーティリティを参照してください。)

  • 別のルートデバイスを切り替えるとき、initrdはpivot_rootしてからramdiskをアンマウントします。ただし、initramfsはrootfsです。pivot_rootrootfsもマウント解除もできません。 代わりに、rootfsからすべてを削除してスペースを解放し(-xdev / -exec rm '{}' ';'を見つけます)、新しいルートでrootfsをオーバーマウントします(cd / newmount; mount --move。/; chroot。)、 stdin / stdout / stderrを新しい/ dev / consoleに接続し、新しいinitを実行します。

これは非常に厄介なプロセスであるため(コマンドを実行する前にコマンドを削除する必要があります)、klibcパッケージにはこれをすべて行うヘルパープログラム(utils / run_init.c)が導入されました。他のほとんどのパッケージ(busyboxなど)は、このコマンドに「switch_root」という名前を付けています。

initramfsの設定:

2.6カーネルビルドプロセスは、常にgzip圧縮されたcpio形式のinitramfsアーカイブを作成し、結果のカーネルバイナリにリンクします。 デフォルトでは、このアーカイブは空です(x86では134バイトを消費します)。

configオプションCONFIG_INITRAMFS_SOURCE(menuconfigのGeneral Setupにあり、usr / Kconfigにあります)を使用して、initramfsアーカイブのソースを指定できます。これは、結果のバイナリに自動的に組み込まれます。このオプションは、既存のgzip圧縮されたcpioアーカイブ、アーカイブされるファイルを含むディレクトリ、または次の例のようなテキストファイル指定を指すことができます。

  dir /dev 755 0 0
  nod /dev/console 644 0 0 c 5 1
  nod /dev/loop0 644 0 0 b 7 0
  dir /bin 755 1000 1000
  slink /bin/sh busybox 777 0 0
  file /bin/busybox initramfs/busybox 755 0 0
  dir /proc 755 0 0
  dir /sys 755 0 0
  dir /mnt 755 0 0
  file /init initramfs/init.sh 755 0 0

(カーネルのビルド後) "usr / gen_init_cpio"を実行して、上記のファイル形式を文書化した使用法メッセージを取得します。

構成ファイルの利点の1つは、新しいアーカイブにアクセス許可を設定したり、デバイスノードを作成したりするためにルートアクセスが必要ないことです。(これら2つの「ファイル」エントリの例では、「init.sh」および「busybox」という名前のファイルがlinux-2.6。*ディレクトリの下の「initramfs」というディレクトリにあることに注意してください。詳細。)

カーネルは外部cpioツールに依存しません。構成ファイルの代わりにディレクトリを指定すると、カーネルのビルドインフラストラクチャはそのディレクトリから構成ファイルを作成し(usr / Makefileがscripts / gen_initramfs_list.shを呼び出します)、構成ファイルを使用してそのディレクトリをパッケージ化しますusr / gen_init_cpio.c)から作成されたusr / gen_init_cpio。カーネルのビルド時cpio作成コードは完全に自己完結型であり、カーネルのブート時抽出プログラムも(明らかに)自己完結型です。


1
initramfsなしで起動できます。あなたの答えはinitramfsのメリットについて詳しく説明していますが、これは典型的な組み込みシステムには当てはまりません。また、initramfsが推奨されるデスクトップやサーバーでも、それは必須ではありません。
ジル 'SO-悪であるのをやめる' 14年

@Gilles-いいえ、できません。何をするかに関係なく、initramfsがあります。カーネルにコンパイルされます-今、あなたのカーネル、私のカーネル、すべてのカーネル。カーネルのドキュメントを読んでください-私の投稿全体はコピーアンドペーストでした。あなたは間違っています。どのようにして公式文書に異議を唱えることができますか?
mikeserv 14年

1
私は公式文書に異議を唱えません。あなたがそこから引き出しているという結論に異議を唱えます。あなたは、initramfsの使用方法を説明したドキュメントを読んでいます。initramfsを使用する必要があるとは記載されていません。
ジル「SO-悪であるのをやめる」14年

@Gillesこれで十分でない場合: "2.6カーネルビルドプロセスは、常にgzip圧縮されたcpio形式のinitramfsアーカイブを作成し、結果のカーネルバイナリにリンクします。デフォルトでは、このアーカイブは空です(x86で134バイトを消費します).... 「もっとうまくできる。上記は2または3分のWeb検索でした。
mikeserv 14年

3
私は、ドキュメントを読んだことがあります。私は生活のためにこれを行います。それは意見の問題ではありません。そこinitramfsには常にあるが、それは必ずしもブートに使用されていません。おそらく、それが説明を必要としないと考えられている古典的なケースだからです。メインロジックはであるdo_mounts.c-特にprepare_namespace、その中saved_root_nameで占めていますroot=コマンドライン引数。
ジル「SO-停止されて悪」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.