LPIC-2 試験勉強メモ その 3

LPIC-2 試験勉強メモ その 3

システムの起動

システムの起動シーケンス

  1. 電源投入
  2. OS 起動用ファームウェア (BIOS, UEFI) を起動し、ブートローダーをメモリにロードする
    • BIOS の場合: ディスクの先頭ブロックに書き込まれたブートローダーをメモリにロードする
    • UEFI の場合: UEFI ブートエントリーで指定された EFI パーティション中のブートローダーをメモリにロードする
  3. ブートローダー (GRUB Legacy, GRUB2) がカーネル (vmlinuz) と initramfs をメモリにロードし、カーネルを起動する
  4. カーネルが自身の初期化シーケンスを実行し、cpio で アーカイブされ gzip で圧縮された initramfs をメモリ上に展開する
  5. initramfs をメモリ上に展開し、次の手順で実行する
    • メモリ上に展開された initramfs を一時的なルートファイルシステムとしてマウントする
    • init プロセスを起動する
      • SysV init の場合: initramfs 内の init を起動し、ディスク内のルートファイルシステムをマウントする
      • systemd の場合: initramfs 内の init からシンボリックリンクされた systemd を起動し、ディスク内のルートファイルシステムをマウントする
    • ルートファイルシステムを initramfs からディスク内のルートファイルシステムへ切り替える
  6. /sbin/init を実行し、起動シーケンスを開始する
    • SysV init の場合: カーネルはディスク内のルートファイルシステムの /sbin/init を実行し、/etc/inittab を参照して起動シーケンスを開始する
    • systemd の場合: カーネルはディスク内のルートファイルシステムの /sbin/init を実行し、シンボリック先の /lib/systemd/sytemd を再実行して各ユニット設定ファイルを参照して起動シーケンスを開始する
  7. ランレベルやターゲットにしたがってサービスを起動する
    • SysV init の場合: etc/inittab に定義したシステムのランレベルに従って、RC スクリプトなどのプログラムを実行する
    • systemd の場合: 各ユニっっと設定がいるに定義されたシステム設定や各サービスのためのデーモンを起動する
  8. ログインプロンプトあるいはログイン画面からログインする

OS 起動ファームウェア

種類名称説明
BIOSBasic Input/Output Systemマザーボード上の NVRAM に格納されたファームウェア。電源を投入すると設定されたデバイスの優先順位に従って、ディスクの先頭ブロックにある MBR 内のブートローダーを検索して最初に検知したデバイスブートローダーを起動する
UEFIUnified Extensible Firmware InterfaceNVRAM のブートエントリーに設定された優先順位に従って、UEFI パーティションのブートローダーを起動する

ブートローダー

主要なブートローダーは次の 2 種類である。 最近ではより新しい GRUB2 を採用する Linux ディストリビューションが多い。

  • GRUB Legacy
  • GRUB2

GRUB のロードシーケンス

GRUB は stage2 のプログラムが設定ファイル /boot/grub/menu.lst を読み、その記述に従ってカーネルと initramfs をメモリにロードする。

  1. セクタ番号 1 にある stage1 では MBR の 0x44~0x47 領域に記載されている stage1.5 か stage2 のブロック番号を読み取る
  2. stage1.5 の場合は stage2 をファイルシステムとして読み込む
  3. /boot/grub/stage2 は menu.lst を読み込む
  4. /boot/grub/menu.lst の記述内容に従って、カーネルと initramfs をメモリに読み込む
GRUB 設定ファイルの例
設定項目説明
defaultデフォルトで起動する OS を定義 (title エントリの順番を指定)
timeoutOS を自動起動するまでの待機時間を定義
splashimageGRUB メニューの背景画像を指定
hiddenmenuGRUB メニューを非表示
title起動する OS に対して名前を定義
rootルートデバイスとしてカーネルが保存されているパーティションを指定
kernelカーネルのイメージファイルとカーネルオプションを指定
initrd初期 RAM ディスクのイメージファイルを指定

GRUB2 のロードシーケンス

GRUB2 では起動時に実行されるバイナリ構成が異なる。 また、GRUB Legacy であった stage1~2 は無くなった代わりに boot.img と core.img、動的にロードされる複数のモジュールで構成される。

  1. セクタ番号 1 にある boot.img を読み込む
  2. セクタ番号 2~64 の core.img で grub.cfg をもとに少数のモジュールを動的リンクする
  3. その後 GRUB を起動し、カーネルと initramfs をロードする
GRUB2 設定ファイル
設定ディレクトリとファイル説明
/bootgrub設定ファイルとモジュールの置かれたディレクトリ
/boot/grub/grub.cfg設定ファイル
/usr/lib/grub/i386-pcモジュールの置かれたディレクトリ
/etc/grub.d設定ファイル grub.cfg の生成時に実行するスクリプトが置かれたディレクトリ

grub-mkconfig コマンド

