環境
OS:Ubuntu 22.04.5 LTS
✅ TL;DR(結論)
Ubuntuのカーネルアップデートに伴い、新カーネル用の initrd.img
が /boot
に生成されておらず、GRUBはそれを使おうとして起動に失敗しました。
LiveUSB + chrootで以下のコマンドを実行することで修復できます:
sudo mount /dev/nvme0n1p3 /mnt
for d in /dev /proc /sys /run; do sudo mount --bind $d /mnt$d; done
sudo chroot /mnt
以下のコマンドでGRUBで使おうとしているカーネルのバージョンを確認.
cat /mnt/boot/grub/grub.cfg | grep -Ei 'menuentry|linux|initrd'
menuentry 'Ubuntu' ... {
...
linux /boot/vmlinuz-6.8.0-64-generic root=/dev/nvme0n1p3 ro quiet splash $vt_handoff
# この次に initrd /boot/initrd.img-6.8.0-64-generic という行があるべき
}
この出力の6.8.0-64-generic
がカーネルのバージョンにあたり,それに対応するinitrdが存在する必要がある.以下のように実行し,再構築する.
update-initramfs -c -k 6.8.0-64-generic # カーネルのバージョンに合わせる
update-grub
再起動すれば復旧するはずです。
症状
GPUでの処理が上手く動作しなかったため,再起動し,OSを選択(Ubuntu)すると黒画面でフリーズしてしまう.
試したこと
1. セーフグラフィックスモードで起動
- セーフグラフィックスモードとはグラフィックドライバ関連で起動できない時に問題を回避するための応急処置用の起動オプション.
-
nomodeset
という特殊な設定をカーネルに渡すことでGPUのドライバを読み込むのをやめ,CPUで描画する.
手法
- PC起動後,「OS選択(Ubuntu)」の画面で止まったら
Esc
キーを連打
⇒GRUBメニュー - 「Ubuntu」で選択した状態で
e
キーを押して編集モードへ -
linux
で始まる行の最後にquiet splash
をnomodeset
に変更 -
F10
またはCtrl + X
で起動
結果
/dev/root: Can't open blockdev
VFS: Cannot open root device "/dev/nvme0n1p3" or unknown-block(0,0): error -6
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
と表示され、カーネルパニックで停止した.
これはカーネルが/dev/nvme0n1p3
(ルートパーティション)を認識できず,ファイルシステムをマウントできないという問題だそう.
2. initramfsの再構築(失敗)
この問題の原因として考えられるのが,initramfs
にNVMeドライバが含まれていないということ.Ubuntu起動時,カーネルはrootファイルシステムを読み込む前にintiramfs
という一時的なRAMディスクを展開し,中に含まれるNVMeドライバを読み込んでNVMeドライブにアクセスする.しかし,今回何らかの理由でinitramfsの中にNVMeが含まれていなかったか,ファイルが壊れている可能性がある.
そのため,このinitramfs
を再構築して解決を試みる.
まずはLiveUSBで修復してみる.USBブートで起動後「Ubuntuを試す(Try Ubuntu)」を選択する.が,以下のようなメッセージが出てしまった.
Oh no! Something has gone wrong
これはGUIの起動に失敗したときに表示されるらしい.そこで,再び1の手法で回避してみる.
手法
-
1. セーフグラフィックスモードで起動
と同様の方法でLiveUSBで起動 -
ターミナルを開いて,以下のコマンドでパーティションを確認
lsblk -f
/dev/nvme0n1p3
のようなエントリがext4
で表示されていれば,それがUbuntuのルートパーティションである. -
パーティションをマウント
# Ubuntuルートをマウント sudo mount /dev/nvme0n1p3 /mnt # 必要なシステムディレクトリもマウント for dir in /dev /proc /sys /run; do sudo mount --bind $dir /mnt$dir done
-
ルート環境に入る
sudo chroot /mnt
-
修復
# initramfs(初期RAMディスク)を再生成 update-initramfs -u -k all # GRUBの設定を再構築 update-grub
-
セーフグラフィックスモードで再起動
結果
解決せず,全く同じKernel panic -not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
が出力されてしまった.
3. GRUBの設定ファイル確認
OSの起動に関する具体的な指示が書かれているGRUB設定ファイル(grub.cfg
)を確認した.
手法
設定ファイルから起動部分を抜粋
cat /mnt/boot/grub/grub.cfg | grep -Ei 'menuentry|linux|initrd'
結果
menuentry 'Ubuntu' ... {
...
linux /boot/vmlinuz-6.8.0-64-generic root=/dev/nvme0n1p3 ro quiet splash $vt_handoff
# この次に initrd /boot/initrd.img-.... という行があるべき
}
GRUB設定ファイルの一番重要な通常の起動メニュー(menuentry 'Ubuntu’
)の中に本来あるべきinitrd
という行が欠落していた.initrd
はディスクを読み込むためのNVMeドライバなど,軌道に不可欠なドライバ群を読み込むための重要な命令である.この行がないため,カーネル(vmlinuz
)が読み込まれた後,ドライバが一切読み込まれていなかった模様.
今回はカーネルのバージョンからinitrd.img-6.8.0-64-generic
が必要である.
4. initrdが存在するか確認
手法
以下のコマンドを実行した.
ls -lR /mnt/boot
結果
initrd.img
initrd.img-6.8.0-60-generic
initrd.img.old
どうやらバージョンの古いものしかなかったよう.カーネルのアップデートが不完全に終わり,GRUBの設定と実際のファイルに不整合が生じた可能性がある.
5. initrdファイルの再生成(成功)
手法
-
1. セーフグラフィックスモードで起動
と同様の方法でLiveUSBで起動 -
パーティションをマウントし,ルート環境に移動
# Ubuntuルートをマウント sudo mount /dev/nvme0n1p3 /mnt # 必要なシステムディレクトリもマウント for dir in /dev /proc /sys /run; do sudo mount --bind $dir /mnt$dir done # ルート環境に入る sudo chroot /mnt
-
修復
# 存在しない initrd.img-6.8.0-64-generic を再生成 update-initramfs -c -k 6.8.0-64-generic # GRUBの設定を再構築 update-grub
-
再起動
結果
上手く再起動できた.
まとめ
今回のKernel Panicが生じていた原因は新しいカーネルのinitrd.img
が/boot
に存在しなかったためである.
おそらくapt update
などによってlinux-image-6.8.0-64-generic
がインストールされたが,このときinitrd.img-6.8.0-64-generic
の生成が失敗していた可能性がある.
その原因として考えられるのは,
-
/boot
が容量不足 -
initramfs-tools
の不具合 - インストール途中で中断
などがあるようである.