8
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?

はじめに

PCの電源を入れてからログイン画面が出るまで、何が起きてるか知ってる?

FreeBSDのブートプロセスを完全に理解しよう。

ブートプロセス全体像

┌─────────────────────────────────────────────────────────────┐
│                  FreeBSD Boot Process                        │
│                                                              │
│  1. BIOS/UEFI                                               │
│       ↓                                                      │
│  2. Boot Manager (boot0 / UEFI Boot Manager)                │
│       ↓                                                      │
│  3. Boot Loader (boot2 / loader.efi)                        │
│       ↓                                                      │
│  4. Kernel (kernel)                                         │
│       ↓                                                      │
│  5. Init (/sbin/init)                                       │
│       ↓                                                      │
│  6. rc scripts (/etc/rc.*)                                  │
│       ↓                                                      │
│  7. Login (getty → login)                                   │
└─────────────────────────────────────────────────────────────┘

1. BIOS/UEFI

BIOS(レガシー)

┌─────────────────────────────────────────────────────────────┐
│  MBR (Master Boot Record) - 512 bytes                       │
│  ┌────────────────────────────────────────┬──────────────┐  │
│  │        Boot Code (446 bytes)           │ Part Table   │  │
│  │        boot0                           │ (64 bytes)   │  │
│  └────────────────────────────────────────┴──────────────┘  │
│                                              │ 0x55AA (2)│  │
└─────────────────────────────────────────────────────────────┘

BIOSはMBRの先頭446バイトを実行する。

UEFI

EFI System Partition (ESP)
/EFI/
└── BOOT/
    └── BOOTx64.efi  ← UEFIが実行
/EFI/
└── FreeBSD/
    └── loader.efi   ← FreeBSDブートローダー

UEFIは直接EFIアプリケーション(.efi)を実行できる。

2. Boot Manager (boot0)

BIOS環境

# MBRにboot0をインストール
gpart bootcode -b /boot/boot0 ada0

boot0の画面:

F1 FreeBSD
F2 Windows
F5 Chainload Drive 1

Default: F1

複数OS選択が可能。

UEFI環境

UEFIのブートマネージャーが直接OS選択を担当。

# EFI変数を確認
efibootmgr -v
# Boot0001* FreeBSD   HD(1,GPT,...)/File(\EFI\FREEBSD\LOADER.EFI)
# Boot0002* Windows   HD(2,GPT,...)/File(\EFI\Microsoft\Boot\bootmgfw.efi)

3. Boot Loader

BIOS: boot2 → loader

┌─────────────────────────────────────────────────────────────┐
│  パーティションブートセクタ                                  │
│  ┌──────────────┐                                           │
│  │    boot1     │ (512 bytes) UFS/ZFSを認識                 │
│  └──────────────┘                                           │
│          ↓                                                   │
│  ┌──────────────┐                                           │
│  │    boot2     │ ファイルシステムから/boot/loaderを読む    │
│  └──────────────┘                                           │
│          ↓                                                   │
│  ┌──────────────┐                                           │
│  │   loader     │ フル機能のブートローダー                  │
│  └──────────────┘                                           │
└─────────────────────────────────────────────────────────────┘

UEFI: loader.efi

ls /boot/efi/EFI/FreeBSD/
# loader.efi

loaderの機能

 /boot/loader.conf (press Enter for defaults)
      or any other key to proceed to loader prompt:

 ____  ____  ____  ____  ____    ____
||F ||||r ||||e ||||e ||||B ||||S ||
||__||||__||||__||||__||||__||||D ||
|/__\||/__\||/__\||/__\||/__\||/__\|

 Welcome to FreeBSD!

 1. Boot Multi user [Enter]
 2. Boot Single user
 3. Escape to loader prompt
 4. Reboot
 5. Kernel: kernel (1 of 2)

 Options:
 6. Configure Boot Options...

loaderプロンプト

Type '?' for a list of commands, 'help' for more detailed help.
OK ?
Available commands:
  autoboot      bcachestat    boot          chain
  efi-autoresectconsole      echo          heap
  help          include       load          lsdev
  ...

OK show
...

OK set kern.hz=1000
OK boot

4. カーネル起動

loader.conf

# /boot/loader.conf
kernel="kernel"               # デフォルトカーネル
# kernel="kernel.old"         # 古いカーネル

# モジュールの自動ロード
if_em_load="YES"
zfs_load="YES"
dtrace_load="YES"

# カーネルパラメータ
kern.hz="1000"
debug.debugger_on_panic="1"

# コンソール設定
boot_serial="YES"
comconsole_speed="115200"

カーネルの初期化フロー

┌─────────────────────────────────────────────────────────────┐
│                Kernel Initialization                         │
│                                                              │
│  1. locore.S (アセンブリ)                                   │
│     - CPU初期化、ページテーブル設定                         │
│         ↓                                                    │
│  2. init_main.c :: mi_startup()                             │
│     - SYSINIT() で登録された初期化関数を順番に実行          │
│         ↓                                                    │
│  3. 各サブシステム初期化                                    │
│     - SI_SUB_COPYRIGHT: 著作権表示                          │
│     - SI_SUB_VM: 仮想メモリ                                 │
│     - SI_SUB_KMEM: カーネルメモリアロケータ                 │
│     - SI_SUB_CPU: CPU                                       │
│     - SI_SUB_DEVFS: デバイスファイルシステム                │
│     - SI_SUB_DRIVERS: デバイスドライバ                      │
│     - SI_SUB_CONFIGURE: autoconfiguration                   │
│         ↓                                                    │
│  4. SI_SUB_RUN_SCHEDULER: スケジューラ開始                  │
│         ↓                                                    │
│  5. create_init() → /sbin/init を exec                      │
└─────────────────────────────────────────────────────────────┘

