Linuxの起動プロセス

Debian Bookwormで Linux カーネル 6.1 を起動する

Linuxのブートプロセスは複数の段階から成り、多くの点でBSDやその他のUnixスタイルのブートプロセス(LinuxはBSDやその他のUnixスタイルのブートプロセスから派生したもの)と類似しています。Linuxのブートプロセスはコンピュータアーキテクチャに大きく依存しますが、これらのアーキテクチャは共通の段階とソフトウェアコンポーネントを共有しています。[ 1 ]システムの起動、ブートローダの実行、Linuxカーネルイメージのロードと起動、そして様々な起動スクリプトデーモンの実行が含まれます。[ 2 ]これらは、システムの起動、ブートローダ段階、カーネル段階、そしてinitプロセスの4つのステップにグループ化されます。[ 3 ]

Linux システムが電源投入またはリセットされると、そのプロセッサは、パワーオンセルフテストなどのシステム初期化用の特定のファームウェア/プログラムを実行し、リセットベクターを呼び出してフラッシュ/ROM (組み込み Linux デバイスの場合) 内の既知のアドレスにあるプログラムを開始し、ブートローダを後の実行のために RAM にロードします。[ 2 ] IBM PC 互換パーソナルコンピュータ(PC)では、このファームウェア/プログラムはBIOSまたはUEFIモニタであり、マザーボードに格納されています。[ 2 ]組み込み Linux システムでは、このファームウェア/プログラムはブート ROMと呼ばれます。[ 4 ] [ 5 ] RAM にロードされた後、ブートローダ (第 1 ステージブートローダまたはプライマリブートローダとも呼ばれる) が実行され、第 2 ステージブートローダ[ 2 ] (セカンダリブートローダとも呼ばれる) がロードされます。[ 6 ]第 2 ステージブートローダはカーネルイメージをメモリにロード[ 2 ]第2段階のブートローダは、システムハードウェアのチェック、ルートデバイスのマウント、必要なカーネルモジュールのロードなど、システム上でいくつかの操作を実行します。[ 2 ]最後に、最初のユーザー空間プロセス(initプロセス)が開始され、その他の高レベルのシステム初期化が実行されます(起動スクリプトが含まれます)。[ 2 ]

これらのステージとコンポーネントごとに、さまざまなバリエーションとアプローチがあります。たとえば、GRUBsystemd-bootcoreboot 、またはDas U-Boot をブートローダとして使用できます (歴史的な例としてはLILOSYSLINUX、またはLoadlinがあります)。一方、起動スクリプトは従来のinitスタイルにすることも、 systemdUpstartなどの最新の代替手段を使用してシステム構成を実行することもできます。

システムの起動

システムの起動は、Linuxが起動されているハードウェアに応じて異なる手順になります。[ 7 ]

IBM PC 互換ハードウェアは、Linux が一般的に使用されるアーキテクチャの 1 つです。これらのシステムでは、BIOSまたはUEFIファームウェアが重要な役割を果たします。

BIOSシステムでは、BIOSはそれぞれ電源投入時セルフテスト(POST)を実行します。これは、システムハードウェアをチェックし、次にローカルデバイスを列挙し、最後にシステムを初期化します。[ 7 ]システムの初期化では、BIOSはOSを保存しているシステム上の起動可能なデバイスを検索することから始めます。起動可能なデバイスには、フロッピーディスク、CD-ROM、USBフラッシュドライブ、ハードディスク上のパーティション(ハードディスクにWindowsとFedoraなど複数のOSを保存している場合)、ローカルネットワーク上のストレージデバイスなどがあります。[ 7 ] Linuxを起動するハードディスクには、マスターブートレコード(MBR)が保存されています。これには、RAMにロードするための第1段階/プライマリブートローダが含まれています。[ 7 ]

UEFIシステムでは、LinuxカーネルはEFIブートスタブを介してUEFIファームウェアによって直接実行できますが[ 8 ]、通常はGRUB 2またはsystemd-bootをブートローダーとして使用します。[ 9 ] [ 10 ]

UEFIセキュアブートがサポートされている場合、ブートローダーまたはEFIスタブ搭載カーネルの前に、UEFIによって「シム」または「プリローダー」が起動されることが多い。[ 11 ] UEFIセキュアブートが無効になっている 場合でも、後で有効になった場合に備えて、このシムが存在し、起動される可能性がある。これは、UEFIキーデータベースを変更することなく、後続のブートステージの署名検証に必要なキーを提供する追加の署名キーデータベースを追加するだけで、UEFIと同様に後続のブートステップにチェーンされる。

