1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
|
---
title: 第12章 FreeBSD の起動のプロセス
part: パートIII. システム管理
prev: books/handbook/config
next: books/handbook/users
showBookMenu: true
weight: 16
path: "/books/handbook/"
---
[[boot]]
= FreeBSD の起動のプロセス
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 12
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/boot/
ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]
ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
[[boot-synopsis]]
== この章では
計算機を起動しオペレーティングシステムをロードするプロセスは、 "ブートストラッププロセス" もしくは "ブート" と呼ばれます。 FreeBSD の起動プロセスを使えば、 システムをスタートするときに起きることをかなり柔軟にカスタマイズできます。 同じ計算機にインストールされた別のオペレーティングシステムを選択することもできますし、 同じオペレーティングシステムの異なるバージョンを選択することも、 インストールされた別のカーネルを選択することさえできます。
この章では、指定できる設定オプションついて詳しく説明します。 FreeBSD カーネルがスタートし、デバイスを検出し、 man:init[8] を起動するまでに起きることすべてを含む FreeBSD の起動プロセスのカスタマイズ方法について説明します。 これは、起動メッセージのテキストの色が、 明るい白から灰色に変わるまでに起きています。
この章を読むと、以下のことが分かります。
* FreeBSD のブートストラップシステムの構成およびそれらが互いにどう関係しているのか
* 起動プロセスを制御するために FreeBSD のブートストラップの各要素に付加できるオプション
* device hints の基本的な記述方法
* シングルユーザもしくはマルチユーザモードでの起動方法、 および FreeBSD システムのシャットダウンの方法
[NOTE]
====
この章では Intel x86 および amd64 システム上で動作する FreeBSD の起動プロセスだけを扱います。
====
[[boot-introduction]]
== FreeBSD の起動プロセス
計算機の電源を入れ、オペレーティングシステムをスタートさせるのには、 おもしろいジレンマがあります。定義により、 計算機は、オペレーティングシステムが起動するまでは、 ディスクからプログラムを動かすことも含めて、 何をどうすればよいかまったく知りません。 計算機はオペレーティングシステムなしにディスクからプログラムを実行することができず、 オペレーティングシステムのプログラムがディスク上にあるのなら、 どうやってオペレーティングシステムを起動するのでしょうか?
この問題はほらふき男爵の冒険 という本の中に書かれている問題ととてもよく似ています。 登場人物がマンホールの下に半分落っこちて、 靴紐 (ブートストラップ) をつかんで自分を引っぱり、持ち上げるのです。 計算機の黎明期には、_ブートストラップ_ という用語でオペレーティングシステムをロードする機構のことを指していました。 いまはこれを縮めて "ブート (起動)" と言います。
x86 ハードウェアでは、基本入出力システム (Basic Input/Output System: BIOS) にオペレーティングシステムをロードする責任があります。 BIOS はハードディスク上のマスターブートレコード (Master Boot Record: MBR) を探します。 MBR はハードディスク上の特定の場所になければなりません。 BIOS には MBR をロードし起動するのに十分な知識があり、 オペレーティングシステムをロードするために必要な作業の残りは、 場合によっては BIOS の助けを得た上で MBR が実行できることを仮定しています。
[NOTE]
====
FreeBSD は古い標準の MBR、 または新しい GUID Partition Table (GPT) から起動できます。 GPT パーティションは、Unified Extensible Firmware Interface (UEFI) に対応したコンピュータで良く用いられます。 しかしながら、FreeBSD はレガシーな BIOS にのみに対応したコンピュータからも、man:gptboot[8] により、 GPT パーティションから起動できます。 UEFI からの直接の起動への対応は進行中です。
====
MBR 内部のコードは、 一般的に_ブートマネージャ_と呼ばれます。 とりわけユーザとの対話がある場合にそう呼ばれます。 通常ブートマネージャのもっと多くのコードが、 ディスクの最初のトラック、またはファイルシステム上におかれます。 ブートマネージャの例としては、Boot Easy とも呼ばれる FreeBSD 標準のブートマネージャの boot0、 多くの Linux(R) ディストリビューションが採用している Grub 等があります。
ディスク上にインストールされているオペレーティングシステムが 1 つの時は、MBR はディスク上の最初の起動可能な (アクティブな) スライスを探し、 そのスライスにあるコードを起動してオペレーティングシステムの残りをロードします。 ディスク上に複数のオペレーティングシステムが存在しているのなら、 複数のオペレーティングシステムの一覧を表示できて、 起動するオペレーティングシステムを選択できるような、 別のブートマネージャをインストールすることもできます。
FreeBSD のブートストラップシステムの残りは 3 段階に分かれます。 第 1 ステージは、 計算機を特定の状態にするために必要なことだけを知っていて、 第 2 ステージを起動します。 第 2 ステージでは、第 3 ステージを起動する前に、 もう少しできることがあります。 第 3 ステージでオペレーティングシステムのロード作業を完了します。 起動作業が 3 段階に分かれているのは、 MBR がステージ 1 とステージ 2 で実行できるプログラムのサイズに制限を課しているからです。 これらの作業をつなぎ合わせることによって、 FreeBSD はより柔軟なローダ (loader) を提供しているのです。
その後カーネルが起動し、デバイスの検出と初期化を開始します。 そしてカーネルの起動が終わると、制御はユーザープロセスの man:init[8] へ移されます。man:init[8] はディスクが利用可能であることを確認し、 ファイルシステムのマウント、 ネットワークで利用するネットワークカードのセットアップ、 そしてブート時に起動されるように設定されたプロセスの起動、 といったユーザーレベルでのリソース (資源) 設定を行ないます。
この章では、これらのステージについてより詳細に、また、FreeBSD ブートプロセスにおける対話的な設定方法について説明します。
[[boot-boot0]]
=== ブートマネージャ
MBR のブートマネージャのコードは起動プロセスの_第 0 ステージ_と呼ばれることがあります。 デフォルトでは、FreeBSD は boot0 を使います。
FreeBSD のインストーラがインストールする MBR は、 [.filename]#/boot/boot0# を基にしています。 boot0 のサイズと機能は、 スライステーブルおよび MBR 末尾の識別子 `0x55AA` のため、 446 バイトの大きさに制限されます。 もし、boot0 と複数のオペレーティングシステムをインストールした場合、 起動時に以下のようなメッセージが表示されます。
[[boot-boot0-example]]
.[.filename]#boot0# のスクリーンショット
[example]
====
[source,shell]
....
F1 Win
F2 FreeBSD
Default: F2
....
====
他のオペレーティングシステムは、 FreeBSD の後にインストールを行うと、既存の MBR を上書きしてしまいます。 もしそうなってしまったら、 もしくは既存の MBR を FreeBSD の MBR で置き換えるには、 次のコマンドを使ってください。
[source,shell]
....
# fdisk -B -b /boot/boot0 device
....
_device_ は起動するデバイス名で、 たとえば 1 番目の IDE ディスクは [.filename]#ad0#、2 番目の IDE コントローラに接続されている 1 番目の IDE ディスクは [.filename]#ad2#、 1 番目の SCSI ディスクは [.filename]#da0# などとなります。 MBR の設定をカスタマイズしたい場合は、 man:boot0cfg[8] を参照してください。
[[boot-boot1]]
=== 起動ステージ 1 と起動ステージ 2
概念上、第 1 ステージと第 2 ステージはハードディスクの同じ領域上の同一のプログラムの部分部分です。 スペースの制約のため 2 つに分割されていますが、 いつも一緒にインストールされます。 FreeBSD のインストーラまたは `bsdlabel` は、 両者を 1 つにまとめた [.filename]#/boot/boot# をコピーします。
これらの 2 つのステージは、ファイルシステムの外部、 起動スライスの最初のトラックに置かれ、 先頭が最初のセクタにきます。 boot0 またはその他のブートマネージャは、 起動プロセスを続けるために必要なプログラムがそこにあると想定しています。
最初のステージの [.filename]#boot1# は、 512 バイトの大きさでなければならないという制限があるので、 非常に単純なプログラムです。 このプログラムは [.filename]#boot2# を検索して実行するため、そのスライスの情報を保持する FreeBSD の _BSD ラベル_ に関する最低限の情報だけを持っています。
次のステージの [.filename]#boot2# はもう少し高機能です。 これは FreeBSD のファイルシステム上でファイルを見つける機能を持ちます。 実行するカーネルやローダを指定するための簡単なインタフェースを提供します。 [.filename]#boot2# により起動される loader はさらに高機能で、 起動設定が行なえる手段を提供します。 ステージ 2 で起動プロセス中断した時には、 次のようながインタラクティブなが画面が表示されます。
[[boot-boot2-example]]
.[.filename]#boot2# のスクリーンショット
[example]
====
[source,shell]
....
>> FreeBSD/i386 BOOT
Default: 0:ad(0,a)/boot/loader
boot:
....
====
インストールされた [.filename]#boot1# と [.filename]#boot2# を変更するには、 `bsdlabel` を使ってください。 以下の例では、_diskslice_ は起動するディスクとスライスで、たとえば最初の IDE ディスクの 1 番目のスライスは [.filename]#ad0s1# となります。
[source,shell]
....
# bsdlabel -B diskslice
....
[WARNING]
====
[.filename]#ad0# のようにディスク名だけを指定すると、 `bsdlabel` は、スライスを持たない "危険な専用モード"を作成してしまいます。 これはおそらく、あなたが望んでいることではないでしょうから、 kbd:[Return] キーを押す前に、 _diskslice_ の部分を二重にチェックしてください。
====
[[boot-loader]]
=== 起動ステージ 3
loader は三段階の起動プロセスの最終段階です。 これは通常、ファイルシステム上の [.filename]#/boot/loader# として存在しています。
loader は、 よりさまざまなコマンド群をサポートした強力なインタプリタによって提供される組み込みコマンド群を利用することで、 インタラクティブな設定手段となるように設計されています。
loader は初期化の際にコンソールとディスクの検出を行ない、 どのディスクから起動しているかを調べます。 そして必要な変数を設定してからインタプリタを起動し、 スクリプトからコマンドを送ったり手でコマンドを入力したりできます。
loader は次に [.filename]#/boot/loader.rc# を読み込み、通常、変数の標準値を定義した [.filename]#/boot/defaults/loader.conf# と、そのコンピュータにローカルに変数を定義した [.filename]#/boot/loader.conf# を読み込みます。 [.filename]#loader.rc# はそれらの変数にもとづき、 選択されたモジュールとカーネルをロードします。
loader は最後に、 標準設定で 10 秒のキー入力待ち時間を用意し、 入力がなければカーネルを起動します。 入力があった場合、コマンド群が使えるプロンプトが表示され、 ユーザは変数を調整したり、すべてのモジュールをアンロードしたり、 モジュールをロードしたりすることができます。 その後、最終的な起動や再起動へ移行します。 <<boot-loader-commands>>では、 もっともよく使われる loader のコマンドをまとめています。 利用可能なコマンドをすべて知りたい場合には、 man:loader[8] を参照してください。
[[boot-loader-commands]]
.ローダの組み込みコマンド
[cols="1,1", frame="none", options="header"]
|===
| 変数
| 説明
|autoboot _seconds_
|_seconds_ で与えられた時間内に入力がなければ、 カーネルの起動へと進みます。 カウントダウンを表示します。標準設定では 10 秒間です。
|boot `[__-options__] [__kernelname]__`
|すぐにカーネルの起動へ進みます。 オプション、カーネル名が指定されている場合は、 それらが使われます。 _unload_ を実行後、 カーネル名をコマンドラインから指定することができます。 _unload_ を実行しないと、 一度読み込まれたカーネルが使われます。 _kernelname_ でパスが指定されていない時には、 _/boot/kernel_ および _/boot/modules_ から調べられます。
|boot-conf
|すべてのモジュールの設定を、 起動時と同じように指定された変数 (最も多いのは `kernel`) にもとづいて自動的に行ないます。 このコマンドは、変数を変更する前に、 最初に `unload` を行なった場合にのみ有効に働きます。
|help `[__topic__]`
|[.filename]#/boot/loader.help# を読み込み、ヘルプメッセージを表示します。 topic に `index` が指定された場合、 利用可能な topic の一覧を表示します。
|include _filename_ ...
|指定されたファイルを読み込み、行単位で解釈します。 エラーが発生した場合、 `include` の実行は直ちに停止します。
|load `[-t __type__]` _filename_
|指定されたファイル名のカーネル、 カーネルモジュール、あるいは type に指定された種類のファイルをロードします。 _filename_ 以降に指定された引数はファイルへと渡されます。 _filename_ でパスが指定されていない時には、 _/boot/kernel_ および _/boot/modules_ から調べられます。
|ls [-l] `[__path__]`
|指定された _path_ にあるファイルを表示します。 _path_ が指定されていなければ、ルートディレクトリを表示します。 `-l` が指定されていればファイルサイズも表示されます。
|lsdev [-v]
|モジュールがロード可能なすべてのデバイスを表示します。 もし `-v` が指定されていれば、 より詳細な出力がされます。
|lsmod [-v]
|ロード済みのモジュールを表示します。 `-v` が指定されていれば、 より詳細な内容が出力されます。
|more _filename_
|`LINES` 行を表示するごとに停止しながら指定されたファイルを表示します。
|reboot
|すぐにシステムを再起動します。
|set _variable_, set _variable_=_value_
|ローダの環境変数を設定します。
|unload
|すべてのロード済みモジュールを削除します。
|===
次にあげるのは、ローダの実践的な使用例です。 普段使っているカーネルをシングルユーザモードで起動します。
[source,shell]
....
boot -s
....
普段使っているカーネルとモジュールをアンロードし、 古いもしくは別のカーネルをロードするには、 以下のように実行してください。
[source,shell]
....
unload
load /path/to/kernelfile
....
インストール時のデフォルトカーネルを指定するには、完全修飾の [.filename]#/boot/GENERIC/kernel# を使ってください。
また、システムをアップグレードしたり、 もしくはカスタムカーネルを設定した場合に、 直前にインストールされていたカーネルは、 [.filename]#/boot/kernel.old/kernel# で指定できます。
普段のカーネルで使っているモジュールを指定したカーネルでロードする場合は、 次のようにします。
この場合は、完全修飾名を使う必要はありません。
[source,shell]
....
unload
set kernel="mykernel"
boot-conf
....
カーネルの自動設定スクリプトをロードします。
[source,shell]
....
load -t userconfig_script /boot/kernel.conf
....
[[boot-init]]
=== 最終ステージ
カーネルがデフォルトの loader もしくは loader を迂回して boot2 によって読み込まれると、 起動フラグが調べられ、それに応じて動作が調整されます。<<boot-kernel>> には、 良く使われる起動フラグがまとめられています。 他の起動フラグの詳細については、 man:boot[8] を参照してください。
[[boot-kernel]]
.起動時のカーネルオプション
[cols="1,1", frame="none", options="header"]
|===
| オプション
| 説明
|`-a`
|カーネル初期化中に、 ルートファイルシステムとしてマウントするデバイスを尋ねます。
|`-C`
|CDROM からルートファイルシステムを起動します。
|`-s`
|シングルユーザモードで起動します。
|`-v`
|カーネル起動時に、より詳細な情報を表示します。
|===
カーネルの起動が完了すると、man:init[8] というユーザプロセスに制御が移されます。 これは [.filename]#/sbin/init#、 もしくは `loader` の `init_path` 変数で指定される場所にあります。 これは起動プロセスの最終ステージです。
起動シーケンスでは、 システム上で利用できるファイルシステムの一慣性を確認します。 もし UFS ファイルシステムにに問題があって `fsck` が不一致を修復できなければ、 管理者が問題を直接解決できるように、init はシステムをシングルユーザモードへと移行させます。 問題がなければ、システムはマルチユーザモードに移行します。
[[boot-singleuser]]
==== シングルユーザモード
このモードには、ユーザが起動時に `-s` を指定した場合、あるいは loader で `boot_single` 変数を設定することによって移行します。 マルチユーザモードから `shutdown now` を呼び出すことでもこのモードに移行できます。 シングルユーザモードは、以下のメッセージで開始します。
[.programlisting]
....
Enter full pathname of shell or RETURN for /bin/sh:
....
ユーザが kbd:[Enter] を入力すると、 システムは Bourne シェルを起動します。 別のシェルを使うには、シェルのフルパスを入力してください。
シングルユーザモードは、 通常ファイルシステムの一貫性に問題があって起動できないシステムを修復したり、 起動設定ファイルの間違いを修正するために使われます。 また、`root` パスワードがわからなくなった場合に、 リセットするために使うことも出来ます。 シングルユーザモードのプロンプトは、 ローカルファイルシステムおよび設定ファイルへのアクセスを与えてくれますが、 ネットワーク接続は出来ません。
シングルユーザモードは、システムの修復には有用ですが、 システムが物理的に安全な場所になければ、 セキュリティのリスクがもたらされます。 デフォルトでは、システムに物理的にアクセス可能なユーザは、 シングルユーザモードで起動後はシステムをすべてコントロールできます。
[.filename]#/etc/ttys# でシステムの `console` が `insecure` に設定されている場合、 システムはシングルユーザモードに移行する前に `root` のパスワードを入力するように求めます。 `root` パスワードがわからなくなった場合のリセット機能が無効になっている間は、 セキュリティ対策が必要となります。
[[boot-insecure-console]]
.[.filename]#/etc/ttys# の insecure コンソール
[example]
====
[.programlisting]
....
# name getty type status comments
#
# If console is marked "insecure", then init will ask for the root password
# when going to single-user mode.
console none unknown off insecure
....
====
`insecure` コンソールとは、 コンソールが物理的に安全でない (insecure) と考えられるため、 `root` のパスワードを知る人だけがシングルユーザモードを使えるという意味です。
[[boot-multiuser]]
==== マルチユーザモード
init がファイルシステムが正常であると判断するか、 ユーザがシングルユーザモードでのコマンドを終了し、 `exit` を入力してシングルユーザモードを終了すると、 システムはマルチユーザモードへ移行し、 システムのリソースの設定を開始します。
リソース設定システムはデフォルト設定を [.filename]#/etc/defaults/rc.conf# から、 また、システム独自の細かな設定を [.filename]#/etc/rc.conf# から読み込みます。 そして [.filename]#/etc/fstab# に記述されるシステムファイルシステムをマウントします。 その後、ネットワークサービス、さまざまなシステムデーモン、 そして最後に、ローカルにインストールされた package の起動スクリプトを実行します。
リソース設定システムについてもっと知りたい場合には、 man:rc[8] を参照してください。また、[.filename]#/etc/rc.d# にあるスクリプトを実行してみてください。
[[device-hints]]
== Device Hints
システムの最初のスタートアップ時に、man:loader[8] は man:device.hints[5] を読み込みます。 このファイルにはカーネル起動の環境変数が格納されており、 これらの環境変数は "device hints" と呼ばれることがあります。デバイスドライバは、 デバイスを設定するために "device hints" を使用します。
<<boot-loader>> で説明されているように device hints はステージ 3 ブートローダプロンプトでも設定できます。 変数は `set` を用いて追加したり、 `unset` を用いて削除できます。 `show` を用いて一覧を見ることもできます。 [.filename]#/boot/device.hints# に設定されている変数は、 上書きすることもできます。 ブートローダで設定した device hints の効果は一時的なものなので、 次回起動するときには無効になります。
システムが起動すると、man:kenv[1] コマンドですべてのカーネル環境変数をダンプすることができます。
[.filename]#/boot/device.hints# は 1 行につき一つの変数を設定でき、行頭の "#" はその行がコメントであることを示しています。 書式は次の通りです。
[source,shell]
....
hint.driver.unit.keyword="value"
....
ステージ 3 ブートローダ で設定するときの書式は次の通りです。
[source,shell]
....
set hint.driver.unit.keyword=value
....
ここで、`driver` はデバイスドライバの名前、 `unit` はデバイスドライバのユニット番号、 `keyword` はヒントキーワードです。 キーワードは以下のようなオプションです。
* `at`: デバイスがどのバスに接続されているか指定します。
* `port`: 使用する I/O ポートの開始アドレスを指定します。
* `irq`: 使用する IRQ を指定します。
* `drq`: 使用する DMA チャネルを指定します。
* `maddr`: 使用する物理メモリアドレスを指定します。
* `flags`: デバイスに対してさまざまなフラグを設定します。
* `disabled`: `1` が設定されていると、そのデバイスは無効になります。
デバイスドライバはこのリスト以外の変数を設定できるかもしれませんし、 このリスト以外の変数を必要とするかもしれないので、 ドライバのマニュアルを読むことをおすすめします。 より多くの情報を知りたければ、man:device.hints[5], man:kenv[1], man:loader.conf[5] および man:loader[8] を参照してください。
[[boot-shutdown]]
== シャットダウン動作
man:shutdown[8] を用いてシステムを意図的にシャットダウンした場合、 man:init[8] は [.filename]#/etc/rc.shutdown# というスクリプトの実行を試みます。 そして、すべてのプロセスへ `TERM` シグナルを送り、続いてうまく終了できなかったプロセスへ `KILL` シグナルを送ります。
電源管理機能を持ったシステムで稼働している FreeBSD では `shutdown -p now` によって、 直ちに電源を落とすことができます。FreeBSD システムを再起動するには、 `shutdown -r now` を実行してください。 man:shutdown[8] を実行するには、 `root` か、`operator` のメンバでなければなりません。man:halt[8] や man:reboot[8] を利用することもできます。 より多くの情報を得るために、それらのマニュアルページや man:shutdown[8] を参照してください。
グループのメンバを変更するには、 crossref:users[users-synopsis,「この章では」] を参照してください。
[NOTE]
====
電源管理機能には man:acpi[4] がモジュールとして読み込まれるか、 カスタムカーネルにコンパイルされて静的に組み込まれている必要があります。
====
|