tanke25616429のアウトプット

IT技術の基本を勉強したことをアウトプットします。Linux、Kubernetes、クラウド中心です。百番煎じくらいだけど誰かの役に立てばそれはそれでうれしい。

Linuxにおけるブート設定入門

本記事の範囲

システム起動までの流れは以下である。

  1. 電源投入
  2. BIOS / UEFI によるデバイス初期化
  3. ブートデバイスの決定
  4. ブートストラップローダのロード
  5. ブートローダGRUB等)の実行
  6. OSの起動

本記事では5.のブートローダの設定に関して、新旧のGRUBがあったりシステムがBIOSなのかUEFIなのかでやり方が異なり、紛らわしい部分があるので整理する。

GRUB LegacyとGRUB2

GRUBにもGRUB Legacyと呼ばれる古いものと、新しいGRUB2がある。GRUB Legacyはサポートが打ち切られているため、基本的には現在はGRUB2を使う。GRUB LegacyとGRUB2の主な違いは以下である。

今後覚える場合は、GRUB2の書式を覚えればよい*1。本記事でも以降はGRUB2前提で記載する。

基本的な設定方法

/etc配下にGRUB関連の設定ファイルがあるため、これを編集する。編集しただけでは反映されていないため、grub2-mkconfigコマンドでビルドし/boot配下の設定ファイルに反映する。システムは起動時に/boot配下の設定ファイルを参照して動作する。人間が直接/boot配下の設定ファイルを編集はしない。

全体的な設定の変更

全体的な設定は/etc/default/grubで行う。例えば、起動メニューのタイムアウト時間や、起動メッセージを流すかどうかといった点を設定する。

# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto spectre_v2=retpoline rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

ここでは起動メニューのタイムアウト時間とスタイルを変更してみる。

# vi /etc/default/grub
# cat /etc/default/grub
#GRUB_TIMEOUT=5
GRUB_TIMEOUT=10 # changed
GRUB_TIMEOUT_STYLE=countdown # changed
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto spectre_v2=retpoline rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

変更後、grub2-mkconfigでビルドし、変更を反映する。 -oで反映先を指定しているが、/boot/grub2/grub.cfgを指定するのはBIOSのシステムの場合である*2UEFIのシステムの場合は、/boot/efi/EFI/ディストリビューション名(redhat, centos等)/grub.cfgに反映する。

# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-1160.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1160.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-7c3a299321421f40be4427dfd36d6708
Found initrd image: /boot/initramfs-0-rescue-7c3a299321421f40be4427dfd36d6708.img
done
[root@localhost ~]# reboot

f:id:tanke25616429:20210321160227p:plain
GRUB_TIMEOUT_STYLE=countdownを指定した場合のメニュー画面

GRUB_TIMEOUT_STYLE=countdownをコメントアウトして再度試す。

# vi /etc/default/grub
# cat /etc/default/grub
#GRUB_TIMEOUT=5
GRUB_TIMEOUT=10 # changed
#GRUB_TIMEOUT_STYLE=countdown
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto spectre_v2=retpoline rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

grub2-mkconfigでビルド後、再起動する。もともと5秒からカウントダウンだったが、下記画面キャプチャ時点では残り9秒になっていることがわかる。

f:id:tanke25616429:20210321160626p:plain
GRUB_TIMEOUT=10の場合のメニュー画面

参考:BIOSUEFIかの区別の仕方

/sys/firmware配下に/efiというディレクトリがある場合はUEFI、ない場合はBIOSである。

UEFIの場合

# ls /sys/firmware/
acpi/        dmi/         efi/         memmap/      qemu_fw_cfg/

BIOSの場合

# ls /sys/firmware/
acpi  dmi  memmap  qemu_fw_cfg

メニューエントリーの変更

カーネルアップデートをかけた場合など、起動メニューに複数の選択肢が発生する場合がある。デフォルトの選択肢をどれにするかを設定することができる。以下の例では、バージョンが3.10.0-1062.18.1.el7.x86_64と3.10.0-957.el7.x86_64のカーネルがインストールされている。

# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
# uname -r
3.10.0-1062.18.1.el7.x86_64
# grep ^menuentry /boot/grub2/grub.cfg
menuentry 'CentOS Linux (3.10.0-1062.18.1.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-957.el7.x86_64-advanced-668d17f8-c677-448b-ace3-cb888f1f9633' {
menuentry 'CentOS Linux (3.10.0-957.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-957.el7.x86_64-advanced-668d17f8-c677-448b-ace3-cb888f1f9633' {
menuentry 'CentOS Linux (0-rescue-88e66ec094834d12b89d26902abe40ce) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-88e66ec094834d12b89d26902abe40ce-advanced-668d17f8-c677-448b-ace3-cb888f1f9633' {

デフォルトメニューは/etc/default/grubGRUB_DEFAULTで設定するが、ここがsavedの場合は別ファイルに保存されている。この場合は、grub2-editenv listコマンドでも確認できる。saved_entry=0なので一番上のもの(=3.10.0-1062.18.1.el7.x86_64)がデフォルトで選択されている。

# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
# grub2-editenv list
saved_entry=0

3.10.0-957.el7.x86_64のカーネルがデフォルトになるように書き換える。

# grub2-set-default 1
# grub2-editenv list
saved_entry=1
# reboot

起動後、↓キーで移動していないが、2番目のエントリーが選択されている。

f:id:tanke25616429:20210321162655p:plain
saved_entry=1としたときのメニュー画面

当然、そのまま起動すれば、バージョン3.10.0-957.el7.x86_64のカーネルで起動する。なお、GRUBの設定は違うメニューから起動しても共通である。

# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
# uname -r
3.10.0-957.el7.x86_64
# grub2-editenv list
saved_entry=1
# grep ^menuentry /boot/grub2/grub.cfg
menuentry 'CentOS Linux (3.10.0-1062.18.1.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-957.el7.x86_64-advanced-668d17f8-c677-448b-ace3-cb888f1f9633' {
menuentry 'CentOS Linux (3.10.0-957.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-957.el7.x86_64-advanced-668d17f8-c677-448b-ace3-cb888f1f9633' {
menuentry 'CentOS Linux (0-rescue-88e66ec094834d12b89d26902abe40ce) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-88e66ec094834d12b89d26902abe40ce-advanced-668d17f8-c677-448b-ace3-cb888f1f9633' {

まとめ

  • GRUB Legacy:古いので基本的には覚えなくてよい(ので本記事では割愛)
    • GRUB Legacy×UEFIの組み合わせはそもそも対応もしていない
  • GRUB2:設定は/etc配下の設定ファイルで行い、/boot配下の設定ファイルは直接編集しない。grub2-mkconfigコマンドで/etc配下の設定ファイルの変更点をビルドして反映するが、反映先がUEFIの場合とBIOSの場合で異なる。

参考にしたもの

www.pc-koubou.jp

第5回 ブートローダ|Linux技術者認定機関 LPI-Japan [エルピーアイジャパン]

enakai00.hatenablog.com

www.youtube.com

websetnet.net

【 grub2-mkconfig/grub-mkconfig 】コマンド――GRUB 2の起動メニューを生成する:Linux基本コマンドTips(278) - @IT

第26章 GRUB 2 での作業 Red Hat Enterprise Linux 7 | Red Hat Customer Portal

*1:古いシステムを扱わなくてはいけない場合は別。

*2:今回はVirtualBox上で試しており、VirtualBoxではデフォルトはBIOSとなっている。