組み込み Linux システムのシステム起動ステージは、オンチップブート ROM上のファームウェア/プログラムを実行することから始まります。次に、eMMC、eUFS、NAND フラッシュなどのストレージデバイスからブートローダ/オペレーティングシステムがロードされます。[ 5 ]システム起動のシーケンスはプロセッサによって異なりますが[ 5 ]、すべてハードウェアの初期化とシステムハードウェアのテスト手順が含まれます。[ 7 ]たとえば、i.MX7D プロセッサと OS (U-Boot を含む) を保存したブート可能なデバイスを備えたシステムでは、オンチップブート ROM が最初にDDR メモリコントローラをセットアップし、ブート ROM のプログラムがブート可能なデバイス上の外部ブートローダから SoC 構成データを取得できるようにします。[ 5 ]次に、オンチップブート ROM はブートローダステージのために U-Boot を DRAM にロードします。[ 12 ]

ブートローダーステージ

BIOSを使用するIBM PC 互換機では、マスター ブート レコード(MBR)の一部である第 1 ステージ ブートローダは、ベンダー固有のプログラム コードとパーティション テーブルを含む 512 バイトのイメージです。[ 6 ]導入部分で前述したように、第 1 ステージ ブートローダは第 2 ステージ ブートローダを見つけてロードします。[ 6 ]これは、パーティション テーブルでアクティブなパーティションを検索することによって行われます。[ 6 ]アクティブなパーティションが見つかると、第 1 ステージ ブートローダはテーブル内の残りのパーティションをスキャンし続け、すべてが非アクティブであることを確認します。[ 6 ]このステップの後、アクティブなパーティションのブート レコードが RAM に読み込まれ、第 2 ステージ ブートローダとして実行されます。[ 6 ]第 2 ステージ ブートローダの役割は、Linux カーネル イメージをメモリ、およびオプションの初期 RAM ディスクにロードすることです。[ 13 ]カーネルイメージは実行可能なカーネルではなく、カーネルの「圧縮ファイル」であり、zlibを使用してzImage または bzImage形式に圧縮されています。[ 14 ]

これらのシステムでは、第 1 ステージおよび第 2 ステージのブートローダは、通常GRand Unified Bootloader (GRUB) によって提供され、以前は Linux Loader ( LILO ) によって提供されていました。[ 13 ]現在使用されているGRUB 2は、さまざまなオペレーティングシステムの自動検出と自動構成が可能な点で GRUB 1 と異なります。stage1 は、MBR から BIOS によってロードされ、実行されます。中間ステージローダ (stage1.5、通常は core.img) は、stage1 ローダによってロードされ、実行されます。第 2 ステージローダ (stage2、/boot/grub/ ファイル) は、stage1.5 によってロードされ、ユーザーがオペレーティングシステムを選択したり、スタートアップパラメータを調べて編集したりできる GRUB スタートアップメニューを表示します。メニューエントリが選択され、オプションのパラメータが指定されると、GRUB は Linux カーネルをメモリにロードし、制御を渡します。GRUB 2 は、別のブートローダをチェーンロードすることもできます。

UEFIシステムでは、stage1 と stage1.5 は通常、同じ UEFI アプリケーション ファイルです ( x64 UEFI システムの場合は grubx64.efi など)。

GRUB 以外にも、人気のあるブートローダーがいくつかあります。

