1
0

More than 3 years have passed since last update.

複数バージョンから選べるNetBSDインストーラーイメージ

Last updated at Posted at 2019-12-13

この記事は、NetBSD Advent Calendar 2019の14日目の記事です。

multiversion

NetBSDの UEFI ブートローダー

build.sh を

build.sh -m amd64 -R RELEASEDIR release install-image

と実行すると、RELEASEDIR/images/NetBSD-VERSION-amd64-uefi-install.img.gz ができます。
このファイルをddとかでUSBメモリに書き込むと UEFI から起動できるインストールメディアになります。

インストーラーイメージは、GPTでパーティションが切られていて、次のように構成されています。

   start     size  index  contents
        0        1         PMBR
        1        1         Pri GPT header
        2       32         Pri GPT table
       34     2014         Unused
     2048   262144      1  GPT part - EFI System
   264192  2908160      2  GPT part - NetBSD FFSv1/FFSv2
  3172352     2015         Unused
  3174367       32         Sec GPT table
  3174399        1         Sec GPT header

UEFIブートローダーのソースを読んでいた時1、GPTパーティションを hd0a, hd0b, ... のように指定できることに気付きました。
上の構成では、 EFI パーティションが hd0a、NetBSDが hd0b になります。 ということは、 もう一つNetBSDのパーティションを作ってブートローダーのプロンプトから

 boot hd0c:netbsd

と起動してやれば、追加のパーティションから NetBSDが起動できそうです。一個のUSBメモリで -current、9.0_BETA、8.1 を選んでインストールできるようになるわけです。

マルチバージョン化の手順

  1. 元のインストールイメージの先頭からEFIパーティションまでをコピーして出力イメージとする。
  2. 出力イメージにNetBSDパーティションを入れる部分を確保して、さらに1MiBytesの領域を追加。これはGPTのセカンダリテーブルに使われる。
  3. GPTテーブルを新規作成2。元イメージの構成にあわせてEFIパーティションを追加。
  4. 各バージョンについて、
    1. NetBSDのGPTパーティションを作成。このパーティションのGUIDを後で使用する。
    2. 元のインストールイメージからNetBSDパーティションの部分を取り出す。
    3. ファイルシステムイメージをマウントして、
    4. /etc/fstab の ルートデバイスのNAME= 指定を新しいGUIDに書き換える。
    5. /boot.cfg からメニューを取得。最初のNetBSDパーティションでは、/boot.cfg を書き換えてメニューを増やす。
    6. 更新したファイルシステムイメージを出力イメージの中に書き込む

以上を実行するシェルスクリプトを github に置きました。

作成例

-current, 9.0_BETA, 8.1_STABLE の三つのイメージからマルチバージョン化したインストーラーイメージのGPTパーティションは、次のようになります。

   start     size  index  contents
        0        1         PMBR
        1        1         Pri GPT header
        2       32         Pri GPT table
       34     2014         Unused
     2048   262144      1  GPT part - EFI System
   264192  2908160      2  GPT part - NetBSD FFSv1/FFSv2          # -current
  3172352  2908160      3  GPT part - NetBSD FFSv1/FFSv2          # 9.0_BETA
  6080512  2560000      4  GPT part - NetBSD FFSv1/FFSv2          # 8.1_STABLE
  8640512     2015         Unused
  8642527       32         Sec GPT table
  8642559        1         Sec GPT header

ブートローダーのメニュー

boot.cfg
banner=Welcome to the NetBSD/amd64 (multiple versions) installation image
banner================================================================================
banner=
banner=If you encounter a problem while booting, report a bug at
banner=https://www.NetBSD.org/.
menu=Install NetBSD/amd64 9.99.17:boot netbsd
menu=Install NetBSD/amd64 8.1_STABLE:boot hd0d:netbsd
menu=Install NetBSD/amd64 8.1_STABLE (no ACPI):boot hd0d:netbsd -2
menu=Install NetBSD/amd64 8.1_STABLE (no ACPI, no SMP):boot hd0d:netbsd -12
menu=Install NetBSD/amd64 9.0_BETA:boot hd0c:netbsd
menu=Drop to boot prompt:prompt
timeout=30
clear=1

おまけ

gpt(8)コマンドの不思議仕様

この記事を書いていて気付いたのですが、TOOLDIR/bin/nbgpt3 の引数の順番が gpt(8) と異なっています。

/sbin/gpt command args device
TOOLDIR/bin/nbgpt device command args

gpt(8)のソースを見ると、argv[0]が "gpt" の時とそうでない時で、わざわざ動作を変えています。
src/sbin/gpt/Makefile を見ると、

#LINKS=  ${BINDIR}/gpt ${BINDIR}/gptlabel
#MLINKS= gpt.8 gptlabel.8

となっていて、コメントアウトされていますが、gptlabel という名前にして引数の順番を変更しようとしたのかな、と推測します。
gptコマンドの引数の順番は、atactl, dkctl などと統一がとれてなくて気持悪い、とは私も思うので意図は理解できますが、gpt と nbgpt で動作が違うのはダメじゃないかな。

Linux の mount -o loop

この作業では、ファイルシステムイメージの中身をいぢる手順があります。 (/etc/fstab と /boot.cfg を変更)

NetBSDでこれをやるには、

vndconfig -c vnd0 image_file
mount /dev/vnd0d /mnt
edit /mnt/foo
umount /mnt
vndconfig -u vnd0

と実行します。Linuxでは、同等のことを

mount -o loop image_file /mnt
edit /mnt/foo
umount /mnt

と、より簡単にできます。NetBSDの方法だと、vnd0 がすでに使われている場合に失敗するので、空いているvndを探すという手間も発生します。

ちょっと頑張れば、mount -o loop は実装できそうな気がするんですが……


  1. ブートローダーを調べたかったのではなくて、libsa (stand alone library: ブートローダーなどNetBSDが起動する前の環境で動作するプログラム用のライブラリ) で UEFIアプリケーションが作れるか調べていた。で、横道に逸れたのでその件は進捗してない。  

  2. 元イメージのGPTテーブルをそのまま使ってもよいが、その場合はセカンダリテーブルもコピーする必要があって面倒。 

  3. build.sh tools で作成されるホストツールの一つ 

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0