LinuC-1 - 101試験 - 1.01:Linuxのインストールと仮想マシン・コンテナの利用 - 1.01.3 ブートプロセスとsystemd

Last Update : August 21 2022 17:47:19

     

a. Linuxの起動

コンピュータが起動して使えるようになるまでは、様々なハードウェア・ソフトウェアが段階的に処理していき、オペレーティングシステムが完全に起動して初めて使えるようになります。ここではPC(x86 アキテクチャ)を例にとってその起動シーケンスを見てみます。PCの起動シーケンスは大きく以下のようになります。

● BIOSの場合
  1. 電源投入
     ↓
  2. BIOS
    POST(Power On Self Test)と呼ばれる、ハードウェアのチェックと初期化を実行します。
    次に起動するためのドライブを探します。起動ドライブとなるのは通常FDD、HDD、 CD-ROMなどです。BIOSは起動ドライブを見つけるとそのデバイスをファーストブートドライブとして起動を試みます。
    ブートドライブが決まったら、ブートドライブのディスクの先頭ブロック(MBR:Master Boot Record)に書き込まれた第1ステージ・ブートローダをメモリにロードします。
    MBRにはパーティションテーブルも書き込まれています。
     ↓
  3. 第1ステージ・ブートローダ
    第1ステージ・ブートローダが /boot パーティションから第2ステージ・ブートローダーをメモリにロードします。
     ↓
  4. 第2ステージ・ブートローダ
    Linuxの代表的なブートローダにはLILOとGRUBがあります。
    ・GRUBの場合:直接、設定ファイル/boot/grub/grub.confを読み込みます。
    ・LILOの場合:MBRの情報を使用してブートオプションを決定します。
    カーネルの選択画面を表示し、選択されたカーネルのカーネルバイナリーファイル[/boot/vmlinuz-バージョン]を/bootディレクトリ内から見つけて、ロードします。
    もし存在すれば、initrdイメージ[/boot/initrd-バージョン.img]をメモリにロードしておく。ここでブートローダーの役目は終わり、ブートプロセスの制御をカーネルに渡します。
     ↓
  5. カーネル
    カーネルは自身の初期化シーケンス(メモリの初期化、CPU、記憶装置など各種ハードウェアをpci情報などから設定します。)を実行し、メモリにロードされている小さなファイルシステムinitrdをマウントします。
     ↓
  6. initrd (カーネルプロセス)(initramfs)
    カーネルはinitrdを利用してルートファイルシステムを読み取り専用でマウントします(一般的にはinitrdを使用しますが、使用しない設定もあります)
    initrdはinitrdとinitramfsの2種類ある。最近の場合、initrdといえばinitramfsのことを指す場合が多い。
    initramfsは、ルートディレクトリをcpioという形式でアーカイブされ、gzipで圧縮されている。
    本番のルートファイルシステムが置いてあるディスクをマウントするために必要なドライバ類や各種ユーティリティが含まれる。
    /sbin/initプログラムを実行します。
     ↓
  7. init (カーネルプロセス)
    カーネルは自身の初期化の最終段階で1番目のユーザープロセスであるinit(プロセスIDは1)を生成します。起動時のカーネルオプションの指定により、init以外のプロセス(例えば/bin/bash)を生成することもできます。
    /etc/inittabの設定に従って処理を行います。
     ↓
  8. /etc/inittab (initプロセス)
    initは起動すると/etc/inittabを読みます。/etc/inittabにはシステムのランレベルと、initが起動するプログラムが記述されています。
    /etc/rc.d/rc.sysinitスクリプトを実行します。
     ↓
  9. rcスクリプト (initプロセス)
    initは/etc/inittabに指定されている、rcスクリプト(Run Control Script)である/etc/rc.d/rc.sysinit、/etc/rc.d/rcを実行します。
    システムの初期設定を行います。この段階で、殆どのデバイス・ドライバは、モジュールとしてロードされます。
    rc.sysinitスクリプトの中で、ルートファイルシステムを読み書きできる状態で再度マウントし直します。
    rc.sysinitスクリプトから/etc/rc.d/init.d/functionsスクリプトが実行されます。
    ランレベルに合せてサービスを起動します。
    ランレベル5では、/etc/X11/prefdmスクリプトを実行し、Xウィンドウマネージャを起動します。これで一連の起動シーケンスが完了します。

