Ubuntuは、標準のブートローダーとしてGRUBを採用しています。ほとんどの利用者は、インストール時に自動設定されるGRUBをそのまま利用し続けていることでしょう。今回は初心者向けに、このGRUBがどう動いているのか、そしてどのように設定可能なのかを紹介します。
セキュアブート時代のGRUB
GNU GRUB
普段Ubuntuをインストールして使っているPCも例外ではなく、CPUがDRAMが使えるようになったあとはまずフラッシュROMに記録されたBIOSが起動処理を担ったあとに、ストレージ上に記録された起動プログラムを立ち上げます。PCの文脈では、この最初に起動するプログラムが
GRUBには現行バージョンとは別に、古いコードベースであるGRUB Legacyが存在します。こちらは開発元でもUbuntuでもメンテナンスされていないソフトウェアです。Ubuntuの利用者なら気にする必要はないでしょう[2]。また、さらに対応システムによって、現行バージョンも次の2種類にわけられます。
- grub-efi:UEFI BIOSが搭載されたシステム向けのGRUB
- grub-pc:UEFIが搭載されていないLegacy BIOS向けのGRUB
UEFI版のGRUBは、ストレージ上のESP
おそらくここ数年の、一般的なPCであればそのほとんどがUEFIになっているでしょう。BIOS側の設定で、Legacy BIOSにできないものも多いかもしれません。よって、今回はすべてUEFI版のみを前提に説明します。
UEFI版のGRUBで、これまでと大きく異なるのがEFI/
」
セキュアブートは第444回の
そこでUbuntuを含むLinuxディストリビューションの多くは
つまりUbuntuでGRUBを細かくカスタマイズするには、ESPやセキュアブートもある程度把握しておく必要があるのです。今回はESP・
- いきなりUbuntuが起動しなくなったので、なんとかしてリカバリーしたい
- 特定のデバイスを動かすためにカーネルパラメーターを変更する必要がある
- 起動時に特定の曲を再生したい
基本的にGRUBの設定変更はトラブルの元であり、インストール時の状態を維持することを強くおすすめします。どうしても設定変更が必要になったときに備えて、基本的な考え方を抑えておこうというのが今回の記事の趣旨となります[3]。
設定ファイルの基本構造
GRUBのカスタマイズは
/boot/
grub/ grub. cfg /etc/
default/ grub /etc/
grub. d/
「GRUBの設定」/boot/
が唯一の設定ファイルです。このファイルから他のファイルを読み込むことも可能ではあるものの、Ubuntuの設定だと起動時にはこのファイルのみが使われると思っておけば良いでしょう。ただし、このファイルを直接編集することはあまりありません。他のファイルを編集し、update-grub
コマンドによってその内容が/boot/
に反映される仕組みになっています。
その代わりに編集するのが/etc/
」
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'
冒頭に書かれているように、このファイルを編集するだけではGRUBの設定には反映されません。編集した後はsudo update-grub
を実行する必要があります。
起動エントリーの指定
/etc/
は他の/etc/
以下のファイルと同じように、ただの環境変数変数名=値
)update-grub
はこのファイルを読み込んで、設定されている内容を変数として参照することになります。最初に登場するのがGRUB_
です。
GRUB_DEFAULT=0
GRUB_
は、自動で選択するGRUBのメニューエントリーの番号です。Ubuntuの場合は、通常次のようなメニューエントリーの表示がされると思います。操作しない時にどのメニューエントリーを選ぶかをここで設定します。
指定できるのは次の4種類です。
- エントリータイトル
- エントリーID
- エントリー番号
- 「saved」
キーワード
GRUBのメニューエントリーは、/boot/
にも記述されていますので、まずはそちらを確認すると良いでしょう。
$ sudo grep -E "menuentry |submenu " /boot/grub/grub.cfg menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-c2133eaa-03ff-4f18-b978-c12f55e5af23' { submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-c2133eaa-03ff-4f18-b978-c12f55e5af23' { menuentry 'Ubuntu, with Linux 5.15.0-56-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.15.0-56-generic-advanced-c2133eaa-03ff-4f18-b978-c12f55e5af23' { menuentry 'Ubuntu, with Linux 5.15.0-56-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.15.0-56-generic-recovery-c2133eaa-03ff-4f18-b978-c12f55e5af23' { menuentry 'Ubuntu, with Linux 5.15.0-53-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.15.0-53-generic-advanced-c2133eaa-03ff-4f18-b978-c12f55e5af23' { menuentry 'Ubuntu, with Linux 5.15.0-53-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.15.0-53-generic-recovery-c2133eaa-03ff-4f18-b978-c12f55e5af23' { menuentry 'UEFI Firmware Settings' $menuentry_id_option 'uefi-firmware' {
エントリー番号は、上から順番に0、1、2と番号が振られます。図1や上記の例だとUbuntu
」Advanced options for Ubuntu
」Ubuntu, with Linux 5.
」
「Ubuntu
」Advanced options for Ubuntu
」$menuentry_
」GRUB_
」
submenu
の下にあるmenuentry
はメインメニュー>サブメニュー
」
GRUB_DEFAULT="1>1"
もし一時的に起動エントリーを変更したいだけなら、grub-reboot
コマンドが使えます。たとえば次のように指定すると、Ubuntuしかインストールされていない環境なら次回起動時に
$ sudo grub-reboot '2'
上記コマンドを実施後に再起動すると、GRUB_
を書き換えた時と同様の状態になります。ただし反映されるのは1度きりです。次の起動時にはGRUB_
の値が使われます。次の起動のときだけ、一時的にUEFI設定画面を起動したり、リカバリーモードにしたい場合などに便利でしょう。
また、GRUB_
も追加します。
GRUB_DEFAULT="saved"
GRUB_SAVEDEFAULT="true"
これにより起動メニューで選択したエントリーが、次の起動でも使われるようになります。
起動メニューの表示
Ubuntuは特定の条件を満たすか、特に設定していないと前述の起動メニューは表示されません。手動で表示するためには、起動直後のGRUB処理中にESCキーを押す必要があります。タイミングはかなりシビアなので、もし必要なら常に表示するようにしておくと良いでしょう。その設定が次の2行です。
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=0
GRUB_
はメニューの表示方式をコントロールします。menu
を設定するとインタラクティブ操作できるメニューを表示し、countdown
は起動までの秒数をカウントダウン形式で表示、hidden
は何も表示しません。
GRUB_
はメニューの表示方式によって見え方が異なるものの、基本的に設定したエントリーを起動するまでの秒数です。このmenu
ならこの時間以内に何かキー入力をすれば、カウントダウンが停止します。countdown
やhidden
だと、まずはESCキーなどでメニューを表示する必要があります。
Ubuntuのインストール時の設定ではhidden
」menu
」
GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=10
ディストリビューターの設定
次の行は、Linuxディストリビューションの設定です。lsb_
」
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
カーネルのコマンドラインの設定
カーネルは起動時に指定できるコマンドラインパラメーターによって、様々挙動を変更できます。また、systemdを含むいくつかのシステムアプリケーションも、このパラメーターを参照して挙動を変えています。よって何かデバッグをしたい場合は、このコマンドラインパラメーターが強力なツールになってくれるのです。
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""
名前が似ていてわかりにくいのですが、Ubuntuの場合はおおよそ次のように使い分けます。
GRUB_
:通常のカーネルのみに設定したいものCMDLINE_ LINUX_ DEFAULT GRUB_
:通常のカーネルとリカバリーモードの両方で設定したいものCMDLINE_ LINUX
上記で設定されているquiet splash
」GRUB_
のみに設定しているのです。
ちなみに何か設定を追加したい場合はダブルクオートの中に追記してもいいのですが、次のように別の行に追加すると、差分がわかりやすくなって便利です。
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT foo"
GRUB_CMDLINE_LINUX=""
カーネルモジュールのロードや無効化、パラメーターの設定にも使えます。よって、NVIDIAに代表される特別扱いしないとへそを曲げるタイプのモジュールの設定や、IOMMUみたいな便利だけどどの環境でも問答無用で有効化するのは憚られる設定などのように、プロダクション用途でもお世話になることがあることでしょう。
もし一時的に設定を変更したいのであれば、起動時のメニューエントリーからカーソルキーで変更したいエントリーを選択した上で、
その他の設定
/etc/
には他にも設定変数が掲載されていますが、いずれもコメントアウトされています。コメントにいくつか説明が書かれているものの、ほとんど使うことはありません。
GRUB_
を使うと、メモリの壊れていると思われる部分の使用を除外できます。GRUB_
の書式はアドレス,マスク
」
# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
GRUB_
はGRUB_
とGRUB_
を一括して設定する変数で、一般的にシリアルコンソールを使用したい場合に使います。具体的な設定方法は第638回の
# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console
# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480
GRUB_
も同様に出力先の画面解像度の設定です。
update-grub
でメニューエントリーを作成する際、ルートファイルシステムはデバイスパスではなくUUIDで指定する形のエントリーroot=UUID=xxx
)
# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true
GRUB_
はリカバリーモードのメニューエントリーを無効化する設定です。
# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY="true"
GRUB_
は起動時にビープ音を鳴らす設定です。最初の数字がBPMで、残りはHzとその音の継続時間のペアを繰り返します。上記の例だと480BPMで1拍なので1/
# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"
他にも変数による設定が存在します。詳細はGRUBの
GRUBの環境変数ブロック
GRUBには/boot/
」/boot/
からload_
コマンドを実行することでロードされます。
これは主にGRUBの実行時に生成された情報を、どこかに保存したい場合に使用します。具体的にはGRUB_
を設定したときのような
環境変数の設定はGRUBからならsave_
コマンドで実現しますが、Linuxからでもgrub-editenv
で変更可能です。
環境変数の一覧表示 $ grub-editenv - list (何も表示されない) 環境変数fooの設定 $ sudo grub-editenv - set foo=bar $ grub-editenv - list foo=bar 環境変数fooの削除 $ sudo grub-editenv - unset foo $ grub-editenv - list (何も表示されない)
grub-editenv
の第一引数には環境変数ブロック/boot/
)-
」
/boot/
の中で$foo
」set foo=bar
」grub-editenv
を使えば、load_
以降はset foo=bar
」GRUB_
を次のように変更することで、カーネルの起動パラメーターをgrub-editenv
コマンドだけでコントロールできるようになります。
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT \$foo"
foo
が未設定だったら何も指定しませんし、一時的にオプションを追加したければsudo grub-editenv - set foo=bar
」