第3章 システムの初期化

目次

3.1. ブートストラッププロセスの概要
3.1.1. 1段目: BIOS
3.1.2. 2段目: ブートローダー
3.1.3. 3段目: ミニ Debian システム
3.1.4. 4段目: 通常の Debian システム
3.2. Systemd init
3.2.1. ホスト名
3.2.2. ファイルシステム
3.2.3. ネットワークインターフェースの初期化
3.2.4. カーネルメッセージ
3.2.5. システムメッセージ
3.2.6. System management under systemd
3.2.7. Customizing systemd
3.3. udev システム
3.3.1. カーネルモジュール初期化

Debian システムが以下に起動され設定されるかの知っていることはシステム管理者として賢明です。正確で詳細な情報がインストールされたパッケージのソースや文書中にあるとは言え、我々の大部分にとってはちょっと大変過ぎます。

著者などの過去の知見に基づき Debian システムの要点とそれらの設定の簡単な参考となる概論を提供するように勤めました。Debian システムは動く標的なので、システムの状況が変わっているかもしれません。システムに変更を加える前に、各パッケージの最新文書を参照下さい。

[ヒント] ヒント

bootup(7) describes the system bootup process based on systemd . (Recent Debian)

[ヒント] ヒント

boot(7) describes the system bootup process based on UNIX System V Release 4. (Older Debian)

コンピューターシステムは、電源投入イベントからユーザーに機能の完備したオペレーティングシステム (OS) を提供するまでブートストラッププロセスを数段通過します。

単純化のため、デフォールトのインストールをした典型的な PC プラットフォームに限定し議論します。

典型的なブートストラッププロセスは4段ロケットのようです。各段のロケットは次の段のロケットにシステムのコントロールを引き継ぎます。

もちろん、これらに関して異なる設定をすることはできます。例えば、自分自身で専用カーネルをコンパイルした場合、ミニ Debian システムのステップをスキップできます。自分自身で確認するまでは、あなたのシステムがこの様になっていると決めつけないで下さい。

[注記] 注記

非伝統的 PC プラットフォームの SUN とか Macintosh システム等では、ROM 上の BIOS やディスク上のパーティション (「ディスクパーティション設定」) が非常に異なっているかもしれません。そのような場合にはプラットフォーム特定の文書をどこかで求めて下さい。

BIOS は電源投入イベントが引き起こすブートプロセスの1段目です。CPU のプログラムカウンターが電源投入イベントで初期化され、読出し専用メモリー (ROM) 上にあるBIOS が特定のメモリーアドレスから実行されます。

BIOS はハードウエアーの基本的な初期化 (POST: 電源投入時自己診断) を行い、システムのコントロールをあなたが提供する次のステップにシステムのコントロールを引き継ぎます。BIOS は通常ハードウエアーによって供給されます。

BIOS 初期画面はどのキーを押すと BIOS 設定画面に入って BIOS の挙動を設定できるかを通常表示しています。よく使われるキーは F1 や F2 や F10 や Esc や Ins や Del です。もし BIOS 初期画面が洒落た画像表示で隠されている場合、Esc 等の何らかのキーをおすとこれを無効にできます。こういったキーはハードウエアーに大いに依存します。

BIOS が起動するコードのハードウエアー上の場所や優先順位は BIOS 設定画面から選択できます。典型的には最初に見つかった選択されたデバイス (ハードディスクやフロッピーディスクや CD-ROM 等) の最初の数セクターがメモリー上にロードされこの初期コードが実行されます。この初期コードは次のいずれでもよろしい。

  • ブートローダーコード

  • FreeDOS のような踏み石 OS のカーネルコード

  • この小さな空間に収まればターゲット OS のカーネルコード

典型的にはプライマリハードディスクの指定されたパーティションからシステムが起動されます。伝統的 PC のハードディスクの最初の2セクターにマスターブートレコード (MBR) が含まれます。ブート選択に含まれるディスクのパーティション情報はこの MBR の最後に記録されています。BIOS から実行される最初のブートローダーコードは残りの部分を占めます。

