0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Linux ブート

Last updated at Posted at 2025-07-01

はじめに

電源を入れてから OS が起動するまでの流れを ブート または ブートストラップ と言う。

ブート手順は アーキテクチャ によって異なる。

さらに近年では従来から広く利用されてきた SysV init 方式から systemd 方式へ移り変わりつつある。

SysV init は 直列 で各プログラムを起動していくのに対して、systemd は 並列 で起動を行うため、起動速度に違いがあるものの、基本的な流れは共通している。

  1. 電源 ON
  2. ファームウェアが起動
  3. ブートローダが起動
  4. カーネルが起動
  5. init(または systemd)が起動
  6. ランレベル(SysVinit)またはターゲット(systemd)に応じたサービスが起動

ファームウェア

Firmware

BIOS (Basic Inpput / Output System)や UEFI (Unified Extensible Fireware Interface)に代表される、デバイスを制御するためのプログラム。

実体はソフトウェアでありながら、ハードウェアとソフトウェアの中間的な存在として位置づけられるため「ファームウェア」と呼ばれる(firm = 固い、堅牢)。

ブートローダ をメモリ上に展開して起動する役割を持つ。

UEFI は BIOS の後継プログラムであり、両者は別々のものだが、BIOS という用語が広く定着しているために UEFI を指して BIOS を言うことがある。

BIOS はマザーボード上の ROM に書き込まれているため、工場出荷後のプログラム更新が困難。

UEFI は、書き換え可能な フラッシュメモリ(NVRAM)に書き込まれるため、発売後にアップデートを行うことができる(ファームウェアアップデート)。

また UEFI には、デジタル署名済みの信頼できるソフトウェアだけを起動するセキュリティ機能(セキュアブート)もある。

ブートローダ

Boot Loader

GRUB 、Windows Boot Manager に代表される、カーネルをメモリにロードして起動するプログラム。

複数の OS がインストールされている PC などで、どの OS を起動するかを選択できる機能を デュアルブート や、マルチブート という。

/boot/grub/menu.lst/boot/grub/grub.conf が設定ファイルとして使用される。

ACPI

advanced configuration and power interface

電力を管理するための規格。

  • 電源ボタンを押す
  • ノートPCを開ける・閉じる

などの物理的操作によって ACPI イベントが発生する。イベントは acpid デーモンによって処理される。

SysVinit

System V(Five) Init

長年 Linux の標準的な init システムとして使用されてきた、システムの起動やプロセス管理の仕組み。

並列処理ができないことによる起動の遅さなどの課題があり、Red Hat 系(RHEL、CentOS、Fedora)や Debian 系(Debian、Ubuntu)では、既に後継版である systemd に移行されている。

ただし一部の軽量ディストリビューション(Alpine Linux)では、現在も SysVinit が採用されている。

  • ランレベル でシステムの状態を管理する
  • サービスの起動を 直列処理 で 1 つずつ順番に起動するため時間がかかる
  • サービスが異常終了した場合、自動で復旧しない

SysVinit の主な役割は、システム起動時に必要なプロセスを適切に立ち上げ、シャットダウン時に適切に停止することだが、「デーモンを起動する」、「親プロセスが終了した孤立プロセスを引き取る」役割なども併せ持つ。

ランレベル

システムの状態を管理するための概念のこと。

例えば「シャットダウン」は「ランレベル 0 の呼び出し」を意味し、「システムの再起動」は「ランレベル 6 の呼び出し」を意味している。

ランレベル 意味
0 システムの停止(シャットダウン)
1 シングルユーザモード
root ユーザのみがログインできる
2 マルチユーザモード
NFS なし(※)
3 マルチユーザモード
NFSあり(※)、GUIなし
4 未使用
5 マルチユーザモード + GUI(X Window)
6 システムの再起動

ランレベルの呼び出しは init プロセスによって行われる。

システム起動時に init/etc/inittab に記載されたランレベルに応じて、実際には /etc/rcX.d/ ディレクトリにあるスクリプトを サービス として起動する。rcXrc の語源は run command。X にはランレベルの番号が入る。

/etc/rcX.d/ ディレクトリ内の SK で始まるファイルは、 /etc/init.d/ ディレクトリに配置されたスクリプトへの シンボリックリンク になっている。

