Ubuntu

Ubuntu22.04 GRUBのカスタマイズ ソースからビルド編

日頃、GRUBのコマンドラインで何かを操作することはほとんどない。
でも、仮想環境でキーマップを日本語化できたのに、メインPCのキーマップが変更できないのが悔しくて、少し調べてみた。
(どちらもセキュアブートが有効なので、使えるようにするのにちょっと手間を掛けたこともあり、引き下がれない!苦笑)

結論からすると、英語キーボードにない[\/|]と[\/_]の2つのキーは空いているところに割り当てる形になったが、それ以外は日本語キーボードの刻印通りに入力ができるようになった。



広告


はじめに

やること

やることは以下。

  • GRUBのソースをダウンロードしてきてビルドする。
  • 使用したいコマンドやフォント・キーマップを内蔵したGRUBバイナリを作る。
    このとき、ソースコードにキーコードを変換するカスタマイズを入れる。
  • できあがったGRUBバイナリに署名し、/boot/efi/EFI/ubuntuに置く。

ビルドのために割と色々インストールするので、専用の仮想環境を作って構築した。

GRUBバイナリに署名してShimの検証を通すようにしているが、説明はメモ程度としている。
これに手を掛けるような人は、セキュアブートについて理解して使っている、あるいは理解した上で外している人だろうから。

実行するかどうか決める

結構手間が掛かる上に、配布されているGRUBバイナリと同じものができるかどうか分からない。
まずは、grub-mkimageでやりたいことが実現できないか、確認しておくのが良いと思う。

この方法にトライする条件を整理しておく。

  • at_keyboardモジュールが動作しない環境で、日本語のキーマップが使いたい。
    • セキュアブートを無効化、あるいは、Shimによる検証を無効化したとき、at_keyboardが動作する環境ならば、grub-mkimageでat_keyboardをビルトインさせることで、セキュアブート環境で動作させることができる。
      この方法なら、完全な日本語キーマップになる。
    • 英語キーボードを頭に思い描いて入力ができるのであれば、それはそれで1つの解決策かもしれない。
      今回のカスタマイズでは、キー2つを正規の場所に割り当てられなかったので、完全解決とはいえない。
  • BIOSにキーボードレイアウトの選択がない。

つまり、どうしようもない場合に頑張る感じ。

構築環境を作る

VMware PlayerでUbuntu 22.04 LTS serverの環境を立ち上げた。
ビルドが終わり、動作確認をしている段階で、ディスクの使用量は8GB程度。

ビルド環境はEFIである必要はないみたいだけれど、テストをするのでEFIでセキュアブートの環境を作っている。

<machine name>.vmx

firmware = "efi"
efi.legacyBoot.enabled = "FALSE"
uefi.secureBoot.enabled = "TRUE"
ulm.disableMitigations="TRUE"
disk.EnableUUID = "TRUE"

解像度を変えて試す場合には、以下を追記。
※起動する度にTRUEに戻るので、FALSEに書き換える必要がある。

svga.guestBackedPrimaryAware = "TRUE"

GRUBバイナリのビルド

必要パッケージのインストール

ビルド方法を模索する中で、パッケージングガイドを教えてくれる投稿があり、これが良さそうだと考えた。
Ubuntu packaging guide / 2. Getting Set Up
Ubuntu packaging guide / 3. Fixing a bug in Ubuntu

$ sudo apt install -y gnupg pbuilder ubuntu-dev-tools apt-file

加えて、GRUBをビルドするのに必要なパッケージをインストールする。

$ sudo apt install -y autoconf autopoint pkg-config bison flex unifont \
libfreetype-dev libzfslinux-dev libfuse3-dev liblzma-dev

ソースのダウンロード

ソースパッケージを探してみる。

$ apt-cache showsrc grub-efi-amd64
Package: grub2
Format: 3.0 (quilt)
Binary: grub2, grub-linuxbios, grub-efi, grub-common, grub2-common, grub-emu, grub-emu-dbg, grub-pc-bin, grub-pc-dbg, grub-pc, grub-rescue-pc, grub-coreboot-bin, grub-coreboot-dbg, grub-coreboot, grub-efi-ia32-bin, grub-efi-ia32-dbg, grub-efi-ia32, grub-efi-ia32-signed-template, grub-efi-amd64-bin, grub-efi-amd64-dbg, grub-efi-amd64, grub-efi-amd64-signed-template, grub-efi-ia64-bin, grub-efi-ia64-dbg, grub-efi-ia64, grub-efi-arm-bin, grub-efi-arm-dbg, grub-efi-arm, grub-efi-arm64-bin, grub-efi-arm64-dbg, grub-efi-arm64, grub-efi-arm64-signed-template, grub-efi-riscv64-bin, grub-efi-riscv64-dbg, grub-efi-riscv64, grub-ieee1275-bin, grub-ieee1275-dbg, grub-ieee1275, grub-firmware-qemu, grub-uboot-bin, grub-uboot-dbg, grub-uboot, grub-xen-bin, grub-xen-dbg, grub-xen, grub-xen-host, grub-yeeloong-bin, grub-yeeloong-dbg, grub-yeeloong, grub-theme-starfield, grub-mount-udeb
...
Package: grub2-unsigned
Format: 3.0 (quilt)
Binary: grub-efi-amd64, grub-efi-arm64, grub-efi-amd64-bin, grub-efi-arm64-bin, grub-efi-amd64-dbg, grub-efi-arm64-dbg
...

もし、ソースが見られないようなら、以下でソースのリポジトリを追加する。

$ sudo add-apt-repository --enable-source http://archive.ubuntu.com/ubuntu -c main -c universe -c multiverse
...
Adding deb entry to /etc/apt/sources.list.d/archive_uri-http_archive_ubuntu_com_ubuntu-jammy.list
Adding deb-src entry to /etc/apt/sources.list.d/archive_uri-http_archive_ubuntu_com_ubuntu-jammy.list
...

grub2は広く色々な環境のモジュールが作れるようだが、amd64版が作りたいので、grub2-unsignedで十分に見える。

ソースをダウンロードする際、jammyを指定しないと最新版をダウンロードする。この日は2.12-rc1だった。
普通はjammyを指定して安定版を使うと思うが、手順は同じ。