現在では一般的には使用されていない歴史的なブートローダには、次のものがあります。

  • LILO はファイルシステムのレイアウトを理解または解析しません。代わりに、/etc/lilo.confカーネルと RAM ディスク (initrd または initramfs) の位置に関する生のオフセット情報 (マッパーツール) をマッピングする設定ファイル () がライブシステム内に作成されます。設定ファイルには、それぞれのブートパーティションカーネルパス名、必要に応じてカスタマイズされたオプションなどのデータが含まれており、ブートローダーコードと共に MBR ブートセクターに書き込まれます。このブートセクターが BIOS によって読み込まれ制御されると、LILO はメニューコードを読み込み、描画します。その後、保存された値とユーザー入力を組み合わせて Linux カーネルを計算し、ロードするか、他のブートローダーをチェーンロードします
  • GRUB 1には、設定ファイルにアクセスするために、実行時に共通ファイルシステムを読み取るロジックが含まれています。[ 15 ]これにより、GRUB 1は設定ファイルをMBRに埋め込むのではなく、ファイルシステムから読み取ることができるようになりました。これにより、実行時に設定を変更したり、オフセットに頼ることなく人間が読める形式でディスクやパーティションを指定したりすることが可能になりました。また、コマンドラインインターフェースも含まれているため、GRUBの設定ミスや破損があった場合に、簡単に修正または変更することができます。[ 16 ]
  • Loadlin は、実行中のDOSまたはWindows 9xカーネルを Linux カーネルに置き換えることができるブートローダーです。これは、ソフトウェアで電源をオンにする必要があるハードウェアで、そのような設定プログラムが独自仕様で DOS でしか利用できないような場合に便利です。Linux には多数のハードウェアデバイス用のドライバーがあるため、このブート方法の必要性は今日ではあまりありませんが、モバイルデバイスではある程度使用されています。別のユースケースとしては、Linux が BIOS からブートに利用できないストレージデバイス上に配置されている場合が挙げられます。DOS または Windows は、BIOS の制限を補うために適切なドライバーをロードし、そこから Linux を起動することができます。

カーネル

カーネルステージはブートローダステージの後に行われます。Linuxカーネルは、メモリ管理、タスクスケジューリングI/Oプロセス間通信、システム全体の制御など、すべてのオペレーティングシステムプロセスを処理します。これは2段階でロードされます。最初の段階では、カーネル(圧縮されたイメージファイルとして)がメモリにロードされ、解凍され、基本的なメモリ管理、最小限のハードウェアセットアップなどのいくつかの基本機能がセットアップされます。[ 14 ]カーネルイメージは自己解凍され、これはカーネルイメージルーチンの一部です。[ 14 ]一部のプラットフォーム(ARM 64ビットなど)では、カーネルの解凍はU-Bootなどのブートローダによって実行する必要があります。[ 17 ]

これらの手順の詳細については、 i386マイクロプロセッサの例を参照してください。その bzImage が呼び出されると、関数start()(の./arch/i386/boot/head.S) が呼び出されて基本的なハードウェア セットアップが行われ、次にstartup_32()(に位置./arch/i386/boot/compressed/head.S) が呼び出されます。[ 14 ]startup_32()は環境 (スタックなど) の基本的なセットアップを行い、Block Started by Symbol (BSS)をクリアしてから、 decompress_kernel()(に位置./arch/i386/boot/compressed/misc.c) を呼び出してカーネルを解凍します。[ 14 ]startup_32()次に、にある別の関数によってカーネルの起動が実行されます./arch/i386/kernel/head.S[ 14 ]カーネルの起動関数startup_32()(スワッパーまたはプロセス 0 とも呼ばれる) は、メモリ管理(ページング テーブルとメモリ ページング) を確立し、 CPUの種類と浮動小数点機能などの追加機能を検出し、start_kernel()にあるの呼び出しによってアーキテクチャ固有ではない Linux カーネル機能に切り替えます./init/main.c[ 14 ]

start_kernel()広範囲にわたる初期化機能を実行します。割り込み処理( IRQ ) を設定し、メモリをさらに構成し、ブートローダの段階で一時ルートファイルシステムとして以前にロードされた初期 RAM ディスク("initrd") をマウントします。 [ 14 ] RAM 内の一時ルートファイルシステムとして機能する initrd により、カーネルを完全にブートし、他のデバイス (ハードディスクなど) に依存せずにドライバモジュールをメモリから直接ロードすることができます。[ 14 ] initrd には通常、ストレージ周辺機器とのインターフェイスに必要なモジュール( SATA ドライバなど) が含まれており、多数のハードウェア構成がサポートされています。[ 14 ]一部のドライバをカーネルに静的にコンパイルし、他のドライバを initrd からロードするように分割することでより小さなカーネルを実現しています。[ 14 ] initramfs(早期ユーザー空間とも呼ばれる)は、Linuxカーネルのバージョン2.5.46から利用可能になりました。[ 18 ]その目的は、以前はカーネルが起動プロセス中に実行していた機能を可能な限り置き換えることです。早期ユーザー空間の典型的な用途は、メインのユーザー空間ファイルシステムをロードするために必要なデバイスドライバーを検出し、それらを一時ファイルシステムからロードすることです。多くのディストリビューションは、dracutを使用してinitramfsイメージを生成および管理しています。