Sstart を意味し、Kkill を意味する。

/etc/rc3.d
$ ls -l /etc/rc3.d/
total 0
lrwxrwxrwx 1 root root  17 Jan  1 09:00 K01bluetooth -> ../init.d/bluetooth
lrwxrwxrwx 1 root root  15 Jan  1 09:00 K02cups -> ../init.d/cups
lrwxrwxrwx 1 root root  16 Jan  1 09:00 S01apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root  16 Jan  1 09:00 S02cron -> ../init.d/cron
lrwxrwxrwx 1 root root  18 Jan  1 09:00 S20networking -> ../init.d/networking
lrwxrwxrwx 1 root root  13 Jan  1 09:00 S99local -> ../init.d/rc.local

NFS

Network File System

リモートのサーバにあるファイルをローカルのディレクトリのように扱える仕組み。

例えばサーバー上の /home/shared/ をクライアントの /mnt/shared/マウント すれば、まるでローカルファイルのようにアクセスできるようになる。

ランレベル 2 では NFS クライアントが無効、3 では有効。

/sbin/init

カーネル起動後に最初に実行される /sbin/init プロセス。

PID(プロセスID) 1 が割り当てられる。

ちなみに PID 0 はカーネル用の特別な番号として使われており、 1 はユーザプロセスが使用できる最初の PID である。

ユーザが手動で起動したプロセスは init ではなく、プロセスを起動したシェル(/bin/bash)などが親プロセスになる。

親プロセスは $ pstree で確認することができる。

親子関係を含めて起動中のプロセスを表示する
$ pstree

init は設定ファイル /etc/inittab を読み込んで、どの ランレベル で起動するかを決定しているする。

  1. init/etc/inittab を読み込む
  2. init/etc/rc.sysinit を読み込む
  3. init/etc/rc を実行する
  4. /etc/rc/etc/rcランレベル.d ディレクトリ配下のスクリプトを実行する

/etc/inittab

SysVinit を使うディストリビューションで、デフォルトのランレベルが記述されたファイル。

init により読み込まれる。

/etc/inittab
id:ランレベル:initdefault:

内容を変更した場合、$ init q で即時反映させることができる。

/etc/inittab の変更を反映させる
$ init q

$ runlevel

ランレベルを表示する
$ runlevel

「一つ前のランレベル」と「現在のランレベル」が表示される。起動直後は一つ前のランレベルが N で表示される。

$ init / $ telinit

ランレベルを変更する
$ init ランレベル
$ telinit ランレベル
/etc/inittab の変更を反映させる
$ telinit q

$ wall

ログイン中のすべてのユーザ端末にメッセージを一斉送信(broadcast)する
$ wall 
メッセージをここで入力  # Ctrl + D で送信終了
標準入力からメッセージを受け取る
$ コマンド | wall
ファイルからメッセージを受け取る
$ wall ファイル

$ service

SysV init で使用される サービス 管理用コマンド。

サービスを起動する
$ service サービス start
指定したサービスを停止する
$ service サービス stop
サービスを再起動する
$ service サービス restart
サービスを停止させずに、設定のみ再読み込みする
$ service サービス reload
サービスの状態を確認する
$ service サービス status

systemd

従来の SysV init の後継版として開発され、現代の Linux で主流になっているブートシステム。

以下の特徴を持つ。

  • 並列 処理により高速に起動
  • すべての管理対象(サービス、デバイス、マウントポイントなど)を ユニット という概念で統一的に管理
  • ターゲット によりシステム状態を管理(SysV init のランレベルに相当)
  • 異常終了したサービスを自動で再起動可能
  • journald というログ管理システムが組み込まれている

ただし、以下の批判をされることがある。

  • SysV init はシンプルなシェルスクリプトで構成されていたのに対して、systemd はバイナリの実行可能ファイルで構成されており、内部動作が隠蔽されているのに加えて、仕組みが複雑すぎる
  • UNIX の「小さなツールを組み合わせる」という設計思想に反して、多機能すぎる
  • あまりにも多くを管理しすぎているため、 systemd に対する依存が強くなる

このため、一部のディストリビューション(Alpine Linux, Devuan, Artix Linux など)は systemd を採用せず、SysVinit や runit、OpenRC を使い続けている。