PCの電源を投入すると、マザーボードのフラッシュROMに書き込まれたBIOS(Basic Input/Output System)というソフトウェアが起動します。このBIOSの初期化プログラムが、PCに接続されている各種デバイスの初期化を行います。この過程を POST(Power On Self Test)といいます。POSTの段階で最初に初期化が行われるのはビデオカードです。
このビデオカードの初期化が終わるとよく目にするBIOSの初期化状況を表示する画面になります。

各種デバイスの初期化が終了すると、BIOSは次の段階に入り、起動するためのドライブを探します。起動ドライブとなるのは通常FDD、HDD、 CD-ROMなどです。BIOSは起動ドライブを見つけるとそのデバイスをファーストブートドライブとして起動を試みます。最初にブートドライブとして何のデバイスが認識されるかはBIOSの設定次第ですが、ここではHDDの起動を中心に見ていきます。HDDの接続については、IDEインターフェイスのHDDでは接続の場所によってブートの優先度が自動的に決まります。(優先度の最も高いのはプライマリのマスタです)こういったブートドライブとなりうるデバイスの中の最も優先順位が高いデバイスを、BIOSはブートドライブとして決定することになります。

ブートドライブが決定すると、BIOSはそのブートドライブの先頭セクタのロードという段階に移ります。HDDでは先頭セクタのことを MBR(Master Boot Record)といい、MBRは1台のHDDに1つしか存在しません。BIOSはこのMBRをメモリ上にロードし、MBR領域にあるプログラムに制御を移します。このMBR領域にあるプログラムを、一般的にブートストラップローダと呼びます。

ブートストラップローダは、実行のなかでパーティションテーブルから起動フラグのあるパーティションを探します。パーティションテーブルとは、複数のパーティションに関する情報が保存されているMBR内の1つの領域です。この起動フラグのあるパーティションにブートストラップローダから制御が移行します。そのとき、ブートストラップローダから呼び出されるのが各基本パーティションにあるブートセクタになります。ブートセクタは各基本パーティションの先頭セクタのことを指し、PBR(Partition Boot Record)とも呼ばれます。

PBRに制御が移行すると、そのPBRのプログラムコードが動作することになります。このPBRにあるプログラムコードが IPL(Initial Program Loader)と呼ばれるもので、OSを起動させるためのブートローダの残りの機能を呼び出す機能を持ちます。

  • ※ブートローダの残りの機能はブートローダの2ndステージとも呼ばれます。

MBRやPBRは512バイトと非常に小さな領域しかもっていません。そのなかの一部であるIPLのデータサイズはさらに小さなものになります。この小さなデータサイズにOSを起動させるためのブートローダのプログラムを全て格納することは困難です。そのためIPLはブートローダの一部のプログラムコードを持ち、ブートローダの残りに機能はPBRの後続セクタに置くかたちになっています。IPLから呼び出されたブートローダが後続のOSのファイルを読み込んでいき、最終的にOSが起動していくことになります。

  • ※LinuxのブートローダをMBR領域に格納した場合は、そのMBR領域のプログラムがパーティションのブートローダを起動する形になっています。
● UEFIの場合
  1. 電源投入
    システムのUEFIファームウェアは、電源オン・セルフテスト(POST)を実行し、ハード・ディスクなどの周辺デバイスを検出して初期化します。
     ↓
  2. UEFI
    UEFIは、ブート・ローダーなどのEFIアプリケーションを含む、EFIシステム・パーティション(ESP)として識別する特定のグローバル一意識別子(GUID)を持つGPTパーティションを検索します。複数のブート・デバイスが存在する場合、UEFIブート・マネージャは、ブート・マネージャで定義された順序に基づいて、使用する適切なESPを決定します。efibootmgrツールでは、デフォルト定義を使用しない場合に、別の順序を定義できます。
     ↓
  3. セキュア・ブート
    UEFIブート・マネージャは、セキュア・ブートが有効になっているかどうかを判定します。セキュア・マネージャが有効になっていない場合、ブート・マネージャはESPでGRUB 2ブート・ローダーを実行します。
    それ以外の場合は、ブート・マネージャがブート・ローダーから証明書をリクエストし、UEFIセキュア・ブート・キー・データベースに格納されているキーに対してこの証明書を検証します。証明書検証プロセスを処理するために、2段階のブート・プロセスを実行するように環境が構成され、GRUB 2ブート・ローダーをロードする前に、認定を実行するshim.efiアプリケーションが最初にロードされます。証明書が有効な場合は、ブート・ローダーが実行され、次にロードするように構成されているカーネルが検証されます。
     ↓
  4. カーネル
    ブート・ローダーはvmlinuzカーネル・イメージ・ファイルをメモリーにロードし、initramfsイメージ・ファイルのコンテンツを一時的なメモリー・ベースのファイル・システム(tmpfs)に抽出します。
     ↓
  5. initrd (カーネルプロセス)(initramfs)
    カーネルは、ルート・ファイル・システムへのアクセスに必要なドライバ・モジュールをinitramfsファイル・システムからロードします。
     ↓
  6. systemdプロセス
    カーネルは、プロセスID 1 (PID 1)でsystemdプロセスを開始します。2.1項「systemdサービス・マネージャについて」を参照してください。
     ↓
  7. 他のプロセスの起動
    systemdは、定義されているすべての追加プロセスを実行します。