ルートファイルシステムは、後での呼び出しによって切り替えられ、pivot_root()一時ルートファイルシステムがアンマウントされ、実際のルートファイルシステムがアクセス可能になったら、実際のルートファイルシステムの使用に置き換えられます。[ 14 ]一時ルートファイルシステムによって使用されていたメモリはその後再利用されます。

最後に、kernel_thread(in arch/i386/kernel/process.c)が呼び出され、Initプロセス(最初のユーザー空間プロセス)が開始され、その後、を介してアイドルタスクが開始されますcpu_idle()[ 14 ]

したがって、カーネルステージでは、デバイスを初期化し、ブートローダによって指定されたルートファイルシステムを読み取り専用としてマウントし、システムによって実行される最初のプロセス(PID = 1)として指定されているInit( )を実行します。[ 19 ]ファイルシステムをマウントするとカーネルによってメッセージが出力され、Initプロセスを開始するとInitによってメッセージが出力されます。[ 19 ]/sbin/init

Red Hatによれば、この段階でのカーネルプロセスの詳細は次のように要約される。[ 15 ]

カーネルがロードされると、直ちにコンピュータのメモリを初期化および構成し、システムに接続された様々なハードウェア(すべてのプロセッサ、I/Oサブシステム、ストレージデバイスなど)を構成します。次に、メモリ内の所定の場所で圧縮されたinitrdイメージを検索し、解凍してマウントし、必要なすべてのドライバをロードします。次に、LVMやソフトウェアRAIDなど、ファイルシステムに関連する仮想デバイスを初期化してから、initrdディスクイメージをアンマウントし、ディスクイメージが占有していたすべてのメモリを解放します。その後、カーネルはルートデバイスを作成し、ルートパーティションを読み取り専用でマウントし、未使用のメモリを解放します。この時点で、カーネルはメモリにロードされ、動作可能になります。ただし、システムへの意味のある入力を可能にするユーザーアプリケーションがないため、カーネルでできることはあまりありません。initramfsスタイルのブートは、前述のinitrdブートに似ていますが、同一ではありません。

この時点で、割り込みが有効になっているため、スケジューラはシステム全体の管理を制御し、プリエンプティブなマルチタスクを提供でき、init プロセスはユーザー空間でユーザー環境のブートを続行します。

初期化プロセス

カーネルが起動すると、initプロセス[ 20 ]が起動します。initプロセスは、ファイルシステムのチェックとマウント、他のプロセスの起動など、ユーザー空間のブートストラップを行うデーモンです。initシステムは、ブート時に最初に起動され、シャットダウン時に最後に終了するデーモンです。

歴史的にはこれは「SysV init 」と呼ばれていましたが、これは単に「init」と呼ばれていました。最近のLinuxディストリビューションでは、 systemdなどのより現代的な代替手段が使用される傾向があります。以下は主要なinitプロセスの概要です。

  • SysV init(単に「init」とも呼ばれる)は、 UNIX System Vのinitプロセスに似ています。標準的なLinuxシステムでは、initはランレベルと呼ばれるパラメータを用いて実行されます。ランレベルは0から6までの値を取り、どのサブシステムを動作させるかを決定します。各ランレベルには、特定のランレベルの設定や終了に関わる様々なプロセスをコード化した独自のスクリプト"/etc/rc..."があり、ブートプロセスで必要に応じてこれらのスクリプトが参照されます。initスクリプトは通常、 などの名前のディレクトリに保存されます。initの最上位設定ファイルは にあります/etc/inittab[ 21 ]システムブート中に、initは/etc/inittabにデフォルトのランレベルが指定されているかどうかを確認し、指定されていない場合はシステムコンソールを介してランレベルに入るように要求します。次に、指定されたランレベルに関連するすべてのブートスクリプトを実行します。これには、モジュールのロード、ルートファイルシステム(読み取り専用でマウントされていた)の整合性チェックと完全な読み取り/書き込みアクセスのための再マウント、ネットワークの設定などが含まれます。[ 19 ]指定されたプロセスをすべて生成した後、initは休止状態になり、開始したプロセスが終了または死ぬ、電源障害信号、または/sbin/telinitランレベルをさらに変更するための要求のいずれかのイベントが発生するのを待ちます。[ 22 ]
  • systemdはSysV initの現代的な代替である。initと同様に、systemdは他のデーモンを管理するデーモンである。すべてのデーモンは、systemdも含めてバックグラウンドプロセスである。最初にsystemdを開発したソフトウェアエンジニアであるLennart PoetteringKay Sievers [ 23 ]は、いくつかの方法でinitデーモンの効率を超えようとした。彼らは、依存関係を表現するためのソフトウェアフレームワークを改善し、システムのブート中により多くの処理を並行して行えるようにしシェルの計算オーバーヘッドを削減したいと考えていた各デーモンに対するsystemdの初期化命令は、シェルスクリプトではなく、宣言型の設定ファイルに記録される。プロセス間通信のために、systemdは実行中のデーモンがUnixドメインソケットD-Busを利用できるようにする。systemdは積極的な並列化も可能である。