SysV init の init が担っていた役割を、systemd では /usr/lib/systemd/systemd デーモンが担当する。systemdinit 同様に PID 1 が割り当てられる。

systemd の他にも以下のデーモンが存在する。

デーモン 役割
systemd /usr/lib/systemd/systemd
PID 1 の特別なメインプロセス
systemd-journald ログ管理
systemd-logind ログイン処理
systemd-networkd ネットワーク管理
systemd-timesyncd システムクロック 管理
systemd-resolved ホスト名の名前解決
systemd-udevd udev

ユニット

Unit

systemd では、すべてのサービスやリソースを ユニット という概念で管理する。

ユニットは ユニットファイル によって定義され、一つのユニットは複数のサービスから構成される。

systemd では起動や停止処理を「ユニット」単位で制御する。

ユニットの拡張子

ユニットにはいくつかの種類があり、それぞれ以下の拡張子が使用される。

拡張子 説明
.target ターゲット を管理するユニット。ターゲットは SysV init の ランレベルに相当する
【ランレベル:ターゲット】
0poweroff.target
1rescue.target
234multi-user.target
5graphical.target
6reboot.target
.service 自身以外の他のデーモンやサービスを管理するユニット。
【Webサーバ】
httpd.serviceapache2.servicenginx.service
【DBサーバ】
mysqld.servicepostgresql.service
【メールサーバ】
postfix.service
【SSHサーバ】
sshd.servic
【ジョブスケジューラ】
crond.service
.mount マウント を管理するユニット。
.device デバイスを管理するユニット。
.timer ジョブのスケジュールを管理するユニット(cron に相当)。
.socket ソケットを管理するユニット。
.swap スワップ を管理するユニット。

ユニットファイル

ユニットはユニットファイルによって定義される。

ユニットファイルは [セクション] 単位で記述され、一つのセクションは複数の ディレクティブ から構成される。

ユニットファイル
[Unit]
Description=
After=
Wants=
Requires=

[Service] (.service の場合)
ExecStart=
Restart=
User=
Group=

[Install]
WantedBy=
ディレクティブ 説明
Description 説明書き
After 起動していることが前提とされる別ユニット(依存しているユニット。起動順の制御に関係するが、試みるだけで強制力を持たない。つまり、ここに記載されたユニットが起動していなくても、起動処理が走る)
Wants 推奨の依存関係(なくても起動可能)
Requires 必須の依存関係(これが無いと起動しないという別のユニット。強制的な依存関係となるため、一方が停止されるともう一方も停止する。起動も同様。)
ExecStart ユニットが内部で実行するコマンドの絶対パス
Restart 再起動の設定(always、on-failure で指定)
User 実行ユーザ名
Group 実行グループ名
WantedBy 実行時にどのターゲットに関連付けるか

ユニットファイルの配置

ユニットファイルは下記のディレクトリに格納されている。

ディレクトリ 説明
/etc/systemd/system ユーザがカスタマイズしたユニットファイルが格納される
優先順位が最も高い。
/run/systemd/system 一時的な Unit ファイルが格納される。
再起動によって消失する。
/usr/lib/systemd/system Linux デフォルトのユニットファイルが格納される
ユーザが直接編集しない。
/lib/systemd/system ディストリビューションによって /usr/lib/systemd/system の代わりに使用される。
~/.config/systemd/user ユーザ単位のユニットファイルが格納される。

/usr/lib/systemd/systemd

systemd の本体は /usr/lib/systemd/systemd にあり、ブートローダがカーネルに制御を渡したあと、最初にこのプロセスが PID 1 として起動される。

$ systemctl

System Control

systemd で使用されるユニット管理用コマンド。

指定するユニットが ***.service の場合、.service を省略できる。

ユニットを起動する
$ systemctl start ユニット
ユニットを停止する
$ systemctl stop ユニット
システムをシャットダウンする
$ systemctl poweroff
ユニットを再起動する
$ systemctl restart ユニット
システムを再起動する
$ systemctl reboot
ユニット(サービス)を停止させずに、設定のみ再読み込みする
$ systemctl reload ユニット # サービスごとに設定ファイルは異なる
ユニット(サービス)を停止させずに、ユニットファイルの変更を反映させる
$ systemctl daemon-reload