ブートローダーは BIOS によって起動されるブートプロセスの2段目です。それはシステムのカーネルイメージと initrd イメージをメモリーにロードし、それらにコントロールを引き継ぎます。この initrd イメージはルートファイルシステムイメージで、そのサポートは使われるブートローダー次第です。

The Debian system normally uses the Linux kernel as the default system kernel. The initrd image for the current 2.6/3.x Linux kernel is technically the initramfs (initial RAM filesystem) image. The basic initrd image is a compressed cpio archive of files in the root filesystem. The kernel can update microcode very early during boot before loading this basic initrd image. This is facilitated by the combined initrd image which is microcode binary blob in uncompressed cpio format followed by the basic initrd image.

[ヒント] ヒント

You can inspect the content of the initrd image file using lsinitramfs(8) and unmkinitramfs(8) from the initramfs-tools-core package. See more on https://wiki.debian.org/initramfs.

Debian システムのデフォールトインストールでは、GRUB ブートローダーの1段目のコードを PC プラットホームの MBR の中に置きます。多くのブートローダーと設定の選択肢が利用可能です。


[警告] 警告

Do not play with boot loaders without having bootable rescue media (USB memory stick, CD or floppy) created from images in the grub-rescue-pc package. It makes you boot your system even without functioning bootloader on the hard disk.

GRUB Legacy のメニューの設定は "/boot/grub/menu.lst" にあります。例えば、次のような内容です。

title           Debian GNU/Linux
root            (hd0,2)
kernel          /vmlinuz root=/dev/hda3 ro
initrd          /initrd.img

GRUB 2 のメニューの設定は "/boot/grub/grub.cfg" にあります。 "/etc/grub.d/*" の雛形と "/etc/default/grub" の設定から "/usr/sbin/update-grub" を使って自動的に作られます。例えば、次のような内容です。

menuentry "Debian GNU/Linux" {
        set root=(hd0,3)
        linux /vmlinuz root=/dev/hda3
        initrd /initrd.img
}

これらの例で、これらの GRUB パラメーターは次の意味です。


[注記] 注記

GRUB legacy プログラムが使うパーティション値は Linux カーネルやユーティリティーツールが使う値より1つ少ない数字です。GRUB 2 プログラムはこの問題を修正します。

[ヒント] ヒント

UUID (「UUID を使ってパーティションをアクセス」参照下さい) は、"/dev/hda3" のようなファイル名に代わるブロックの特定デバイスを確定するのに使え、例えば "root=UUID=81b289d5-4341-4003-9602-e254a17ac232 ro" です。

[ヒント] ヒント

もし GRUB が使われている場合には、カーネルブートパラメーターは /boot/grub/grub.cfg 中に設定されます。 Debian システム上では、/boot/grub/grub.cfg を直接編集するべきではありません。/etc/default/grub 中の GRUB_CMDLINE_LINUX_DEFAULT の値を編集するべきで、update-grub(8) を実行することで /boot/grub/grub.cfg を更新すべきです。

[ヒント] ヒント

チェインロード (連鎖導入) とよばれる技術を使うと、あるブートローダーから他のブートローダーを起動できます。

"info grub" と grub-install(8) を参照下さい。

ミニ Debian システムはブートローダーによって起動されるブートプロセスの3段目です。メモリー上でルートファイルシステムとともにシステムカーネルを実行します。これはオプションの起動プロセスの準備段階です。

[注記] 注記

"ミニ Debian システム" は著者がこの3段目のブートプロセスを本文書中で記述するために作った言葉です。このシステムは一般に initrd とか initramfs システムと呼ばれています。類似のメモリー上のシステムは Debian インストーラーでも使われています。