Linuxの起動スクリプトを実行する方法に、SysVinit、Upstart、Systemdの3種類ある。

b. SysVinit

SysVinit では、Linux カーネルがロードされたあと init が一番最初のプロセスとして起動します。カーネルによって使われるデフォルトの init プログラムは /sbin/init です。 inittab は /etc に置かれた init の起動設定ファイルのことです。特定のランレベルに入ったときにどのプログラムやスクリプトを実行すればいいのか init に指定します。 システム起動時の initプロセス(/sbin/init)では、/etc/inittabファイルに従いシステムサービスを起動します。

     
  1. initが、/etc/inittab を読み込む。
  2.  
  3. initが、/etc/rc.sysinitスクリプトを実行する。
  4.  
  5. initが、/etc/rcスクリプトを実行する。
  6.  
  7. /etc/rcスクリプトが、/etc/rc(ランレベル).d ディレクトリ配下の起動スクリプトを実行する。

SysVinitでは、各種サービスを起動するために /etc/init.d ディレクトリの配下に用意されている起動スクリプトが使われます。ランレベルが異なれば起動サービスも異なります。/etc/rc*.d ディレクトリでは、各ランレベルで起動するサービス、終了するサービスのスクリプトファイルが配置されています。


c. Upstart

Upstart は、SysVinitの代わりになる init デーモンです。
SysVinit との違いは、SysVinit の init デーモンは、指定されたランレベルに必要なサービスを、 決められた順番で起動(あるいは停止)していきます。 Upstartは、サービスを順番に起動するのではなく、 サービスが起動できる状態になったとき(イベント)に、起動します。Upstartはイベント駆動型のinitです。
SysVinitでは、順番に起動するのに比べて、Upstartでは、並列で起動できるため全体の起動時間が早くなります。
イベントは、ハードウェアの変更、タスクの開始または停止、あるいはシステム上の他のプロセスなどです。
Upstartは,/etc/event.dディレクトリに格納されているファイル群で定義された「イベント・ジョブ」を実行する仕組みになっています。/etc/event.dディレクトリ内の各ファイルには「start on イベント名」という設定行があり,ここで指定されたイベントが発生すると,「exec コマンド名」という設定行で指定したコマンドが実行されます。


d. systemd

systemdは、SysVinitやUpstartではシェルスクリプトで行っていた起動処理を新しく作り直し、処理を分割して並列化することでシステム起動処理を高速化します。
systemdでは、様々な処理をそれぞれUnitとして定義して、実行時には各Unitを指定して実行します。つまり、従来、シェルスクリプトでシーケンシャルに実行されていた処理を複数のUnitに分解して並列実行します。
定義ファイルは、/etc/systemd/systemと/usr/lib/systemd/systemに配置されています。デフォルトの設定は/usr/lib/systemd/systemに、管理者が追加修正したものは/etc/systemd/systemに配置します。
デフォルト値の変更時は、/usr/lib/systemd/systemのファイルをコピーして /etc/systemd/systemに保存して編集します。
元に戻す場合は、 /etc/systemd/systemにあるファイルを削除します。
同じ名前のファイルがあった場合は、/etc/systemd/systemが優先されます。
Unitにはいくつか種類があり、拡張子によって判別されます。


●主なUnitの種類
 .serviceプロセスの起動/停止に関する設定
ファイル名は「プロセス名.service」となる
(httpd.service、sshd.serviceなど)
 .mountファイルシステムのマウント/アンマウントに関する設定
ファイル名は「マウントポイント.mount」となる
/etc/fstabの内容を元にSystemdが自動作成する
 .socketソケットの監視設定