$ pull-lp-source grub2-unsigned
$ ls -l
total 7532
drwxrwxr-x 16 rohhie rohhie    4096 Sep 28 21:32 grub2-unsigned-2.12~rc1
-rw-rw-r--  1 rohhie rohhie 1113140 Sep 28 21:32 grub2-unsigned_2.12~rc1-10ubuntu2.debian.tar.xz
-rw-rw-r--  1 rohhie rohhie    3624 Sep 28 21:32 grub2-unsigned_2.12~rc1-10ubuntu2.dsc
-rw-rw-r--  1 rohhie rohhie 6589460 Sep 28 21:32 grub2-unsigned_2.12~rc1.orig.tar.xz

あるいは
$ pull-lp-source grub2-unsigned jammy

ビルド

ビルド方法は全く分からなかったけれど、以下のサイトで教えてくれたことがきっかけで、何とか進めることができた。
DRLM / Building GRUB2 for diferent platfoms

ビルド環境&ソースの状態で、やることは多少変わると思われる。
今回整理した手順が通用しなくなった時のために、試行錯誤の過程を別途メモに残す(2.12~rc1/2.06)。

2.06のビルドの過程でpythonコマンドが使われているのだが、Ubuntu 22.04ではpython3となっている。
そこで、デフォルトコマンドのシンボリックリンクを作っておく。

$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1

ビルド環境を整える。
それぞれのコマンドが正しく終了することを確認し、もし何か起きていたら都度修正。

$ cd grub2-unsigned-2.12~rc1
$ automake --add-missing
$ autoreconf
$ ./autogen.sh
$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
*******************************************************
GRUB2 will be compiled with following components:
Platform: x86_64-efi
With devmapper support: No (need libdevmapper header)
With memory debugging: No
With disk cache statistics: No
With boot time statistics: No
efiemu runtime: No (not available on efi)
grub-mkfont: Yes
grub-mount: Yes
starfield theme: Yes
With DejaVuSans font from /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
With libzfs support: Yes
Build-time grub-mkfont: Yes
With unifont from /usr/share/fonts/X11/misc/unifont.pcf.gz
With liblzma from -llzma (support for XZ-compressed mips images)
With stack smashing protector: No
With quiet boot: No
*******************************************************

x86_64-efiになっているし、grub-mkfontも作られ、unifontも作られるようになっている。OK。
ビルドする。

$ make

正常終了したら、make installすれば、/usr/local/{bin.share/grub,lib/grub}にファイルがインストールされるけれど、ここでは実行しないでおく。
2.12~rc1をインストールした後でupdate-grubを実行したら、/boot/grub/grub.cfgが壊れてしまい、Ubuntuが起動しなくなったから。

実際、GRUBバイナリができれば良く、インストールは必要ではないから。

署名用の秘密鍵・証明書を生成

別の記事で詳しく説明している
ここでは、画面イメージなしで、手順だけザックリ記載。

秘密鍵(MOK.priv)と証明書(MOK.der, MOK.pem)の生成し、所定の場所に保管。

$ openssl req -newkey rsa:4096 -nodes -new -x509 -sha256 -days 36500 -subj "/CN=ROHHIE" -keyout MOK.priv -outform DER -out MOK.der
$ openssl x509 -in MOK.der -inform DER -outform PEM -out MOK.pem
$ sudo cp MOK.* /var/lib/shim-signed/mok

※CNのところは自分でわかりやすい名前を付けておく。
※ファイルを上書きしないように注意。重複していたら2でも付ければOK。
※ローカルのMOK.*は削除して構わない。

Shimに証明書を登録し、再起動後にMokManagerで登録手続きを完了させる。

$ sudo mokutil --import /var/lib/shim-signed/mok/MOK.der
$ sudo reboot

※ここで聞かれるパスワードは、MOKの操作が終わるまで覚えておけばOK。

GRUBバイナリのビルド

debianディレクトリにあるビルドスクリプトを実行する。
出力先を/usr/local/bin/lib/grub/x86_64-efiにしたのでsudoを付けているが、書き込み権限のある出力先ならsudoはいらない。

$ grub2-unsigned-2.12~rc1
$ sudo debian/build-efi-images ./grub-mkimage ./grub-core /usr/local/lib/grub/x86_64-efi ubuntu x86_64-efi x64 debian/sbat.ubuntu.csv.in ubuntu
$ ls -l /usr/local/lib/grub/x86_64-efi
total 6996
-rw-r--r-- 1 root root 2265088 Sep 30 17:41 gcdx64.efi
-rw-r--r-- 1 root root 2281472 Sep 30 17:41 grubnetx64.efi
-rw-r--r-- 1 root root 2617344 Sep 30 17:41 grubx64.efi

GRUBバイナリへの署名と配置

署名結果をそのままメインPCに適用する。

$ sudo sbsign --key /var/lib/shim-signed/mok/MOK.priv --cert /var/lib/shim-signed/mok/MOK.pem \
--output /boot/efi/EFI/ubuntu/grubx64.efi /usr/local/lib/grub/x86_64-efi/grubx64.efi

Shimによる検証を無効にしていたり、セキュアブートを無効にしている場合は、できあがったバイナリをそのままコピーすれば良い。

GRUBバイナリの差し替えによって問題が発生した時に備えて、復旧方法を2つ用意している。

この記事を書いている時点では、この手順で問題なく起動してくることを何度も繰り返し確認しているが、起動しなくなると手間が掛かるので準備しておくと良い。

実際、カットアンドトライを繰り返す中では、救援用ブートエントリーはなくてはならないものだった。

もし、grub.cfgが壊れたという話ならば、こちらの方法でUbuntuを起動できるかもしれない。
Ubuntu22.04 GRUBのコンソールから起動

再起動して確認

GRUBメニューが表示されるように、以下の変更を加えておく。

/etc/default/grub

GRUB_DEFAULT=0
#GRUB_TIMEOUT_STYLE=hidden
#GRUB_TIMEOUT=0
GRUB_TIMEOUT=10
GRUB_GFXMODE=1920x1080

※解像度の設定は必須ではないが、unicode.pf2が読み込まれていることの確認になるので、入れておいた。

設定を反映。

$ sudo update-grub

再起動後にメニューが表示され、Ubuntuが起動できれば、ビルドは成功。

GRUBのカスタマイズ

カスタマイズを入れたら、makeして、build-efi-imagesして、sbsignして動作を確かめる。
configureは都度実行する必要はなく、モジュールを追加したときなどに行えば良いようだった。

キーマップの変更

メインPCでat_keyboardが使えなかったので、consoleモジュールを改造して、キーコードを置き換えることを考えた。

英語キーボードが手元にないのでWikipediaで見てみたら、×の位置にはキーがなかった。
console.cの関数にこのキーの入力が通知されないので、どうにも置き換えようがなく、[全角/半角]と[0]に×のキーのコードを割り当てている。