The "/init" program is executed as the first program in this root filesystem on the memory. It is a program which initializes the kernel in user space and hands control over to the next stage. This mini-Debian system offers flexibility to the boot process such as adding kernel modules before the main boot process or mounting the root filesystem as an encrypted one.

  • The "/init" program is a shell script program if initramfs was created by initramfs-tools.

    • "break=init" 等をカーネルブートパラメーターとして与えると、本部分のブートプロセスに割り込み root シェルを獲得できます。この他の割り込み条件は "/init" スクリプトを参照下さい。このシェル環境はあなたの機器のハードウエアーを詳細に検査できるだけ十分洗練されています。

    • この機能を削ったミニ Debian システムで利用可能なコマンドは、主に busybox(1) という GNU ツールで提供されます。

  • The "/init" program is a binary systemd program if initramfs was created by dracut.

    • Commands available in this mini-Debian system are stripped down systemd(1) environment.

[注意] 注意

読出しのみのルートファイルシステム上では、mount コマンドには "-n" オプションを使う必要があります。

通常の Debian システムはミニ Debian システムによって起動されるブートプロセスの4段目です。ミニ Debian システムのシステムカーネルはこの環境ででも実行され続けます。ルートファイルシステムはメモリー上から本当にハードディスク上にあるファイルシステムに切り替えられます。

多くのプログラムを起動する主ブートプロセスを行う init プログラムは、PID=1 で最初のプログラムとして実行されます。init プログラムのデフォールトのファイルパスは "/sbin/init" ですが、"init=/path/to/init_program" のようなカーネルブートパラメーターにより変更できます。

デフォルトの init プログラムは変化してきています:

  • squeeze 以前の Debian は、単純な SysV-スタイル init を使用します。

  • wheezy の Debian は、LSB ヘッダーを用いブート順決めブートスクリプトを並列起動をする改良された SysV-スタイル init を使用します。

  • jessie の Debian は、イベントドリブンで並列初期化のために systemd にデフォルトの init を切り替えました。

[ヒント] ヒント

あなたのシステム上の実際の init コマンドは "ps --pid 1 -f" コマンドで確認できます。

[ヒント] ヒント

"/sbin/init" is symlinked to "/lib/systemd/systemd" after Debian jessie.

表3.3 Debian システムののブートユーティリティーのリスト

パッケージ ポプコン サイズ 説明
systemd V:730, I:820 11844 並行処理のためのイベント依存の init(8) デーモン (sysvinit 代替)
systemd-sysv V:713, I:813 114 the manual pages and links needed for systemd to replace sysvinit
systemd-cron V:0, I:1 135 systemd units to provide cron daemon and anacron functionality
init-system-helpers V:720, I:840 129 helper tools for switching between sysvinit and systemd
initscripts V:259, I:626 205 システムの始動と停止のためのスクリプト
sysvinit-core V:13, I:16 225 System-V 的な init(8) ユーティリティー
sysv-rc V:436, I:634 123 System-V 的なランレベル変更メカニズム
sysvinit-utils V:782, I:999 110 System-V 的なユーティリティー (startpar(8)bootlogd(8)、…)
lsb-base V:891, I:999 49 Linux Standard Base 3.2 の init スクリプト機能
insserv V:474, I:621 140 LSB init.d スクリプト依存関係を使いブート順序を整理するツール
uswsusp V:3, I:11 699 Linux が提供するユーザースペースソフトウエアーによるサスペンドを使うためのツール
kexec-tools V:1, I:8 270 kexec(8) リブートのための kexec ツール (ワームリブート)
systemd-bootchart V:0, I:0 123 ブートプロセスのパーフォンマンスアナライザー
bootchart2 V:0, I:1 94 ブートプロセスのパーフォンマンスアナライザー
pybootchartgui V:0, I:1 177 ブートプロセスのアナライザー (可視化)
mingetty V:0, I:3 35 コンソール専用 getty(8)
mgetty V:0, I:1 301 インテリジェントモデム用の代替 getty(8)

[ヒント] ヒント

ブートプロセスを高速化する最新のティップは Debian wiki: BootProcessSpeedup を参照下さい。

This section describes how system is started by the systemd(1) program with PID=1 (i.e., init process).