”ソケットへの接続を検出すると特定のプロセスを起動”といった動作を実現可
(xinet.dの代替にできる)
 .deviceシステムが認識しているデバイス情報を保持する
udevデーモンによって自動作成される
 .pathパスの監視設定
”監視ディレクトリにファイルが置かれたらサービス起動”といった動作を実現可
 .target複数のUnitをとりまとめるUnit
 .swapスワップ領域の有効化
(etc/fstabから自動作成)

● 複数のUnitをまとめるtarget

複数のUnitをグルーピングすることができるtargetと呼ばれるUnitがあります。
targetは他Unitとの関係を保持し、複数のUnitをとりまとめます。targetを利用することで、Unit同士の依存や起動順定義が楽に行うことができます。


● ランレベルの代わりに target Unit

Systemdでは全てがUnitで処理されるため、従来のランレベルというプロセスの管理体系はなくなり、ランレベルに相当する機能を target Unit を利用して処理しています。
ランレベルの目的は、ランレベル別に定義された状態でシステムを起動するために必要となるプロセスを管理することにあり、init/Upstartでは、/etc/rc.d/rc[runlevel].dにランレベルに応じたプロセス群を定義することでこれを実現していました。
Systemdでは、これらのプロセスをtargetとしてグルーピングすることでランレベルと同様のプロセス管理を実現しています。
従来のランレベルは0 – 6の7種類のみ定義されていたのに対し、targetは好きなだけ定義できるため、より柔軟になっています。

●主なtargetの種類
 target名 内容従来のランレベル
(RedHat)
 poweroff.targetシステム停止 0
 rescue.targetシングルユーザモード 1
 multi-user.targetマルチユーザモード (コンソールログイン) 3
 graphical.targetマルチユーザ+GUI 5
 reboot.target再起動 6
 emergency.target緊急シェル
rescue.targetよりも起動対象が少ない
ルートファイルシステムですらマウントできない場合などに利用
 無し

【 default.target 】
default.target とは、OS の起動シーケンスの起点となるユニットで(一番最初に起動される)、systemd は default.target に記述されている依存関係を満たすように、各種ユニットを立ちあげます。
defualt.target の実体はシンボリックリンクで、具体的な処理の中身はリンク先のターゲットによって決まります。
default.target にリンクされているtargetは、一般的にGUI のシステムでは graphical.target に、GUI 無しのシステムでは multi-user.target にリンクされています。
default.target に何がリンクされているかは systemctl get-default で確認できます。

$ systemctl get-default
graphical.target

systemctl set-default によって default.target にリンクするターゲットを変更できます。

# systemctl set-default multi-user.target
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target → /usr/lib/systemd/system/multi-user.target.

【 現在のターゲットの変更 】
現在実行中のセッションで異なるターゲットユニットに変更するには、systemctl isolate のコマンドを実行します。

グラフィカルユーザーインターフェースを無効にし、現行セッションで multi-user.target ユニットに変更するには、

# systemctl isolate multi-user.target

すぐに再起動するには、

# systemctl isolate reboot.target

e. Linuxのブートローダ

現状ではLinuxのデフォルトのブートローダにはLILO(LInux LOader)とGRUB(GRand Unified Bootloader)が採用されています。LILO、GRUBなどのブートローダの役目はOSの本体である、カーネルをロードすることにあります。この 2つはブートローダという点においては同じ物ですが、それぞれカーネルのロードまでの工程が異なります。

● LILO(LInux LOader)
LILOは古くからLinuxで利用されてきたブートローダです。特徴としてはカーネルの位置情報をLILO自身内部に情報として持ち、その情報からカーネルをロードするというものです。LILOはファイルシステムを認識しないため、カーネルの位置をHDDの物理的な位置情報で判断しています。この物理的な位置情報をブロックリストといいます。
LILOはこのブロックリストを自身の内部に保持しており、ブロックリストを参照してカーネルをロードします。そのためLILOは「ブロックリスト参照型」のブートローダといわれます。

● GRUB(GRand Unified Bootloader)
GRUBは高性能ブートローダでLILOとは異なる仕組みを持ちます。GRUBの特徴の1つにファイルシステムを認識できることがあげられますが、これはLILOとは異なりカーネルの位置をファイルパスで指定することができることを意味しています。このようなタイプを「ファイルシステム認識型」といいます。

こういったLILOやGRUBの動作を経て、カーネルがロードされることになるわけですが、このカーネルがロードされてからがOS自身の起動シーケンスであり、カーネルの制御下でOSとして機能するための様々な処理が行われます。