変更前

┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐┌─┬─┬─┬─┐
│`~│1!│2@│3#│4$│5%│6^│7&│8*│9(│0)│-_│=+│×│BS││NL│/ │* │- │
├─┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴─┤├─┼─┼─┼─┤
│Tab │qQ│wW│eE│rR│tT│yY│uU│iI│oO│pP│[{│]}│Ente││7 │8 │9 │  │
├──┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┐  │├─┼─┼─┤+ │
│CapsLo│aA│sS│dD│fF│gG│hH│jJ│kK│lL│;:│'"│\|│  ││4 │5 │6 │  │
├───┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴─┤├─┼─┼─┼─┤
│Shift   │zZ│xX│cC│vV│bB│nN│mM│,<│.>│/?│×│Shif││1 │2 │3 │  │
├──┬─┴┬┴─┼─┴─┴─┴─┴─┼─┴┬┴─┼─┼──┤├─┴─┼─┤En│
│Ctrl│Win │ALT │                  │ALT │Win │Mn│Ctrl││  0   │. │  │
└──┴──┴──┴─────────┴──┴──┴─┴──┘└───┴─┴─┘

変更後

┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐┌─┬─┬─┬─┐
│\|│1!│2"│3#│4$│5%│6&│7'│8(│9)│0_│-=│^~│×│BS││NL│/ │( │- │
├─┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴─┤├─┼─┼─┼─┤
│Tab │qQ│wW│eE│rR│tT│yY│uU│iI│oO│pP│@`│[{│Ente││7 │8 │9 │  │
├──┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┐  │├─┼─┼─┤~ │
│CapsLo│aA│sS│dD│fF│gG│hH│jJ│kK│lL│;+│:*│]}│  ││4 │5 │6 │  │
├───┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴─┤├─┼─┼─┼─┤
│Shift   │zZ│xX│cC│vV│bB│nN│mM│,<│.>│/?│×│Shif││1 │2 │3 │  │
├──┬─┴┬┴─┼─┴─┴─┴─┴─┼─┴┬┴─┼─┼──┤├─┴─┼─┤En│
│Ctrl│Win │ALT │                  │ALT │Win │Mn│Ctrl││  0   │. │  │
└──┴──┴──┴─────────┴──┴──┴─┴──┘└───┴─┴─┘

※日本語キーボードの刻印と合わない箇所を赤文字で表示。テンキーも改造の副作用で*と+が置き換わってしまう。
※×のキーは入力を検知できない。

この置き換えを、以下のソースを改変することで行った。

grub-core/term/efi/console.c

