サーバーが起動の途中で止まった
どこまで進んだか見当を付けたいけど、起動の流れがよう分からん
【疑問】電源を入れてからログイン画面まで何が起きてるん?BIOS・UEFI・ブートローダ・カーネル・initramfs・init【LPICレベル1】
前提のおさらい。カーネルは /proc と /sys で機器やドライバの情報を見せていて、ドライバの多くはモジュールとして読み込まれる
>>1
大きく分けるとこの順
1. ファームウェア(BIOS か UEFI)が機器を調べて、起動するディスクを選ぶ
2. ブートローダ(GRUB など)がカーネルと initramfs をメモリに読み込む
3. カーネルが動き出して、initramfs の中のドライバで本物のルートファイルシステムをマウントする
4. 最初のプロセス init(今は多くが systemd)がサービスを順に起動する
>>3
BIOS と UEFI で違うのはどこ?
>>4
BIOS はディスクの先頭の512バイト(MBR)にあるブートローダの最初の部分を読み込んで動かす。UEFI は ESP(EFI システムパーティション、FAT で作る)の中の .efi ファイルを動かして、どれを動かすかはファームウェアの設定に登録しておく
>>5
MBR の512バイトの内訳
起動用のコード446バイト、パーティションテーブル64バイト(16バイト × 4つ)、最後の2バイトが印(55 AA)
>>3
initramfs は何のためにあるん?
>>7
ルートファイルシステムを読むためのドライバ(ディスクのコントローラや LVM・暗号化など)がモジュールになってると、それを読み込むまでルートが読めない。そこで、最小限のドライバと道具を入れた小さいファイルシステムを先にメモリに展開して使う
>>3
カーネルに起動のオプションを渡すのは?
>>9
カーネルパラメータ。ブートローダのメニューで足すか、設定ファイルに書く。今のものは /proc/cmdline で見られる
試したら console=ttyS0 root=/dev/vda … rw のように、コンソールとルートの場所が入ってたsingle や 1 でシングルユーザー、systemd.unit=rescue.target で systemd のレスキュー、init=/bin/bash で init の代わりに bash
>>1
起動のときのメッセージを後から見るには?
>>11dmesg でカーネルのメッセージ(リングバッファ)。-T で時刻を読める形に、-l err でエラーだけ、-w で新しいものを待って出し続ける
>>12
長く動いてたマシンで dmesg を見たら、最初の行はもう起動のずっと後のものやった。リングバッファは一杯になると古いものから上書きされるから、起動直後のメッセージは消えてることがある
>>13
systemd の環境なら journalctl -b でこの起動からのログ、journalctl -b -1 で1つ前の起動のログ。ジャーナルを保存してない環境では No journal files were found と出て何も見られへんかったから、/var/log/ の下のファイルを見る
>>3
init が SysVinit か systemd かで、4番目の中身が変わるんやな
>>15
そう。/sbin/init は Debian 13 では ../lib/systemd/systemd へのリンクやった。古い仕組みの SysVinit や Upstart では別のプログラムになる
>>3
ファームウェア → ブートローダ → カーネルと initramfs → init。止まった場所の見当はこれで付けられる
管理人のひとこと
- 起動の順:ファームウェア(BIOS・UEFI)→ ブートローダ(GRUB など)→ カーネルと initramfs → init(systemd・SysVinit・Upstart)。
- BIOS は MBR(512バイト:起動コード446、パーティションテーブル 16×4=64、印2)のコードを動かす。UEFI は ESP(FAT)の .efi ファイルを動かす。
- initramfs はルートファイルシステムを読むためのドライバと道具を入れた、メモリ上の小さいファイルシステム。
- カーネルパラメータは /proc/cmdline で確認。
single・1、systemd.unit=rescue.target、init=/bin/bashなど。 - 起動のログ:
dmesg(リングバッファなので古いものは消える。-T・-l・-w)、journalctl -b(-b -1で1つ前)、/var/log/ のファイル。