起動時にカーネルにオプションを指定する

GRUBなどのブートローダーから渡される起動オプションを解釈し機能を有効/無効にしたりデフォルトとは異なる設定で起動できます。


  1. 起動オプションを変更するにはまず起動時にShiftキーを押しつづけ、GRUBメニューを表示します。
  2. 起動可能なカーネル一覧が表示されたら起動したいカーネルにカーソルを合わせて編集のためにeキーを押します。
  3. kernelで始まる行を選択してさらにeボタンを押下します。
  4. 起動オプションを設定します。
  5. Returnで戻り、bキーを押して起動します。
● 起動オプション(一部)
 1ランレベル1(シングルユーザモード)で起動します。rootユーザのみが使用可能な状態になり、ネットワークやNFSなどの設定は自動的には行われません。主にシステムの管理や復旧のときに使用します。
 3ランレベル3で起動します。通常のユーザも使用できます。コンソールからのログインになります。
 5ランレベル5で起動します。通常のユーザも使用できます。Xサーバが起動され、gdmなどのディスプレイマネージャが起動されます。ログイン後すぐにXウインドウ環境が使えます。
 root=/dev/hda1ルートファイルシステムのデバイス名を指定します。
 debug ログレベルを10に設定する。( 全てのカーネルメッセージをコンソールに出力
 mem=数 メモリーサイズを指定した値に設定する。
例:512mだと512Mバイト、2gだと2Gバイト。
 root=デバイスなどルートファイルシステムを指定したデバイスに設定する。
 console=デバイス コンソールを指定したデバイスに設定する。
 init=プログラム /sbin/initの代わりに指定したプログラムを起動する。
 initcall_debug 初期化時の関数呼び出しの情報をカーネルメッセージに出力する
 disable_ipv6=1IPv6を無効にする ( 0だと無効 )
 ip=dhcpなど IPアドレスをDHCPなどに設定する
 nosmp SMPを無効にする
 nr_cpus=数指定した数のCPUを使用する
 nousbUSBを使わない
 single シングルユーザモードでシステムを起動する
 emergency 緊急モードでシステムを起動する。
 text テキストモードでシステムを起動する。
 init=/bin/sh起動時に実行させるプログラムを指定します。システムが破損され、全く起動できない非常事態のときにinit=/bin/shと指定すると、シェル/bin/shを起動させることができます。



f.ブート時のメッセージ

1.サーバー起動時のメッセージを表示する [ dmesg ] [ Ctrl +s,Ctrl + q ]

起動時にコンソール上に表示されるメッセージは、流れるのが早すぎて全てをじっくり見ることは不可能です。これらのメッセージは、サーバーが立ち上がってから、dmesg コマンドを使用する事で後でじっくり閲覧する事ができるようになります。但し、dmesg で表示されるメッセージは、起動時に表示されたものそっくりそのままではありません。
dmesgコマンドは、カーネルのリングバッファの内容を表示するためのコマンドで、システム起動時のメッセージや稼働中のカーネル情報などを得ることができます。
また、/var/log/dmesg ファイルや /var/log/messages 、 /var/log/boot.log を参照することで、同じような情報を得ることが可能です。

$ dmesg | more

起動時にリアルタイムで確認するには、コンソール上のキーボード操作で確認する事ができます。まず、コンソール上の画面をストップさせるには、Ctrl + s、再開するには、Ctrl + qをタイプします。なお、上にスクロールする際には、Shift + PageUp 、下にスクロールさせるには、Shift + PageDown でできます。


g.コマンドラインからシャットダウンおよびリブートする。

コマンドラインからシャットダウンするには、shutdown, halt, reboot, poweroff コマンドを使います。


参照 => 1.01.1 Linuxのインストール、起動、接続、切断と停止



z. 出題範囲概要

概要 :
  • UEFI/BIOSからブート完了までのブート手順について理解している。
  • システムにおけるsystemdのブートターゲットを管理できる。これには、シングルユーザモードへの変更と、システムのシャットダウンまたはリブート、デフォルトのsystemdのブートターゲットの設定も含まれる。

詳細 :
  • デフォルトのブートターゲットを設定する。
    systemd, systemctl
  • ブートターゲット(シングルユーザモードを含む)を変更する。
    systemctl
  • コマンドラインからシャットダウンおよびリブートする。
    shutdown, halt, reboot, poweroff


  [ 例題 ] 


         

    www.it-shikaku.jp