...
static int
grub_efi_translate_key (grub_efi_input_key_t key)
{
  /* my debug
  if (key.scan_code != 0 || key.unicode_char !=0) {
    grub_dprintf ("mydeb", "scan_code=%d,unicode_char=%d\n", key.scan_code, key.unicode_char);
  }
  */

  if (key.scan_code == 0)
    {
      /* Some firmware implementations use VT100-style codes against the spec.
         This is especially likely if driven by serial.
       */
      if (key.unicode_char < 0x20 && key.unicode_char != 0
          && key.unicode_char != '\t' && key.unicode_char != '\b'
          && key.unicode_char != '\n' && key.unicode_char != '\r')
        return GRUB_TERM_CTRL | (key.unicode_char - 1 + 'a');
      else {
        switch (key.unicode_char) {
          case '`':  return '\\';/* It can't be helped */
          case '~':  return '|'; /* It can't be helped */
          case '@':  return '\"';
          case '^':  return '&';
          case '&':  return '\'';
          case '*':  return '(';
          case '(':  return ')';
          case ')':  return '_'; /* It can't be helped */
          case '_':  return '=';
          case '=':  return '^';
          case '+':  return '~';
        /*case ' ':  return '\'; Not available */
        /*case ' ':  return '|'; Not available */
          case '[':  return '@';
          case '{':  return '`';
          case ']':  return '[';
          case '}':  return '{';
        /*case ';':  return ';'; Same code */
          case ':':  return '+';
          case '\'': return ':';
          case '\"': return '*';
          case '\\': return ']';
          case '|':  return '}';
        /*case ',':  return ','; Same code */
        /*case '<':  return '<'; Same code */
        /*case '.':  return '.'; Same code */
        /*case '>':  return '>'; Same code */
        /*case '/':  return '/'; Same code */
        /*case '?':  return '?'; Same code */
        /*case ' ':  return '\'; Not available */
        /*case ' ':  return '_'; Not available */
        }
        return key.unicode_char;
      }
    }
...

変更後にmakeすれば、変更後のキーマップで入力ができる。
上段:SHIFTキーを押しながら、左から右へ、上から下へキーボードを順番に押した。
下段:SHIFTキーを押さずに、左から右へ、上から下へキーボードを順番に押した。

GRUBでコマンドを使用するなら、アンダーバーは使いそうだけれど、[SHIFT]+[0]で出るのを忘れそう…
かといって、他に割り当てるのもどうかと思うので…これで割り切り。

フォントの変更

解像度を上げた関係で、フォントが小さく見えている。
もうちょっと大きくしたい。

makeで作られたunicode.pf2を差し替えた後、build-efi-imageでGRUBイメージを作り、sbsignで署名し、/boot/efi/EFI/ubuntu/grubx64.efiを差し替えれば、作成したフォントで表示されるようになる。

実際に、2種類のフォントを試してみた。

$ grub-mkfont -o unicode.pf2 -s 24 /usr/share/fonts/truetype/unifont/unifont.ttf
$ grub-mkfont -o unicode.pf2 -s 24 /usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf

※フォント名をunicode.pf2としているから、makeする度にフォントを作り直す必要あり。

grub-mkfontでビットマップフォントに変換しているのだけれど…

  • unifontは明らかに品質が落ちている。
    • makeの時にはビットマップフォント(/usr/share/fonts/X11/misc/unifont.pcf.gz)が使われており、これがとても品質が高いのできれいに見えていた。
    • 変換による品質の低下がかなりはっきりと分かる。
      BOLDも試してみたが、これはちょっとレトロな雰囲気になって面白いかもしれない。
    • 日本語も含まれていてサイズは大きい。
      日本語環境でupdate-grubすると、GRUBが日本語表示に変わるが、これが表現できる。
  • DejaVuSansMonoも品質は落ちている。
    • でも、unifontよりは見栄えがいい。
    • サイズは小さいが、日本語は含まれていない。

といった特徴がある。

使えるコマンドを増やす

元々、GRUBバイナリをいじりはじめたのは、セキュアブート環境でvideoinfoコマンドが使えるようにするためだった。
だいぶ深入りして、大変なことになっちゃってるけれども…

せっかくなので、videoinfoコマンドを使えるようにしておこう。
これには、EFIイメージを作るスクリプトを少しだけ改造して実行する。

debian/build-efi-images

...
        raid6rec
        "
GRUB_MODULES="$CD_MODULES
        videoinfo
        "
NET_MODULES="$CD_MODULES
...

※赤文字部分を追加

build-efi-imageでGRUBイメージを作り、sbsignで署名し、/boot/efi/EFI/ubuntu/grubx64.efiを差し替えれば、videoinfoコマンドのビルトインができており、セキュアブート環境で使えるようになる。

モジュールの追加は何でもかんでもすれば良い、というものでもなくて、使うものを入れる感じで。
メインPCでuhciとかohciを入れて試したら、GRUBがうまく動かなくなり、メニューも表示されなくなった。

署名と差し替え

入れたカスタマイズを反映させ、再起動して動作を確認する。

$ sudo debian/build-efi-images ./grub-mkimage ./grub-core /usr/local/lib/grub/x86_64-efi ubuntu x86_64-efi x64 debian/sbat.ubuntu.csv.in ubuntu
$ sudo sbsign --key /var/lib/shim-signed/mok/MOK.priv --cert /var/lib/shim-s
igned/mok/MOK.pem --output /boot/efi/EFI/ubuntu/grubx64.efi /usr/local/lib/grub/x86_64-efi/grubx64.efi
Signing Unsigned original image

問題ないようなら、/usr/local/lib/grub/x86_64-efi/grubx64.efiをメインPCに持って行って、署名してから/boot/efi/EFI/ubuntu/grubx64.efiに差し替える。

実際にメインPCで動かしてみたけれど、問題なく動作している。
キー入力をする度にswitchでチェックをする仕掛けが足されているものの、速度が落ちているといったこともない。
(まぁ、人間のキー入力の方が圧倒的に遅いに決まっている)

OK!以上でカスタマイズ終了。

調べたこと

Ubuntuでの取り扱い

at_keyboardを実行した途端に、キーボード入力を受け付けなくなることについては、既にバグとして報告されているけれど、重要度はLowとされていた。
Launchpad / GRUB2 freezes after loading at_keyboard

確かに、今回はこのテーマでやっているので注目しているが、ほとんどの場合OSが無事に起動できれば良くて、メニューで選択することもまれだし、メニューを表示させるにしても、カーソルキーでアイテムが選択できれば良いから、優先度はグッと下がってしまうのだろう。

さらに、どうやらUEFIの環境では、GRUBはUEFIとキーコードのやりとりをしているように見えている。
ファームウェアに依存するところが大きくて、どうにもできないのかなと思われた。

とはいえ、いざ問題が発生して何かをしようとしたとき、日頃使っていない英語キーボード配列を念頭に置くのは厳しい。
しかも、文法からして割と使う括弧とか等号とかが違っているので、かなりキツい。
英語キーボードを買えばいいじゃん!という話もあるが、それ、どこに置いとくんだよ…と。

ということで、やれるとこまでやってみたのが今回の記事。

UEFIの仕様

色々調べているうちに、UEFIの仕様にたどり着いた。
UEFI Specification / Protocols — Console Support
UEFI Specification / B. Console

ちゃんと読んでいないけれど、一見してUSキーボードだけを相手にしているように見える。

ゆっくり読んだら、何かを見つけられるかもしれない。

2.12~rc1ビルドメモ

パッケージングガイドが教えてくれるパッケージをインストールした後、GRUBをビルドしてみると、不足しているものが幾つも見つかる。
その時に表示されたメッセージと、追加するパッケージをメモしておく。

$ sudo apt install -y gnupg pbuilder ubuntu-dev-tools apt-file
$ pull-lp-source grub2-unsigned
$ cd grub2-unsigned-2.12~rc1

configureを実行(1回目)。

$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
configure: error: bison is not found

 ↓↓↓
$ sudo apt install -y bison
...
The following NEW packages will be installed:
  bison m4
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
...

configureを実行(2回目)。

$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
configure: error: flex is not found

 ↓↓↓
$ sudo apt install -y flex
...
The following NEW packages will be installed:
  flex libfl-dev libfl2
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
...

configureを実行(3回目)。
ここで、とりあえず設定は完了するものの、幾つか不足しているものがある。

$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
*******************************************************
GRUB2 will be compiled with following components:
Platform: x86_64-efi
With devmapper support: No (need libdevmapper header)
With memory debugging: No
With disk cache statistics: No
With boot time statistics: No
efiemu runtime: No (not available on efi)
grub-mkfont: No (need freetype2 library)
grub-mount: No (need fuse or fuse3 libraries)
starfield theme: No (No build-time grub-mkfont)
With libzfs support: No (need zfs library)
Build-time grub-mkfont: No (need freetype2 library)
Without unifont (no build-time grub-mkfont)
Without liblzma (no support for XZ-compressed mips images) (need lzma library)
With stack smashing protector: No
*******************************************************

 ↓↓↓
$ sudo apt install -y unifont libfreetype6-dev libfuse3-dev libzfslinux-dev liblzma-dev
...
The following NEW packages will be installed:
  fonts-unifont libbrotli-dev libfontenc1 libfreetype-dev libfreetype6-dev libfuse3-dev liblzma-dev libnvpair3linux
  libpcre2-16-0 libpcre2-32-0 libpcre2-dev libpcre2-posix3 libpng-dev libpng-tools libselinux1-dev libsepol-dev
  libssl-dev libuutil3linux libzfs4linux libzfsbootenv1linux libzfslinux-dev libzpool5linux psf-unifont unifont
  x11-common xfonts-encodings xfonts-unifont xfonts-utils zlib1g-dev
0 upgraded, 29 newly installed, 0 to remove and 0 not upgraded.
...

configureを実行(4回目)。
2つが有効になったけれども、まだ不足している…

$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
*******************************************************
GRUB2 will be compiled with following components:
Platform: x86_64-efi
With devmapper support: No (need libdevmapper header)
With memory debugging: No
With disk cache statistics: No
With boot time statistics: No
efiemu runtime: No (not available on efi)
grub-mkfont: No (need freetype2 library)
grub-mount: No (need fuse or fuse3 libraries)
starfield theme: No (No build-time grub-mkfont)
With libzfs support: Yes
Build-time grub-mkfont: No (need freetype2 library)
Without unifont (no build-time grub-mkfont)
With liblzma from -llzma (support for XZ-compressed mips images)
With stack smashing protector: No
*******************************************************

ちょっと方向を変えて、autogen.shを実行(1回目)。

$ ./autogen.sh
...
./autogen.sh: line 112: autoreconf: command not found

 ↓↓↓
$ sudo apt install -y autoconf
...
The following NEW packages will be installed:
  autoconf automake autotools-dev
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
...

autogen.shを実行(2回目)。

$ ./autogen.sh
...
autoreconf: running: autopoint --force
Can't exec "autopoint": No such file or directory at /usr/share/autoconf/Autom4te/FileUtils.pm line 293.
autoreconf: error: autopoint failed with exit status: 2

 ↓↓↓
$ sudo apt install -y autopoint
...
The following NEW packages will be installed:
  autopoint
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
...

autogen.shを実行(3回目)。

$ ./autogen.sh
...
autoreconf: running: /usr/bin/autoconf --force
configure.ac:277: error: possibly undefined macro: AC_SUBST
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.
configure.ac:442: error: possibly undefined macro: AC_CHECK_HEADERS
configure.ac:465: error: possibly undefined macro: AC_DEFINE
configure.ac:545: error: possibly undefined macro: AC_LINK_IFELSE
configure.ac:1724: error: possibly undefined macro: AC_LANG_CALL
autoreconf: error: /usr/bin/autoconf failed with exit status: 1

これはちょっと困った…と思って探してみると、答えを教えてくれた。
stack overflow / possibly undefined macro: AC_SUBST

$ sudo apt install -y pkg-config
...
The following NEW packages will be installed:
  pkg-config
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
...

autogen.shを実行(4回目)。

$ ./autogen.sh
...
autoreconf: Leaving directory '.'

configureを実行(5回目)。

$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
*******************************************************
GRUB2 will be compiled with following components:
Platform: x86_64-efi
With devmapper support: No (need libdevmapper header)
With memory debugging: No
With disk cache statistics: No
With boot time statistics: No
efiemu runtime: No (not available on efi)
grub-mkfont: Yes
grub-mount: Yes
starfield theme: Yes
With DejaVuSans font from /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
With libzfs support: Yes
Build-time grub-mkfont: Yes
With unifont from /usr/share/fonts/X11/misc/unifont.pcf.gz
With liblzma from -llzma (support for XZ-compressed mips images)
With stack smashing protector: No
With quiet boot: No
*******************************************************

ようやく作りたい形になったので、makeを実行。
こんな感じでエラーなく終了していれば、ビルドができている。

$ make
...
make[2]: Leaving directory '/home/rohhie/work/grub2-unsigned-2.12~rc1/util/bash-completion.d'
make[1]: Leaving directory '/home/rohhie/work/grub2-unsigned-2.12~rc1'

2.06ビルドメモ

2.12~rc1とほぼ同じなのだけれども、少しだけ違う問題が発生したのでメモしておく。

$ sudo apt install -y gnupg pbuilder ubuntu-dev-tools apt-file
$ pull-lp-source grub2-unsigned jammy
$ grub2-unsigned-2.06/

configureを実行(1回目)。

$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
configure: error: bison is not found

 ↓↓↓
$ sudo apt install -y bison
...
The following NEW packages will be installed:
  bison m4
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
...

configureを実行(2回目)。

$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
configure: error: flex is not found

 ↓↓↓
$ sudo apt install -y flex
...
The following NEW packages will be installed:
  flex libfl-dev libfl2
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
...

configureを実行(3回目)。
ここで、とりあえず設定は完了するものの、幾つか不足しているものがある。

$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
*******************************************************
GRUB2 will be compiled with following components:
Platform: x86_64-efi
With devmapper support: No (need libdevmapper header)
With memory debugging: No
With disk cache statistics: No
With boot time statistics: No
efiemu runtime: No (not available on efi)
grub-mkfont: No (need freetype2 library)
grub-mount: No (need fuse or fuse3 libraries)
starfield theme: No (No build-time grub-mkfont)
With libzfs support: No (need zfs library)
Build-time grub-mkfont: No (need freetype2 library)
Without unifont (no build-time grub-mkfont)
Without liblzma (no support for XZ-compressed mips images) (need lzma library)
With stack smashing protector: No
*******************************************************

 ↓↓↓
$ sudo apt install -y unifont libfreetype6-dev libfuse3-dev libzfslinux-dev liblzma-dev
...
The following NEW packages will be installed:
  fonts-unifont libbrotli-dev libfontenc1 libfreetype-dev libfreetype6-dev libfuse3-dev liblzma-dev libnvpair3linux
  libpcre2-16-0 libpcre2-32-0 libpcre2-dev libpcre2-posix3 libpng-dev libpng-tools libselinux1-dev libsepol-dev
  libssl-dev libuutil3linux libzfs4linux libzfsbootenv1linux libzfslinux-dev libzpool5linux psf-unifont unifont
  x11-common xfonts-encodings xfonts-unifont xfonts-utils zlib1g-dev
0 upgraded, 29 newly installed, 0 to remove and 0 not upgraded.
...

configureを実行(4回目)。
2つが有効になったけれども、まだ不足している…

$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
*******************************************************
GRUB2 will be compiled with following components:
Platform: x86_64-efi
With devmapper support: No (need libdevmapper header)
With memory debugging: No
With disk cache statistics: No
With boot time statistics: No
efiemu runtime: No (not available on efi)
grub-mkfont: No (need freetype2 library)
grub-mount: No (need fuse or fuse3 libraries)
starfield theme: No (No build-time grub-mkfont)
With libzfs support: Yes
Build-time grub-mkfont: No (need freetype2 library)
Without unifont (no build-time grub-mkfont)
With liblzma from -llzma (support for XZ-compressed mips images)
With stack smashing protector: No
*******************************************************

ちょっと方向を変えて、autogen.shを実行(1回目)。

$ ./autogen.sh
Importing unicode...
./autogen.sh: line 20: python: command not found

 ↓↓↓
$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1
update-alternatives: using /usr/bin/python3.10 to provide /usr/bin/python (python) in auto mode
$ python --version
Python 3.10.12

autogen.shを実行(2回目)。

$ ./autogen.sh
...
./autogen.sh: line 99: autoreconf: command not found

 ↓↓↓
$ sudo apt install -y autoconf
...
The following NEW packages will be installed:
  autoconf automake autotools-dev
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
...

autogen.shを実行(3回目)。

$ ./autogen.sh
...
autoreconf: running: autopoint --force
Can't exec "autopoint": No such file or directory at /usr/share/autoconf/Autom4te/FileUtils.pm line 293.
autoreconf: error: autopoint failed with exit status: 2

 ↓↓↓
$ sudo apt install -y autopoint
...
The following NEW packages will be installed:
  autopoint
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
...

autogen.shを実行(4回目)。

$ ./autogen.sh
...
configure.ac:433: error: possibly undefined macro: AC_CHECK_HEADERS
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.
configure.ac:456: error: possibly undefined macro: AC_DEFINE
configure.ac:536: error: possibly undefined macro: AC_LINK_IFELSE
configure.ac:1638: error: possibly undefined macro: AC_LANG_CALL
autoreconf: error: /usr/bin/autoconf failed with exit status: 1

これはちょっと困った…と思って探してみると、答えを教えてくれた。
stack overflow / possibly undefined macro: AC_SUBST

$ sudo apt install -y pkg-config
...
The following NEW packages will be installed:
  pkg-config
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
...

autogen.shを実行(5回目)。

$ ./autogen.sh
...
autoreconf: Leaving directory '.'

configureを実行(5回目)。

$ ./configure --with-platform=efi --target=x86_64 --disable-werror
...
*******************************************************
GRUB2 will be compiled with following components:
Platform: x86_64-efi
With devmapper support: No (need libdevmapper header)
With memory debugging: No
With disk cache statistics: No
With boot time statistics: No
efiemu runtime: No (not available on efi)
grub-mkfont: Yes
grub-mount: Yes
starfield theme: Yes
With DejaVuSans font from /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
With libzfs support: Yes
Build-time grub-mkfont: Yes
With unifont from /usr/share/fonts/X11/misc/unifont.pcf.gz
With liblzma from -llzma (support for XZ-compressed mips images)
With stack smashing protector: No
With quiet boot: No
*******************************************************

ようやく作りたい形になったので、makeを実行。
こんな感じでエラーなく終了していれば、ビルドができている。

$ make
...
make[2]: Leaving directory '/home/rohhie/work/grub2-unsigned-2.06/util/bash-completion.d'
make[1]: Leaving directory '/home/rohhie/work/grub2-unsigned-2.06'

デバッグログ

debug=allの状態で、at_keyboardを有効化させてみた。
debug=lexer,verify といった設定ができるようだ。

ソースを見ると、at_keyboard関連のログには「atkeyb」と表示される見込み。

だが、実際にやってみると、atkeybのログは出力されなかった。
以下は、画面上にログが表示されたものを転記したものだが、差もほとんどない。
tmp関連?でログが出力されていることくらいで、at_keyboardが動かない手がかりは得られなかった。

VMware Player / GRUB 2.12~rc1

grub> set debug=all
grub> terminal_input at_keyboard
script/lexer.c:336:lexer: token 288 text [terminal_input]
script/script.c:50:scripting: malloc 0xbf09f080
script/script.c:50:scripting: malloc 0xbf09f040
script/script.c:163:scripting: arglist
script/script.c:50:scripting: malloc 0xbf09efe0
script/lexer.c:336:lexer: token 288 text [at_keyboard]
script/script.c:50:scripting: malloc 0xbf09ef80
script/script.c:50:scripting: malloc 0xbf09f040
script/script.c:163:scripting: arglist
script/script.c:50:scripting: malloc 0xbf09eee0
script/lexer.c:336:lexer: token 259 text [
]
script/script.c:50:scripting: malloc 0xbf09ee80
script/script.c:50:scripting: malloc 0xbf09ee40
script/script.c:198:scripting: cmdline
script/script.c:50:scripting: malloc 0xbf09ede0
script/lexer.c:336:lexer: token 0 text []
script/script.c:50:scripting: malloc 0xbf09f1a0
script/script.c:50:scripting: malloc 0xbf09eda0
kern/verifiers.c:214:verify: string: terminal_input at_keyboard, type: 2
script/script.c:50:scripting: malloc 0xbf09ed60
script/script.c:50:scripting: malloc 0xbf09eda0
script/script.c:50:scripting: malloc 0xbf09f1a0
script/script.c:50:scripting: malloc 0xbf09ede0
script/script.c:50:scripting: malloc 0xbf09ee40
script/script.c:50:scripting: malloc 0xbf09ee80
script/script.c:50:scripting: malloc 0xbf09eee0
script/script.c:50:scripting: malloc 0xbf09ef40
script/script.c:50:scripting: malloc 0xbf09ef80
script/script.c:50:scripting: malloc 0xbf09efe0
script/script.c:50:scripting: malloc 0xbf09f040
script/script.c:50:scripting: malloc 0xbf09f080

メインPC / GRUB 2.06

grub> set debug=all
grub> terminal_input at_keyboard
script/lexer.c:336:lexer: token 288 text [terminal_input]
script/script.c:50:scripting: malloc 0x7f7b24c0
script/script.c:50:scripting: malloc 0x7f7b2480
script/script.c:163:scripting: arglist
script/script.c:50:scripting: malloc 0x7f7b2420
script/lexer.c:336:lexer: token 288 text [at_keyboard]
script/script.c:50:scripting: malloc 0x7f7b23c0
script/script.c:50:scripting: malloc 0x7f7b2380
script/script.c:163:scripting: arglist
script/script.c:50:scripting: malloc 0x7f7b2320
script/lexer.c:336:lexer: token 259 text [
]
script/script.c:50:scripting: malloc 0x7f7b22c0
script/script.c:50:scripting: malloc 0x7f7b2480
script/script.c:198:scripting: cmdline
script/script.c:50:scripting: malloc 0x7f7b2220
script/lexer.c:336:lexer: token 0 text []
script/script.c:50:scripting: malloc 0x7f7b25e0
script/script.c:50:scripting: malloc 0x7f7b25a0
kern/verifiers.c:214:verify: string: terminal_input at_keyboard, type: 2
commands/efi/tpm.c:283: log event, pcr = 8, size = 0x1a, grub cmd: terminal_input at_keyboard
script/script.c:50:scripting: malloc 0x7f7b21e0
script/script.c:50:scripting: malloc 0x7f7b25a0
script/script.c:50:scripting: malloc 0x7f7b25e0
script/script.c:50:scripting: malloc 0x7f7b2220
script/script.c:50:scripting: malloc 0x7f7b2280
script/script.c:50:scripting: malloc 0x7f7b22c0
script/script.c:50:scripting: malloc 0x7f7b2320
script/script.c:50:scripting: malloc 0x7f7b2380
script/script.c:50:scripting: malloc 0x7f7b23c0
script/script.c:50:scripting: malloc 0x7f7b2420
script/script.c:50:scripting: malloc 0x7f7b2480
script/script.c:50:scripting: malloc 0x7f7b24c0

console.cに手を入れるた時には、押されたキーのコードを表示させるようにして、「\|」と「\_」のキーを押しても、GRUBには何も送られてこないことを確認することができた。

setkey(断念)

GRUBのバージョンが1だった時代には、setkeyというコマンドが使えたようだ。
でも、現在はat_keyboardがあるから、setkeyは作られていない。

at_keyboardがうまく動かない場合、consoleでどうにかせざるを得ないので、setkeyコマンドのようなものが使えるといいよなーと探していたら、このメッセージを教えてくれる人がいた。
Debian Bug report logs - #686817 / grub-pc: Add option to change keyboard layout / Message #22

この人は、ext_kbdというコマンドを追加するパッチを提供してくれていて、これが動いたらかなり汎用的だなと思った。
そこで、パッチの中身を実際に手で書いてみることにした。

grub-core/Makefile.core.def

...
module = {
  name = ext_kbd;
  efi = term/efi/ext_kbd.c;
  enable = x86_64_efi; ← 元々はi386_pcになっていた
};

※最後に追加。

i386_pc用だとすると、ちょっと違うかー。

grub/grub-core/term/efi/ext_kbd.c ← これもi386のところに置かれている

...
#include <grub/dl.h>
#include <grub/machine/memory.h>
#include <grub/term.h>
#include <grub/extcmd.h>
#include <grub/types.h>
#include <grub/machine/int.h>

#define  GRUB_SETKEY_KEYMAP_TABLE_SIZE   128

GRUB_MOD_LICENSE ("GPLv3+");

static const struct grub_arg_option options_setkey[] =
  {
    /********************************************************************************************************/
    /*                                                                                                      */
    /* The 'setkey' command does not provide any specific options.                                          */
    /* This entry is required, however, to make the '--help' and '--usage' options work.                    */
...

コンパイルしてみたけれどもエラーが発生していて、見た感じEFIっぽい感じじゃない。
当然だけれど、そのままじゃ無理ですな。

いま、このような活動をしている人もいないみたいなので、どうしても欲しければ自分で作るしかないのだろう。
それよりもat_keyboardを動かしたいような、でもそれUEFI側の制限?ちょっと大変そうだ。

unicode.pf2のサイズの話

GRUBバイナリを作り始めてからずっと思っていたのだけれど、自分で作ったのはサイズが凄く小さい。
何かが漏れている?これで良いといえるの?と不安だったのだが、原因がはっきりと分かった。

フォントだった。

てっきり、unicode.pf2はDejaVuから作られているものと思っていた。
ところがどっこい、unifontから作られていた。

build-grub-mkfont -o unicode.pf2 /usr/share/fonts/X11/misc/unifont.pcf.gz

※build-grub-mkfontはmakeを実行すると呼び出されるコマンド。grub-mkfontとだいたい同じことができるようだけれども、ユーザー向けには作られたものではなく、ヘルプメッセージもない。

unifont.pcf.gzはビットマップフォントで、フォントのサイズは16、多くの言語の文字を含んでいる。
これをビルトインしているのだから、GRUBバイナリのサイズは大きくなる。

一方、今までDejaVuからフォントファイルを作っていたが、これには少なくとも日本語は入っておらず、サイズは小さい。
当然、GRUBバイナリのサイズは小さくなる。

試しに、grub-mkfontコマンドでunifont.pcf.gzからpf2ファイルを作ったところ、全く同じサイズになった。

$ grub-mkfont -o ./unicode2.pf2 /usr/share/fonts/X11/misc/unifont.pcf.gz

当然、/usr/share/fonts/truetype/unifont/unifont.ttfを使ってpf2ファイルを作った場合、サイズが大きくなる。
文字のサイズを大きくすればする程、サイズは加速度的に大きくなる。

フォントの品質向上(断念)

unifont.pcf.gzのサイズは16で、これを大きくすることはできない。
じゃあ、unifont.ttfで大きなフォントを作ればいいじゃん、と作ってみたら品質が悪い。

ならば、品質が良くても字が大きいunifont.pcf.gzを作ればいいじゃん、と考えたのだが、その方法が見つからない。
ttfをpcfに変換する話題は、10年くらい前にあるくらいで、最近はあまりないようだった。

bdfからpf2を作ることができるのでは?と思ったが、それもできなかった。

$ sudo apt install otf2bdf

$ otf2bdf -p 24 -o unicode.bdf /usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf
$ grub-mkfont -o unicode.pf2 ./unicode.bdf
grub-mkfont: error: can't set 37x37 font size: Freetype error 23: invalid pixel size.

フォントのサイズは、pixel_size = point_size * resolution / 72 で計算できる。
FreeType Glyph Conventions / II / II. Glyph Outlines

それで望みのサイズにできたとしても、grub-mkfontはそれを受け付けてくれない。

otf2bdfもFreetypeを使って変換をしているのだろうから、実はあまり変わらないのかもしれないな。
ということで、割り切りとした。

メインPCのこと

メインPCはWindows 11 ProとUbuntu 20.04のデュアルブート環境。
GRUBバイナリをソースからビルドすることを決意するに至った過程をメモしておく。

キーマップが使えない

キーマップというのは at_keyboard というモジュールと連携して使うものらしい。

ところが、以下の設定を入れると、解像度が4Kになり、かつ、キーボードの入力を受け付けない。
BIOSでUSBキーボードのエミュレーション設定も有効にしてみたが、何も変わらなかった。

/etc/default/grub

GRUB_GFXMODE=1920x1200x32
GRUB_TERMINAL_INPUT="at_keyboard"

at_keyboardが正しく動作しない何かが起きているようだ。

以下の設定を入れると、解像度が1Kになり、とりあえずキーボードの入力は受け付けてくれる。

/etc/default/grub

GRUB_GFXMODE=1920x1200x32
GRUB_TERMINAL_INPUT="at_keyboard usb_keyboard"

GRUBのコンソール画面で調べてみると、at_keyboardをインストールした時点でキーボード入力を受け付けなくなる。
usb_keyboardは読み込みで存在しないと怒られていたが、このことで何かの処理がスルーされて、consoleが有効になっていることになる。

ちなみに、setkeyというコマンドも使えないので、このPCでこのバージョンである限り、日本語キーボードには対応できないと結論し、GRUB_TERMINAL_INPUTの設定はコメント化した。

GRUBのアップグレード

at_keyboardがうまく動かないのはGRUBが古いから?と思い、メインPCのUbuntu 20.04を22.04にアップグレードしてみた。
アップグレード自体は何の問題もなく実行できて、色々入れていたカスタマイズも残った状態で22.04が起動してきた。

これによって、GRUBは2.04から2.06にバージョンが上がった。
GRUBが日本語を表示していたので驚いた。

そこで、ここにカスタマイズしたGRUBを適用したところ、Shimの検証を通過できなくなった。

Verification failed: (0x1A) Security Violation

  • MOK.privとMOK.derは2021/10/27に生成されていた。有効期間は100年。
    • プロプライエタリのグラフィックスカードのドライバをインストールするとき、ドライバに署名する必要があり、インストール中の説明を見ながら、Shimに証明書を登録していたもの。
      ドライバへの署名にはDER形式の証明書を使うので、PEM形式の証明書はなかった。
    • GRUBモジュールへの署名にはPEM形式の証明書が必要なので、DER形式のものを変換して生成。
      MOK.privとMOK.pemを使って署名し、Ubuntu 20.04では問題なく動作していた。
  • セキュアブートを無効にすると、問題なく動作する。
    同様に、Shimによる検証を止めれば、問題なく動作する。
    • SBATは、配布されているものと同じものが設定されている。
    • 22.04なのでSBATを含めたGRUBバイナリを作ることができ、順序やアドレスに問題はない。
  • 署名と検証の仕組みにも対応できているように見える。
    • sbverifyによる署名の検証はOK。
    • mokutilで登録済みの証明書を確認すると、MOK.derが2つ目に登録されている。

全く動作しないため、仕方なく新しい秘密鍵と証明書を作成し、Shimに登録して、GRUBモジュールに署名したところ、問題なく起動するようになった。

なぜ、2021年に作られた秘密鍵と証明書では検証がうまく行かないのか、どうにも理解ができない。何か秘密鍵と証明書の形式が変わったのかもしれないし、Revokeされた証明書にでもなっているのかもしれないが、よく分からない。

なお、22.04にアップグレードしてもat_keyboardはうまく動かなかった。
残念だが、仕方がない。

証明書と秘密鍵が使えないことの調査

ファームウェアに登録されているデーターを取り出す。

$ for var in PK KEK db dbx; do efi-readvar -v $var -o ${var}.esl; done
Variable PK, length 808
Variable KEK, length 1560
Variable db, length 3143
Variable dbx, length 12872

取り出したデーターを証明書に変換する。

$ for var in PK KEK db dbx; do sig-list-to-certs $var.esl $var; done

表記意味内容メインPCに入っていたもの
PKPlatform Keyそのマシンのオーナーの鍵
KEKを更新できる
GIGABYTEの証明書(S/N 2d:ec:af:d8:49:08:d7:bf:48:ae:6d:65:35:2e:f9:e6)
KEKKey Exchange Keydb/dbxを更新する鍵Microsoftの証明書(S/N 61:0a:d1:88:00:00:00:00:00:03)
db署名データーベースMicrosoftの証明書(S/N 61:08:d3:c4:00:00:00:00:00:04)
Microsoftの証明書(S/N 61:07:76:56:00:00:00:00:00:08)
dbx失効した署名データーベース

dbとdbxには実行バイナリのハッシュが入ったりもしているようだ。
それにしても数が凄い…とりあえずメインPCは起動しているし、どうしてもダメなら新しい証明書で署名すりゃいいか。

もう時間を掛けすぎだ、割り切りとする。

解像度が大きいと反応が鈍い

検証環境で1K表示はサクサクだ。
じゃあ、メインPCでどうだろう?と思ったら、GRUBを4Kで表示して利用するのは不可能と思う、遅すぎる。
キーを1回叩くと、それがずーっと押されっぱなしになることがあった。

2Kでもキー入力がかなり遅延して厳しい。
1K(1920x1080)という設定はなく、1920x1200が用意されていたが、これも遅い。
挙げ句に、キーを1回叩くと2回入力されることがあった。

1440x900x32でどうにか使える感じ。
32ビットカラーしか選択肢に出てこないので、色味を減らして高速化させることもできない。

これについても情報を探してみたが、対応策は解像度を下げることだけだった。
UEFIで用意されているのがこのドライバーなので、これ以上できることはないということのようだった。

サスティナビリティ

GRUBを起動している間、CPUなのかGPUなのかわからないが、ファンが全開で回る。
かなり発熱すると見られる。

どうしてこうなるのかはよく分からないが、これはきっと電気が無駄遣いされている。
(ESXiはOSが起動してからの話だから少しズレるけれど)先日、長期間発熱にさらされたグラフィックカードが壊れたので、取り替えたところだ。

サスティナビリティの観点から、低電力でGRUBやOSのコンソールが表示できる方法があるのか知りたいなぁ。

当面はメインPCでGRUBを使うのは最小限にするとして、ゆっくり調べていこう。
GUIを備えたOSの上で仮想マシンを動かして、GRUBやESXiを動かせばいいのかな。

さいごに

GRUBについて調べはじめて、色々な制限があると知る。
制限を突破するために、grub-mkimageについて学習したが、それでもat_keyboardをどうにもできなかった。

じゃあしょうがない、ソースからビルドして、できるとこまでやってみるか…なんて考えたら、3週間が経過していた。
元記事が5万文字、この記事も3万5千文字…

ちょっとソースに手を入れようとしたら、こんなに大変なのか。
すっごい制限ありそうだし。

メンテナーの人達は凄い。

ところで、今回情報を探している中で、GRUBにパスワードを掛けている人が結構いそうだった。キーコードが違うから、注意深くゆっくり入力する必要がある、何カ所かに書かれていた。
そういう場合はどうするかというと…パスワードを英語レイアウトで入力して設定すれば、キーボードの刻印通りに入力ができる訳ですよね。でも、そんなことは分かっているはずだよな…あれはきっと方便ですな。

今回のことで[|][\][_]の3つ以外は刻印通りに入力することができるようになった。
もう少しGRUBでできることを増やしていきたいな、緊急事態の対応ができるように。

広告

コメントはこちらから お気軽にどうぞ ~ 投稿に関するご意見・感想・他