参照

参考文献

  1. ^ M. Tim Jones 2006、「はじめに」、「Linux® システムの起動プロセスは、いくつかの段階から構成されます。しかし、標準的な x86 デスクトップを起動する場合でも、深く組み込まれた PowerPC® ターゲットを起動する場合でも、そのフローの多くは驚くほど似ています。」
  2. ^ a b c d e f g M. Tim Jones 2006、「概要」、「図1. Linuxブートプロセスの20,000フィートビュー」
  3. ^ M. Tim Jones 2006、「LinuxのブートプロセスはIBMの情報源に基づいて4つの段階に分けられる」
  4. ^ Bin, Niu; Dejian, Li; Zhangjian, LU; Lixin, Yang; Zhihua, Bai; Longlong, He; Sheng, Liu (2020年8月).セキュアブートモードをサポートするBootromの研究と設計. 2020 International Symposium on Computer Engineering and Intelligent Communications (ISCEIC). pp.  5– 8. doi : 10.1109/ISCEIC51027.2020.00009 . ISBN 978-1-7281-8171-4. S2CID  231714880 .
  5. ^ a b c dアルベルト・リベラル・デ・ロス・リオス、2017 年、p. 28、「Linux ブート プロセス」。
  6. ^ a b c d e f M. Tim Jones 2006、「ステージ 1 ブートローダー」。
  7. ^ a b c d e M. Tim Jones 2006、「システムスタートアップ」。
  8. ^ 「EFIスタブカーネル - Gentoo Wiki」 . wiki.gentoo.org . 2020年11月2日閲覧
  9. ^ Kinney, Michael (2000年9月1日). 「EFIによるBIOSブート問題の解決」(PDF) . pp.  47– 50. 2007年1月23日時点のオリジナル(PDF)からアーカイブ。 2010年9月14日閲覧
  10. ^ 「MSはセキュアブートがLinuxを除外すると否定」 The Register、2011年9月23日。 2011年9月24日閲覧
  11. ^ 「署名付きブートローダーの使用 - Arch Wiki」 . wiki.archlinux.org . 2024年12月5日閲覧
  12. ^アルベルト・リベラル・デ・ロス・リオス、2017 年、p. 29、「Linux ブート プロセス」。
  13. ^ a b M. Tim Jones 2006、「ステージ 2 ブートローダー」。
  14. ^ a b c d e f g h i j k l m n M. Tim Jones 2006、「カーネル」。
  15. ^ a b「製品ドキュメント」 . Redhat.com. 2013年9月30日. 2008年8月30日時点のオリジナルよりアーカイブ2014年1月22日閲覧。
  16. ^ 「製品ドキュメント」 . Redhat.com. 2013年9月30日. 2014年1月22日閲覧
  17. ^アルベルト・リベラル・デ・ロス・リオス、2017 年、p. 20、「ブートローダー」。
  18. ^ Corbet, Jonathan (2002年11月6日). 「Initramfs が到着」. 2011年11月14日閲覧。
  19. ^ a b c http://oldfield.wattle.id.au/luv/boot.html Linux ブートプロセス - Kim Oldfield (2001)
  20. ^ M. Tim Jones 2006、「Init」。
  21. ^ 「電源投入から Bash プロンプトまで: Init」 . users.cecs.anu.edu.au .
  22. ^ "init" . man.he.net .
  23. ^ "systemd README" . freedesktop.org . 2012年9月9日閲覧。

引用文献