起動メッセージ

FreeBSD 14.2-RELEASE #0 releng/14.2-n269506-c8918d6c7412: Fri Nov  8 11:24:11 UTC 2024
    root@releng2.nyi.freebsd.org:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
FreeBSD clance program.
CPU: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz (2400.10-MHz K8-class CPU)
  Origin="GenuineIntel"  Id=0x406f1  Family=0x6  Model=0x4f  Stepping=1
  ...
real memory  = 68719476736 (65536 MB)
avail memory = 66430898176 (63353 MB)
...
Mounting from zfs:zroot/ROOT/default...
...

5. Init

カーネルが最初に起動するユーザープロセスは/sbin/init(PID 1)。

ps aux | head -2
# USER  PID  %CPU %MEM    VSZ   RSS TT  STAT STARTED    TIME COMMAND
# root    1   0.0  0.0  10852  1388  -  ILs  Dec01   0:00.06 /sbin/init

initの役割

  1. /etc/rcスクリプトを実行
  2. シングルユーザーモードかマルチユーザーモードを判断
  3. マルチユーザーモードなら/etc/ttysに従ってgettyを起動
  4. シグナルを監視(再起動など)

6. rc スクリプト

/etc/rc

#!/bin/sh
# $FreeBSD$

# System startup script run by init(8) on autoboot
# or after single-user.

stty status '^T'
trap : 2
trap "echo 'Boot interrupted'; exit 1" 3

HOME=/
PATH=/sbin:/bin:/usr/sbin:/usr/bin
export HOME PATH

. /etc/rc.subr
load_rc_config ''

# ... 続く

起動順序

┌─────────────────────────────────────────────────────────────┐
│                 rc Script Execution                          │
│                                                              │
│  /etc/rc                                                    │
│      ↓                                                       │
│  /etc/rc.d/ (ベースシステムのスクリプト)                    │
│    REQUIRE/BEFORE で依存関係を解決して順番に実行            │
│      ↓                                                       │
│  /usr/local/etc/rc.d/ (pkg でインストールされたもの)        │
│      ↓                                                       │
│  /etc/rc.local (あれば)                                     │
└─────────────────────────────────────────────────────────────┘

rcスクリプトの例

cat /etc/rc.d/sshd
#!/bin/sh
#
# PROVIDE: sshd
# REQUIRE: LOGIN FILESYSTEMS
# KEYWORD: shutdown
#

. /etc/rc.subr

name="sshd"
rcvar="sshd_enable"
command="/usr/sbin/sshd"
keygen_cmd="sshd_keygen"
start_precmd="sshd_precmd"
reload_precmd="sshd_configtest"
restart_precmd="sshd_configtest"
...

PROVIDE/REQUIRE/BEFOREで依存関係を定義。

rcの操作

# サービス一覧
service -l

# 有効なサービス一覧
service -e

# サービス制御
service sshd start
service sshd stop
service sshd restart
service sshd status

# 自動起動設定
sysrc sshd_enable="YES"

7. Login (getty → login)

/etc/ttys

cat /etc/ttys
# name  getty                           type    status  comments
#
console none                            unknown off     secure
#
ttyv0   "/usr/libexec/getty Pc"         xterm   onifexists secure
ttyv1   "/usr/libexec/getty Pc"         xterm   onifexists secure
ttyv2   "/usr/libexec/getty Pc"         xterm   onifexists secure
...
ttyu0   "/usr/libexec/getty 3wire"      vt100   onifconsole secure

ログインの流れ

init
  ↓ fork
getty (ttyv0)
  ↓ login: プロンプトを表示
  ↓ ユーザー名入力
exec login
  ↓ Password: プロンプトを表示
  ↓ 認証成功
exec shell (/bin/sh 等)

ブートの問題解決

シングルユーザーモードで起動

ブートメニューで "2. Boot Single user" を選択。

Enter full pathname of shell or RETURN for /bin/sh:
# (Enter)
# mount -u /
# mount -a
# (修復作業)
# exit

ブートローダープロンプト

OK boot -s          # シングルユーザー
OK boot kernel.old  # 古いカーネルで起動
OK unload           # 全モジュールをアンロード
OK load kernel      # カーネルをロード
OK boot             # 起動

起動しない時のチェックリスト

  1. カーネルパニック: kernel.oldで起動
  2. fsckエラー: シングルユーザーでfsck -y
  3. rc.confのミス: シングルユーザーで修正
  4. デバイスが見つからない: loader.confでモジュールをロード

まとめ

FreeBSDのブートプロセス:

  1. BIOS/UEFI: ハードウェア初期化
  2. boot0/EFI: ブートマネージャー
  3. loader: 柔軟なブートローダー
  4. kernel: OS本体
  5. init: 最初のプロセス
  6. rc: サービス起動
  7. getty/login: ユーザーログイン

loader.confとrc.confを理解すれば、ブートのカスタマイズは自由自在

この記事が役に立ったら、いいね・ストックしてもらえると嬉しいです!

8
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
8
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?