The systemd init process spawns processes in parallel based on the unit configuration files (see systemd.unit(5)) which are written in declarative style instead of SysV-like procedural style. These are loaded from a set of paths (see systemd-system.conf(5)) as follows:

  • "/lib/systemd/system": OS default configuration files

  • "/etc/systemd/system": system administrator configuration files which override the OS default configuration files

  • "/run/systemd/system": run-time generated configuration files which override the installed configuration files

Their inter-dependencies are specified by the directives "Wants=", "Requires=", "Before=", "After=", … (see "MAPPING OF UNIT PROPERTIES TO THEIR INVERSES" in systemd.unit(5)). The resource controls are also defined (see systemd.resource-control(5)).

The suffix of the unit configuration file encodes their types as:

  • *.service describes the process controlled and supervised by systemd. See systemd.service(5).

  • *.device describes the device exposed in the sysfs(5) as udev(7) device tree. See systemd.device(5).

  • *.mount describes the file system mount point controlled and supervised by systemd. See systemd.mount(5).

  • *.automount describes the file system auto mount point controlled and supervised by systemd. See systemd.automount(5).

  • *.swap describes the swap device or file controlled and supervised by systemd. See systemd.swap(5).

  • *.path describes the path monitored by systemd for path-based activation. See systemd.path(5).

  • *.socket describes the socket controlled and supervised by systemd for socket-based activation. See systemd.socket(5).

  • *.timer describes the timer controlled and supervised by systemd for timer-based activation. See systemd.timer(5).

  • *.slice manages resources with the cgroups(7). See systemd.slice(5).

  • *.scope is created programmatically using the bus interfaces of systemd to manages a set of system processes. See systemd.scope(5).

  • *.target groups other unit configuration files to create the synchronization point during start-up. See systemd.target(5).

Upon system start up (i.e., init), the systemd process tries to start the "/lib/systemd/system/default.target (normally symlinked to "graphical.target"). First, some special target units (see systemd.special(7)) such as "local-fs.target", "swap.target" and "cryptsetup.target" are pulled in to mount the filesystems. Then, other target units are also pulled in by the target unit dependencies. For details, read bootup(7).

systemd offers backward compatibility features. SysV-style boot scripts in "/etc/init.d/rc[0123456S].d/[KS]<name>" are still parsed and telinit(8) is translated into systemd unit activation requests.

[注意] 注意

Emulated runlevel 2 to 4 are all symlinked to the same "multi-user.target".

The mount options of normal disk and network filesystems are set in "/etc/fstab". See fstab(5) and 「マウントオプションによるファイルシステムの最適化」.

The configuration of the encrypted filesystem is set in "/etc/crypttab". See crypttab(5)

The configuration of software RAID with mdadm(8) is set in "/etc/mdadm/mdadm.conf". See mdadm.conf(5).

[警告] 警告

各ブートアップごとに、全てのファイルシステムをマウントした後で、"/tmp" と "/var/lock" と "/var/run" 中の一時ファイルはクリーンされます。

The systemd offers not only init system but also generic system management functionalities such as journal logging, login management, time management, network management. etc..

The systemd(1) is managed by several commands:

  • the systemctl(1) command controls the systemd system and service manager (CLI),

  • the systemsdm(1) command controls the systemd system and service manager (GUI),

  • the journalctl(1) command queries the systemd journal,

  • the loginctl(1) command controls the systemd login manager, and

  • the systemd-analyze(1) analyzes system boot-up performance.

Here are a list of typical systemd management command snippets. For the exact meanings, please read the pertinent manpages.

表3.5 List of typical systemd management command snippets