$ systemctl reload サービス は特定のサービスの設定を再読み込みするためのコマンド。

$ systemctl daemon-reloadsystemdユニットファイル の変更を反映させるためのコマンド。

システム起動時にユニットを自動起動する
$ systemctl enable ユニット
システム起動時にユニットを自動起動させない
$ systemctl disable ユニット
ユニットの状態を確認する
$ systemctl status ユニット
ユニットが稼働しているかを確認する
$ systemctl is-active ユニット
ユニットの依存関係を表示する
$ systemctl list-dependencies ユニット
すべてのユニットを一覧表示する
$ systemctl list-unit-files
すべてのサービスを一覧表示する(--type)
$ systemctl list-unit-files -t service
自動起動される設定のサービスを一覧表示する
$ systemctl list-unit-files -t service  --state=enabled
稼働しているすべてのユニットを一覧表示する
$ systemctl list-units
ユニットをマスクすることで起動禁止状態にする
$ systemctl mask ユニット

$ mask はユニットファイルに /dev/null への シンボリックリンク を作成するため、start などの起動コマンドすら無効になる。enable 無効化とは異なり、手動起動もブロックされる。

マスクを解除する
$ systemctl unmask ユニット
デフォルトのターゲット(起動時に適用される systemd のターゲット)を確認する
$ systemctl get-default
システムのデフォルトのターゲットを変更する
$ systemctl set-default ターゲット

getty

/dev/tty1 ~ /dev/tty6 までの 仮想コンソール のデバイスファイルは、起動時にカーネルによって作成される。

OS が起動すると、SysVinit もしくは systemdgetty (get tty)プロセスを起動する。

getty の役割は以下を行うことにある。

  • デバイスとしての端末を open() する
  • シェルの標準入出力を open() した端末へ接続する
  • ユーザ名の入力を促すログイン用のプロンプトを表示する
  • login プロセスを起動し、ユーザが入力した情報を渡すことでログインを実行する

getty/dev/tty1/dev/tty2、 ... のデバイスファイルを open() によってオープンし、戻り値として取得した ファイルディスクリプタ の接続先を次のように割り当てる。

ファイルディスクリプタ 接続先
00 /dev/tty1(キーボード)
1(標準出力) /dev/tty1(画面出力)
2(標準エラー) /dev/tty1(画面出力)

これにより、シェルは 標準入力/dev/tty1(キーボード)から受け取り、標準出力を /dev/tty1(ディスプレイ)へと流せるようになる。

getty はその後、下記のようなログインプロンプトを表示し、ユーザー名から入力された「ユーザ名」と「パスワード」を login プロセスに渡す。login プロセスは getty によって起動される。

Screenshot 2025-02-19 at 21.42.14.png

login プロセスは、入力された情報による認証が完了すると、ユーザのデフォルトシェル(bash など)起動する。

/proc/cmdline

command line

カーネルが起動される時に、ブートローダから受け取るコマンドライン引数。

カーネルの起動時に渡す引数には以下のような種類がある。

  • ro
    • read only
    • ルートファイルシステムを読み取り専用でマウントする
    • その後、init の中などの適切なタイミングで $ mount -o remout,rw / される
  • root=
    • ルートファイルシステムをマウントするパーティション
    • UUID、LABEL でも指定可能
  • quiet
    • 起動時のカーネルメッセージを最小限に抑える

$ uname

アーキテクチャを確認することができる。

$ grub-install

GRUBをシステムにインストールする
$ sudo grub-install インストール先ディスク
$ sudo grub-install /dev/sda

$ shutdown

シャットダウンする(halt)
$ shutdown -h now
再起動する(reboot)
$ shutdown -r now
21時にシャットダウンする
$ shutdown -h 21:00
予定したシャットダウンをキャンセルする(cancel)
$ shutdown -c

$ dmesg

/var/log/dmesg に保存された、起動時のカーネルのログを確認する。

起動時のカーネルのログを確認する
$ dmesg

/var/log/dmesg の情報は $ dmesg --clear にて明示的に削除することができる(Ubuntu では /var/log/dmesg は作成されない)。

ログを削除する
$ dmesg --clear
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?