システムの起動
システムの起動シーケンス
- 電源投入
- OS 起動用ファームウェア (BIOS, UEFI) を起動し、ブートローダーをメモリにロードする
- BIOS の場合: ディスクの先頭ブロックに書き込まれたブートローダーをメモリにロードする
- UEFI の場合: UEFI ブートエントリーで指定された EFI パーティション中のブートローダーをメモリにロードする
- ブートローダー (GRUB Legacy, GRUB2) がカーネル (vmlinuz) と initramfs をメモリにロードし、カーネルを起動する
- カーネルが自身の初期化シーケンスを実行し、cpio で アーカイブされ gzip で圧縮された initramfs をメモリ上に展開する
- initramfs をメモリ上に展開し、次の手順で実行する
- メモリ上に展開された initramfs を一時的なルートファイルシステムとしてマウントする
- init プロセスを起動する
- SysV init の場合: initramfs 内の init を起動し、ディスク内のルートファイルシステムをマウントする
- systemd の場合: initramfs 内の init からシンボリックリンクされた systemd を起動し、ディスク内のルートファイルシステムをマウントする
- ルートファイルシステムを initramfs からディスク内のルートファイルシステムへ切り替える
/sbin/init
を実行し、起動シーケンスを開始する- SysV init の場合: カーネルはディスク内のルートファイルシステムの
/sbin/init
を実行し、/etc/inittab
を参照して起動シーケンスを開始する - systemd の場合: カーネルはディスク内のルートファイルシステムの
/sbin/init
を実行し、シンボリック先の/lib/systemd/sytemd
を再実行して各ユニット設定ファイルを参照して起動シーケンスを開始する
- SysV init の場合: カーネルはディスク内のルートファイルシステムの
- ランレベルやターゲットにしたがってサービスを起動する
- SysV init の場合:
etc/inittab
に定義したシステムのランレベルに従って、RC スクリプトなどのプログラムを実行する - systemd の場合: 各ユニっっと設定がいるに定義されたシステム設定や各サービスのためのデーモンを起動する
- SysV init の場合:
- ログインプロンプトあるいはログイン画面からログインする
OS 起動ファームウェア
種類 | 名称 | 説明 |
---|---|---|
BIOS | Basic Input/Output System | マザーボード上の NVRAM に格納されたファームウェア。電源を投入すると設定されたデバイスの優先順位に従って、ディスクの先頭ブロックにある MBR 内のブートローダーを検索して最初に検知したデバイスブートローダーを起動する |
UEFI | Unified Extensible Firmware Interface | NVRAM のブートエントリーに設定された優先順位に従って、UEFI パーティションのブートローダーを起動する |
ブートローダー
主要なブートローダーは次の 2 種類である。 最近ではより新しい GRUB2 を採用する Linux ディストリビューションが多い。
- GRUB Legacy
- GRUB2
GRUB のロードシーケンス
GRUB は stage2 のプログラムが設定ファイル /boot/grub/menu.lst
を読み、その記述に従ってカーネルと initramfs をメモリにロードする。
- セクタ番号 1 にある stage1 では MBR の 0x44~0x47 領域に記載されている stage1.5 か stage2 のブロック番号を読み取る
- stage1.5 の場合は stage2 をファイルシステムとして読み込む
/boot/grub/stage2
は menu.lst を読み込む/boot/grub/menu.lst
の記述内容に従って、カーネルと initramfs をメモリに読み込む
GRUB 設定ファイルの例
設定項目 | 説明 |
---|---|
default | デフォルトで起動する OS を定義 (title エントリの順番を指定) |
timeout | OS を自動起動するまでの待機時間を定義 |
splashimage | GRUB メニューの背景画像を指定 |
hiddenmenu | GRUB メニューを非表示 |
title | 起動する OS に対して名前を定義 |
root | ルートデバイスとしてカーネルが保存されているパーティションを指定 |
kernel | カーネルのイメージファイルとカーネルオプションを指定 |
initrd | 初期 RAM ディスクのイメージファイルを指定 |
GRUB2 のロードシーケンス
GRUB2 では起動時に実行されるバイナリ構成が異なる。 また、GRUB Legacy であった stage1~2 は無くなった代わりに boot.img と core.img、動的にロードされる複数のモジュールで構成される。
- セクタ番号 1 にある boot.img を読み込む
- セクタ番号 2~64 の core.img で grub.cfg をもとに少数のモジュールを動的リンクする
- その後 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 | ほとんどのカーネルメッセージを抑制し、表示を行わない |
nosmp | SMP であっても非 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 [ファイルシステム]
カーネルの初期化
カーネル起動時の初期化シーケンス
- GRUB による vmlinuz と initramfs のロード
- カーネル解凍: vmlinuz の先頭部に連結された misc.o によって自己解凍
- カーネル初期化: ページング機構、スケジューラ、割り込みベクタテーブル、タイマーなどを初期化
- initramfs 解凍: gzip 圧縮形式の initramfs の解凍、解凍された cpio 形式の initramfs の展開
- initramfs の /init 実行:
- デバイスファイル作成
- モジュールのロード
- ルートファイルシステムのマウント
- ルートファイルシステムの切り替え
/sbin/init
の実行:- マウントされたルートファイルシステムの
/sbin/init
をカーネル内システムコール関数 kernel_execve() により実行 - またはカーネル起動時のオプションで
init=
で指定したプログラムを実行
- マウントされたルートファイルシステムの
/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 コマンドが実行される。
- /bin/mknod コマンドにより必要なデバイスファイルを作成
- /bin/mkdir コマンドにより必要なディレクトリを作成
- /bin/mount コマンドにより擬似ファイルシステムをマウント
- /bin/mount コマンドによりディスクないのルートファイルシステムを /sysroot にマウント
- /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 ファイルはメモリ上にロードされ、ディスクには保存されない。
- クライアントの PXE 対応 NIC からサーバーへ DHCP リクエスト
- サーバーから IP アドレスと NBP ファイル名を取得
- クライアントからサーバーへ NBP ファイルを TFTP リクエスト
- サーバーから prelinux.0 をダウンロード
- NBP ファイル (prelinux.0) を起動して TFTP リクエスト
- サーバーから 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 | マルチユーザー + GUI | 5 |
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
配下にあるシンボリックをすべて削除する
コメント