Operation Type Command snippets
GUI for service manager GUI "systemadm" (systemd-ui package)
List all target unit configuration Unit "systemctl list-units --type=target"
List all service unit configuration Unit "systemctl list-units --type=service"
List all unit configuration types Unit "systemctl list-units --type=help"
List all socket units in memory Unit "systemctl list-sockets"
List all timer units in memory Unit "systemctl list-timers"
Start "$unit" Unit "systemctl start $unit"
Stop "$unit" Unit "systemctl stop $unit"
Reload service-specific configuration Unit "systemctl reload $unit"
Stop and start all "$unit" Unit "systemctl restart $unit"
Start "$unit" and stop all others Unit "systemctl isolate $unit"
Switch to "graphical" (GUI system) Unit "systemctl isolate graphical"
Switch to "multi-user" (CLI system) Unit "systemctl isolate multi-user"
Switch to "rescue" (single user CLI system) Unit "systemctl isolate rescue"
Send kill signal to "$unit" Unit "systemctl kill $unit"
Check if "$unit" service is active Unit "systemctl is-active $unit"
Check if "$unit" service is failed Unit "systemctl is-failed $unit"
Check status of "$unit|$PID|device" Unit "systemctl status $unit|$PID|$device"
Show properties of "$unit|$job" Unit "systemctl show $unit|$job"
Reset failed "$unit" Unit "systemctl reset-failed $unit"
List dependency of all unit services Unit "systemctl list-dependencies --all"
List unit files installed on the system Unit file "systemctl list-unit-files"
Enable "$unit" (add symlink) Unit file "systemctl enable $unit"
Disable "$unit" (remove symlink) Unit file "systemctl disable $unit"
Unmask "$unit" (remove symlink to "/dev/null") Unit file "systemctl unmask $unit"
Mask "$unit" (add symlink to "/dev/null") Unit file "systemctl mask $unit"
Get default-target setting Unit file "systemctl get-default"
Set default-target to "graphical" (GUI system) Unit file "systemctl set-default graphical"
Set default-target to "multi-user" (CLI system) Unit file "systemctl set-default multi-user"
Show job environment Environment "systemctl show-environment"
Set job environment "variable" to "value" Environment "systemctl set-environment variable=value"
Unset job environment "variable" Environment "systemctl unset-environment variable"
Reload all unit files and daemons Lifecycle "systemctl daemon-reload"
Shut down the system System "systemctl poweroff"
Shut down and reboot the system System "systemctl reboot"
Suspend the system System "systemctl suspend"
Hibernate the system System "systemctl hibernate"
View job log of "$unit" Journal "journalctl -u $unit"
View job log of "$unit" ("tail -f" style) Journal "journalctl -u $unit -f"
Show time spent for each initialization steps Analyze "systemd-analyze time"
List of all units by the time to initialize Analyze "systemd-analyze blame"
Load and detect errors in "$unit" file Analyze "systemd-analyze verify $unit"
Track boot process by the cgroups(7) Cgroup "systemd-cgls"
Track boot process by the cgroups(7) Cgroup "ps xawf -eo pid,user,cgroup,args"
Track boot process by the cgroups(7) Cgroup Read sysfs under "/sys/fs/cgroup/systemd/"

Here, "$unit" in the above examples may be a single unit name (suffix such as .service and .target are optional) or, in many cases, multiple unit specifications (shell-style globs "*", "?", "[]" using fnmatch(3) which will be matched against the primary names of all units currently in memory).

System state changing commands in the above examples are typically preceded by the "sudo" to attain the required administrative privilege.

The output of the "systemctl status $unit|$PID|$device" uses color of the dot ("●") to summarize the unit state at a glance.

  • White "●" indicates an "inactive" or "deactivating" state.

  • Red "●" indicates a "failed" or "error" state.

  • Green "●" indicates an "active", "reloading" or "activating" state.

With default installation, many network services (see 6章ネットワークアプリケーション) are started as daemon processes after network.target at boot time by systemd. The "sshd" is no exception. Let's change this to on-demand start of "sshd" as a customization example.

First, disable system installed service unit.

 $ sudo systemctl stop sshd.service
 $ sudo systemctl mask sshd.service

The on-demand socket activation system of the classic Unix services was through the indetd superserver. Under systemd, the equivalent can be enabled by adding *.socket and *.service unit configuration files.