設定ファイル grub.cfg を生成する。 引数なしで実行すると設定ファイルの内容を標準出力に出力する。

  • -o: 出力先を指定
grub.cfg の設定内容
set root='hd0,msdos1'
linux /bootvmlinuz-3.9.5 root=/dev/sda1 ro
initrd /boot//initramfs-3.9.5.img
  • 1 行目: ブートするカーネルと initrd の置かれルパ=ディションとディスクを ‘ディスク,パーティション’ で指定
  • 2 行目: カーネルと引数を指定。ランレベルを追加すると指定したランレベルで立ち上げる
    • GRUB1 では kernel で始まり、GRUB2 では linux で始まる
  • 3 行目: initramfs を指定。
    • GRUB1 ではパーティションは 0 始まり、GRUB2 では 1 始まり

ディスクとデバイス名との対応は /boot/grub/device.map に格納されている。

UEFI 起動の場合 EFI パーティション内の FAT32 ファイルシステム上にある shim.efi というブートローダを呼び出す。 GRUB2 の場合は boot.img と core.img を呼び出す。

ブートローダで指定するパラメータ

オプション説明
roルートパーティションを読み取り専用でロードする
root=ルートパーティションをパーティション名もしくはラベル名で指定する
quietほとんどのカーネルメッセージを抑制し、表示を行わない
nosmpSMP であっても非 SMP による単一プロセッサでの処理を行う
maxcpus=使用する CPU の最大個数を指定する
init=カーネルが生成する最初のプログラムを設定する

カーネル起動時に指定したパラメータは /proc/cmdline ファイルに格納される。

UEFI の起動

GPT の EFI System Partition に格納されたブートローダを起動する。 この中に shim.efi があり、grubx64.efi が grub.cfg を参照したのちに vmliinuz initramfs を起動する。

efibootmgr コマンド

EFI ブートエントリを表示編集できる。

efibootmgr [オプション]
  • -b, –bootnum: ブートエントリ番号の指定
  • -c, –create: 新規ブートエントリの作成
  • -l, –loader: ローダーを指定
  • -o: ブートエントリの起動順序を変更
  • -p, –part: EFI パーティションのパーティション番号を指定
  • -v, –verbose: 詳細表示
  • -B, –delete-bootnum: ブートエントリの削除
  • -L, –label: ブートエントリ名の指定

ルートデバイスを正しくマウントできなかった場合はカーネルパニックとなる。 システム立ち上げ時、最初に実行される /etc/rc.sysinit スクリプト内で fsck -a によってルートファイルシステムと /etc/fstab に登録されているファイルシステムの正常性をチェックしてマウントする。

grub-install コマンド

指定したファイルシステムに GURB をインストールする。 /boot/grub/stage1 の内容が指定したファイルシステムの先頭ブロック (MBR) に書き込まれる。

grub-install [ファイルシステム]

カーネルの初期化

カーネル起動時の初期化シーケンス

  1. GRUB による vmlinuz と initramfs のロード
  2. カーネル解凍: vmlinuz の先頭部に連結された misc.o によって自己解凍
  3. カーネル初期化: ページング機構、スケジューラ、割り込みベクタテーブル、タイマーなどを初期化
  4. initramfs 解凍: gzip 圧縮形式の initramfs の解凍、解凍された cpio 形式の initramfs の展開
  5. initramfs の /init 実行:
    1. デバイスファイル作成
    2. モジュールのロード
    3. ルートファイルシステムのマウント
    4. ルートファイルシステムの切り替え
  6. /sbin/init の実行:
    1. マウントされたルートファイルシステムの /sbin/init をカーネル内システムコール関数 kernel_execve() により実行
    2. またはカーネル起動時のオプションで init= で指定したプログラムを実行
  7. /etc/inittab を参照し、init は RC スクリプトを実行

dmesg コマンド

カーネル内の循環バッファに記録されたカーネル起動時のメッセージを表示する。

dmesg [-c] [-r] [-n level] [-s bufsize]
  • -c: 循環バッファの内容を表示した後、バッファの内容をクリアする (root ユーザーのみ使用可能)
  • -r: バッファないのログレベルのプレフィックスを削除することなく、そのまま表示する
  • -n レベル: 循環バッファに書き込むログレベルを指定する (root ユーザーのみ使用可能)
  • -s バッファサイズ: 読み込むコマンド側のバッファサイズを指定する (デフォルトサイズは 16,392 バイト)

起動時 start_kernel() はカーネル関数 printk() によって書き込まれる。 dmesg はシステムコール klogctl() を発行して循環バッファの内容を読み込む。

initramfs マウント後

initramfs の /init コマンドが実行される。

  1. /bin/mknod コマンドにより必要なデバイスファイルを作成
  2. /bin/mkdir コマンドにより必要なディレクトリを作成
  3. /bin/mount コマンドにより擬似ファイルシステムをマウント
  4. /bin/mount コマンドによりディスクないのルートファイルシステムを /sysroot にマウント
  5. /sbin/switch_root コマンドによりディスク内のルートファイルシステムに切り替え