sshd.socket for specifying a socket to listen on

[Unit]
Description=SSH Socket for Per-Connection Servers

[Socket]
ListenStream=22
Accept=yes

[Install]
WantedBy=sockets.target

sshd@.service as the matching service file of sshd.socket

[Unit]
Description=SSH Per-Connection Server

[Service]
ExecStart=-/usr/sbin/sshd -i
StandardInput=socket

Then reload.

 $ sudo systemctl daemon-reload

Linux カーネル 2.6以降 では、udev システムがハードウエアーの自動検出と初期化のメカニズムを提供します (udev(7) 参照下さい)。カーネルが各デバイスを発見すると、udev システムは sysfs ファイルシステム (「procfs と sysfs」参照下さい) からの情報を使いユーザープロセスを起動し、modprobe(8) プログラム (「カーネルモジュール初期化」参照下さい) を使ってそれをサポートする必要なカーネルモジュールをロードし、対応するデバイスノードを作成します。

[ヒント] ヒント

もし "/lib/modules/<kernel-version>/modules.dep" が何らかの理由で depmod(8) によって適正に生成されていなかった場合には、モジュールは udev システムによる期待にそってロードされないかもしれません。これを修正するには、"depmod -a" を実行します。

デバイスノード名は "/etc/udev/rules.d/" の中のファイルによって設定できます。現在のデフォールトのルールは、cd とネットワークデバイス以外は非静的なデバイス名となる動的生成名を作る傾向があります。cd やネットワークデバイスと同様のカスタムルールを追加することで USB メモリースティック等の他のデバイスにも静的なデバイス名を生成出来ます。"Writing udev rules" か "/usr/share/doc/udev/writing_udev_rules/index.html" を参照下さい。

udev システムは少々動くターゲットなので、詳細は他のドキュメントに譲り、ここでは最小限の記述に止めます。

[ヒント] ヒント

"/etc/fstab" 中のマウントルールでは、デバイス名が静的なデバイス名である必要がありません。"/dev/sda" 等のデバイス名ではなく UUID を使ってデバイスをマウントできます。「UUID を使ってパーティションをアクセス」を参照下さい。

modprobe(8) プログラムは、ユーザープロセスからカーネルモジュールを追加や削除することで実行中の Linux カーネルの設定を可能にします。udev システム (「udev システム」参照下さい) は、その起動を自動化しカーネルモジュールの初期化を補助します。

"/etc/modules" ファイル中にリストしてプリロードする必要のある (modules(5) 参照下さい) 次に記すような非ハードウエアーや特殊ハードウエアーのドライバーモジュールがあります。

modprobe(8) プログラムのための設定ファイルは、modprobe.conf(5) で説明されているように "/etc/modprobes.d/" ディレクトリーの下にあります。(あるカーネルモジュールが自動ロードされるのを避けるには、"/etc/modprobes.d/blacklist" ファイル中にブラックリストします。)

depmod(8) プログラムによって生成される "/lib/modules/<version>/modules.dep" ファイルは、modprobe(8) プログラムによって使われるモジュール依存関係を記述します。

[注記] 注記

ブート時に modprobe(8) を使ってのモジュールロードの問題に出会った場合には、"depmod -a" として "modules.dep" を再構築をするとこの様な問題が解消できるかもしれません。

modinfo(8) プログラムは Linux カーネルモジュールに関する情報を表示します。

lsmod(8) プログラムは "/proc/modules" の内容を読みやすい形式にして、どのカーネルモジュールが現在ロードされているかを表示します。

[ヒント] ヒント

あなたのシステム上の正確なハードウエアーを特定します。「ハードウエアーの識別」を参照下さい。

[ヒント] ヒント

ブート時に期待されるハードウエアー機能を有効となるように設定もできます。「ハードウエアー設定」を参照下さい。

[ヒント] ヒント

あなたのデバイスのサポートは、カーネルを再コンパイルすれば追加できます。「カーネル」を参照下さい。