Syslinux プロジェクトで開発されるブートローダー

  • SYSLINUX: MS-DOS FAT に対応したブートローダー
  • PXELINUX: PXE ブート (ネットワークブート) に対応したブートローダー
  • ISOLINUX: CD-ROM ブートに対応したブートローダー
  • EXTLINUX: ext2/ext3/ext4 及び Btrfs に対応したブートローダー

PXE

PXE (Preboot eXection Environment) はネットワークブートのプロトコルである。 クライアントがネットワーク上のサーバーから Network Bootstrap Program (NBP) をダウンロードし、 NBP がカーネルと initramfs をダウンロードして起動する。

PXE のブートシーケンス

次の流れで PXE を起動する。 NBP ファイルはメモリ上にロードされ、ディスクには保存されない。

  1. クライアントの PXE 対応 NIC からサーバーへ DHCP リクエスト
  2. サーバーから IP アドレスと NBP ファイル名を取得
  3. クライアントからサーバーへ NBP ファイルを TFTP リクエスト
  4. サーバーから prelinux.0 をダウンロード
  5. NBP ファイル (prelinux.0) を起動して TFTP リクエスト
  6. サーバーから vmlinnuz と initramfs をダウンロード

その他の開発ブートローダー

  • systemd-boot: systemd 独自の EFI 対応ブートローダー
  • U-boot: 組み込み Linux システムで使用されるブートローダー

サービスの起動

init プロセス

init は Linux カーネルが最初に生成するユーザープロセスである。 PID は必ず 1 になる。 init には次の 2 種類がある。 最近ではより新しい systemd を採用する Linux ディストリビューションが多い。

  • SysV init
  • systemd

SysV init

  • デフォルトランレベルの指定: /etc/inittab

ブートローダの引数で指定したものの方が優先される。

/etc/inittab の記述

id:runlevels:action:process
フィールド説明
  • id: 1~4 文字の各エントリの識別子
  • runlevels: 指定されたランレベルの時に第 4 フィールドのコマンドを実行
  • action: どのような動作をするか指定
    • initdefault: システム起動完了後のランレベルを第 2 フィールドで指定
    • sysinit: システム起動時にこのエントリの第 4 フィールドを実行
    • wait: 第 4 フィールドのコマンドを一度だけ実行して次のエントリに進む
    • respawn: 起動されたデーモンが終了すると再起動される
  • process: 第 2 フィールドのランレベルと一致した時に実行するコマンドやデーモンの指定

systemctl コマンド

systemd の管理対象となるユニットに対してさまざまな管理を行う。

systemctl [オプション] サブコマンド [unit 名]
オプション
  • -a, –all: 非アクティブなユニットも含めてロードされているユニットをすべて表示
  • -l, –full: unit 名などを省略しないで表示
  • -t, –type=: 表示するユニットのタイプを指定
サブコマンド
主なサブコマンド説明
startユニットを開始 (アクティブ化) する
restartユニットをリスタートする
stopユニットを (非アクティブ化) する
statusユニットの状態を表示する
enableユニットを enable にして、システム起動時に自動的に開始するようにする
disableユニットを disable にして、システム起動時に自動的に開始しないようにする
list-unitsアクティブなユニットをすべて表示する
list-unit-filesインストールされているすべてのユニットを表示する
get-defaultデフォルトのターゲットを表示する
set-defaultデフォルトのターゲットを指定する
ターゲット
主なターゲット説明SysV init ランレベル
default.targetデフォルトターゲットデフォルトランレベル
poweroff.target電源オフ0
rescue.targetレスキューモード1
mulit-user.targetマルチユーザー3
graohical.targetマルチユーザー + GUI5
reboot.targetシステム再起動6

systemd-delta コマンド

変更された設定ファイルを表示する。

systemd-delta [オプション] [プレフィックス | サフィックス]

引数をつけなかった場合は変更されたすべての設定ファイルを表示する。

  • -t, –type: 表示する変更の種類を指定
    • overridden: 上書きによる変更
    • extended: ドロップインディレクトリ (/etc/systemd/system/ユニット名.d/*.conf) による追加変更
    • unchanged: 変更なし

systemd-fstab-generator により生成される mount ユニットによって /etc/fstab に記述されたローカルファイルシステムと NFS をマウントする。

chkconfig コマンド

RHEL 系ディストリブユーションでは、サービスの管理は chkconfig コマンドで行う。

chkconfig [--list] [サービス名]
chkconfig [--level レベル] サービス名 {on | off}

update-rc.d コマンド

Debian 系ディストリビューションでは、サービスの管理は update-rc.d コマンドで行う。

update-rc.d サービス名 defaults
update-rc.d サービス名 remove
  • -f: /etc/init.d 配下にあるシンボリックをすべて削除する