USBフラッシュメモリーを差し込むとUbuntuが起動し、ブラウザが動作するとっても軽い環境を作れないか、と思い立った。
以前、KNOPPIXを使わせてもらっていたことがあり、とても便利だったのをイメージしている。
そもそも、UbuntuのインストールディスクはLive CDになっていて、アレを軽い感じに仕上げればいいのかなと考えたが、実際には手順を整理するのがやっと。
調べていくと、Live CDとLive USBというのがあるようで、定義を確認してみた。
今回は、Live CDを作る。CDという名前ではあるがDVDにしか入らないサイズになった。
過去のUbuntuを使ったISOの作成もやってみている。練習として、とても良いものだった。
Live CDを作ってみる
最初は、記事のずっと下のほう live-helper でLiveを作成した。
見つけた記事が日本語だったのと、教えてくれていることをそのままに実行すればできそうだったので、感覚をつかむのにとても良かった。
Ubuntu 20.04ではlive-helperというパッケージがなく、live-buildに変わっていた。
探してみると、ここで詳細かつ確実な手順を教えてくれていることが分かった。
Github / How to create a custom Ubuntu live from scratch
今回、教えてくれている手順に、日本語対応やセキュアブートへの対応など、細々した改変を入れているので、その箇所には[改変]と記載している。
通常は、コマンド行の先頭を#と$で書き分けたりしているのだが、コピペするコマンドがとにかく多いので、
ベースとなる環境で、一般ユーザーとして入力するコマンド
chrootした環境で、rootとして入力するコマンド
と、文字色・背景色で書き分けておく。
ミラーサーバー
Live CDを作成するにあたっては、大量のパッケージをダウンロードしてくることになる。
気に入らなければやり直しもするだろうし、ダウンロード先のサーバーの状態によってはダウンロードにとても時間が掛かったりもする。
こうしたことを考慮すると、自分でミラーサーバーを立てて、ローカルで自由に使えるようにするのが良いのではなかろうか。
ということで、実際にミラーサーバーを立ててみたところ、とても快適な作成環境を作ることができた。
(仮想ゲスト2台=ミラーサーバー+作業環境 を同じホストの上で動かしたところ、もう爆速)
最初の全パッケージのダウンロードには6時間ぐらい掛かったけれど、そんなの寝ている間に終わってしまう。
立てたミラーサーバーは、mirror.hogeserver.hogeddns.jp と記載している。
これは、ローカルでは実際に名前解決ができて使えるミラーサーバーになっている。
作業環境の構築
過去にやったことが影響するのも嫌なので、まっさらな環境で作業をすることにした。
VMware Workstation 16 Player + Ubuntu 20.04 LTS Desktop
今回の手順を試すと、ISOイメージができあがった段階でハードディスクイメージのサイズが16.7GB程になった。多少余裕を持たせておいた方が無難。
また、ファイルの圧縮処理が入りCPUを使うので、コアは多めに割り当てても良いのではないかと思う。
メモリは4GB程度は必要。
仮想ホストは、UEFI+セキュアブートにしておいた。
CreateLive.vmx
firmware = "efi" efi.legacyBoot.enabled = "FALSE" uefi.secureBoot.enabled = "TRUE"
この状態でUbuntu 20.04のISOをセットしてインストール。
求められるままにアップデートをしてインストール完了。
ついでに、open-vm-tools-desktopがインストールされているか確認。なければ入れておく。
コマンドをコピペできるので、便利。
シャットダウン後、仮想マシン設定でフォルダの共有として VMware という名前のものを用意した。
後でISOファイルを簡単に取り出すため。
この段階でハードディスクイメージをバックアップした。
サイズは8.5GB程だった。
最初に一度やること
[改変]構築に必要なパッケージをインストールする。
syslinux-commonとisolinuxはISOLINUXで起動する場合に必要になるものだが、念のため。
sudo apt install binutils debootstrap squashfs-tools xorriso grub-pc-bin grub-efi-amd64-bin mtools syslinux-common isolinux
[改変]署名済みのブートローダーとGrubがインストールされていることを確認しておく。
dpkg -l grub-efi-amd64-signed shim-signed Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) ||/ Name Version Architecture Description +++-=====================-========================-============-=============================================================== ii grub-efi-amd64-signed 1.167.2+2.04-1ubuntu44.2 amd64 GRand Unified Bootloader, version 2 (EFI-AMD64 version, signed) ii shim-signed 1.40.7+15.4-0ubuntu9 amd64 Secure Boot chain-loading bootloader (Microsoft-signed binary)
※セキュアブートしているシステムでのことなので、ちゃんとインストールされているはず。
Live CDの作成環境を作る
debootstrapは、DebianシステムをMIRRORからTARGETにインストールして起動できるようにするコマンドで、Ubuntuでも使える。
次の実行すると $HOME/live-ubuntu-from-scratch/chroot/var/cache/apt/archives/ にパッケージをダウンロードしてきて、展開・設定する。
ubuntu manpage / debootstrap
mkdir $HOME/live-ubuntu-from-scratch sudo debootstrap --arch=amd64 --variant=minbase focal $HOME/live-ubuntu-from-scratch/chroot http://ja.archive.ubuntu.com/ubuntu/ あるいは… mkdir $HOME/live-ubuntu-from-scratch sudo debootstrap --arch=amd64 --variant=minbase focal $HOME/live-ubuntu-from-scratch/chroot http://ftp.riken.go.jp/Linux/ubuntu/ ミラーサーバーを立てたなら… mkdir $HOME/live-ubuntu-from-scratch sudo debootstrap --arch=amd64 --variant=minbase focal $HOME/live-ubuntu-from-scratch/chroot http://mirror.hogeserver.hogeddns.jp/ubuntu/ I: Retrieving InRelease I: Checking Release signature … I: Configuring apt... I: Configuring libc-bin... I: Base system installed successfully.
variantにはminbaseを指定しているが、以下から選べるようになっている。
設定値 | 効果 |
---|---|
minbase | 必須パッケージとaptのみを含む。 |
buildd | ビルドに必要なパッケージをインストールする。 |
fakechroot | root権限なしでパッケージをインストールする。 一般ユーザーが、その権限のままでchrootされた環境にパッケージをインストールすることを示している模様。 |
無指定 | aptを含む必須・重要の全パッケージを含むインストール。 |
SUITEとしてfocal(20.04のコードネーム)を指定している。
ファイルシステムをマウント。
sudo mount --bind /dev $HOME/live-ubuntu-from-scratch/chroot/dev sudo mount --bind /run $HOME/live-ubuntu-from-scratch/chroot/run
chrootする。
sudo chroot $HOME/live-ubuntu-from-scratch/chroot
追加でファイルシステムをマウントし、環境変数を設定する。
mount none -t proc /proc mount none -t sysfs /sys mount none -t devpts /dev/pts export HOME=/root export LC_ALL=C
chroot環境のホスト名を設定。
echo "ubuntu-fs-live" > /etc/hostname
[改変]aptのsource.listを作成。ubuntu Japanese Team / 日本国内のダウンロードサイトにあるサイトを利用させていただく。
ローカルに立てたミラーを使うこともできて、試行錯誤の段階ではそれもいいと思われるが、リリースの時には公式のものに戻しておくのが良さそうだ。
cat <<EOF > /etc/apt/sources.list deb http://ja.archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse deb-src http://ja.archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse deb http://ja.archive.ubuntu.com/ubuntu/ focal-security main restricted universe multiverse deb-src http://ja.archive.ubuntu.com/ubuntu/ focal-security main restricted universe multiverse deb http://ja.archive.ubuntu.com/ubuntu/ focal-updates main restricted universe multiverse deb-src http://ja.archive.ubuntu.com/ubuntu/ focal-updates main restricted universe multiverse EOF あるいは… cat <<EOF > /etc/apt/sources.list deb http://ftp.riken.go.jp/Linux/ubuntu/ focal main restricted universe multiverse deb-src http://ftp.riken.go.jp/Linux/ubuntu/ focal main restricted universe multiverse deb http://ftp.riken.go.jp/Linux/ubuntu/ focal-security main restricted universe multiverse deb-src http://ftp.riken.go.jp/Linux/ubuntu/ focal-security main restricted universe multiverse deb http://ftp.riken.go.jp/Linux/ubuntu/ focal-updates main restricted universe multiverse deb-src http://ftp.riken.go.jp/Linux/ubuntu/ focal-updates main restricted universe multiverse EOF ミラーサーバーを立てたなら、リリースするまでの試行錯誤は… cat <<EOF > /etc/apt/sources.list deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ focal main restricted universe multiverse deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ focal-security main restricted universe multiverse deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ focal-updates main restricted universe multiverse EOF 等々。
updateする。
apt update
[改変]必要パッケージのインストール。libterm-readline-gnu-perl(Perlのデバッガで履歴機能を有効にするそうだ)は、必要とは言えないと思うので外した。
Ubuntuサーバー構築入門 / libterm-readline-gnu-perlのインストール - PerlのTerm::ReadLine::Gnuモジュール
apt install systemd-sysv
machine-idを構成。machine-idは常に一意であるべきで、同じIDを持つマシンが複数あると不具合を来す、とのこと。
DHCPホスト識別子、カーネルがマシンIDにちなんで名付けられたディレクトリに保管される…等々。
debian wiki / MachineId
dbus-uuidgen > /etc/machine-id mkdir /var/lib/dbus ln -fs /etc/machine-id /var/lib/dbus/machine-id
※ディレクトリがなかったので作成。2022/01/16追記
dpkgがパッケージをインストールする際に、いかなるパッケージがインストールされても、/sbin/initctlをインストールしないように細工。
/bin/trueは、呼び出されたら何もせずに0を戻すプログラム…なるほど、インストールするとサービスを起動するようなパッケージがまともに動かないようにしているということだな、きっと。
Debian クイックリファレンス / 3.5.1 dpkg-divert コマンド
dpkg-divert --local --rename --add /sbin/initctl ln -s /bin/true /sbin/initctl
事前の準備が済んだので、パッケージを更新。
apt upgrade
Live CDの中身を編集
Liveシステムに必要なパッケージをインストールする。※結構時間が掛かる。
apt install \ sudo \ ubuntu-standard \ casper \ lupin-casper \ discover \ laptop-detect \ os-prober \ network-manager \ resolvconf \ net-tools \ wireless-tools \ wpagui \ locales \ grub-common \ grub-gfxpayload-lists \ grub-pc \ grub-pc-bin \ grub2-common
カーネルのインストール。どちらか一方を選択。
apt install --no-install-recommends linux-generic ← カーネル5.4 apt install --no-install-recommends linux-generic-hwe-20.04 ← カーネル5.13
※新しい方が新しいハードウェアに対応できるので追記。2022/08/08
グラフィカルインストーラーをインストールする。※結構時間が掛かる。
apt install \
ubiquity \
ubiquity-casper \
ubiquity-frontend-gtk \
ubiquity-slideshow-ubuntu \
ubiquity-ubuntu-artwork
キーボードの選択画面が表示されたら
Japan → Japanese の順に選択。
コンソールセットアップが表示されたら
Guess optimal character set を選択。
ウィンドウマネージャーのインストール。※結構時間が掛かる。
apt install \
plymouth-theme-ubuntu-logo \
ubuntu-gnome-desktop \
ubuntu-gnome-wallpapers
キーボードはJapanese→Japaneseを選択。
[改変]よく使うアプリケーションのインストール。pingを追加。
apt install \ clamav-daemon \ terminator \ apt-transport-https \ curl \ vim \ nano \ less \ inetutils-ping
Visual Studio Codeのインストール。※インストールしたいならば。
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg install -o root -g root -m 644 microsoft.gpg /etc/apt/trusted.gpg.d/ echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list rm microsoft.gpg apt update apt install code
Google Chromeのインストール。※インストールしたいならば。
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list apt update apt install google-chrome-stable
Java JDK 8のインストール。※インストールしたいならば。
apt install openjdk-8-jdk openjdk-8-jre
使わないアプリケーションの削除。※削除したいならば。
apt purge \ transmission-gtk \ transmission-common \ gnome-mahjongg \ gnome-mines \ gnome-sudoku \ aisleriot \ hitori
最終的に使わなくなったパッケージを削除。
apt autoremove
[改変]言語サポートをインストール。※結構時間が掛かる。
check-language-support -l ja で必要パッケージが分かるので、それをそのまま投入。
ask ubuntu / How can I install one language by command-line
apt install --no-install-recommends `check-language-support -l ja`
[改変]ロケールの設定。デフォルトロケールとして2つ目のja_JP.UTF-8を選択している。最初はこれでMOZCが選択できたようだったけれど、手順を色々と改変していく中で何かが変わってしまったらしく、単に日本語が選択される。
dpkg-reconfigure locales
ロケールとして
en_US ISO-8859-1
en_US.UTF-8 UTF-8
ja_JP.UTF-8.UTF-8
を選択。
デフォルトロケールとして
ja_JP.UTF-8(2つ目)
を選択。
リゾルバの設定。
dpkg-reconfigure resolvconf
YESを選択。
NetworkManagerの設定編集。
/etc/NetworkManager/NetworkManager.conf
[main] rc-manager=resolvconf plugins=ifupdown,keyfile dns=dnsmasq [ifupdown] managed=false [device] wifi.scan-rand-mac-address=no
設定変更を反映。
dpkg-reconfigure network-manager
※NetPlanは入っていないな…。
編集環境の後始末
machine-idを削除。削除しておけば、Live起動したときに自動で生成される。
truncate -s 0 /etc/machine-id
dpkgインストール先の待避を解除。
rm /sbin/initctl dpkg-divert --rename --remove /sbin/initctl
[改変]クリーンアップして、chroot環境を終了する。.bash_historyはexit時に書き込まれるようなので、chrootを抜けてから削除する。
apt clean rm -rf /tmp/* umount /proc umount /sys umount /dev/pts export HISTSIZE=0 exit
sudo rm $HOME/live-ubuntu-from-scratch/chroot/root/.bash_history
マウントポイントの解除。
sudo umount $HOME/live-ubuntu-from-scratch/chroot/dev sudo umount $HOME/live-ubuntu-from-scratch/chroot/run
Live CDに収録するファイルを集める
CDイメージのディレクトリimage、およびサブディレクトリを作り、カーネルをコピーする。
cd $HOME/live-ubuntu-from-scratch mkdir -p image/{casper,isolinux,install} sudo cp chroot/boot/vmlinuz-**-**-generic image/casper/vmlinuz sudo cp chroot/boot/initrd.img-**-**-generic image/casper/initrd
memtest86(BIOS/UEFI)をコピーする。
wgetで取得しているのは、ブータブルUSB用のイメージで、Grubでループバックして起動している。
sudo cp chroot/boot/memtest86+.bin image/install/memtest86+ wget --progress=dot https://www.memtest86.com/downloads/memtest86-usb.zip -O image/install/memtest86-usb.zip unzip -p image/install/memtest86-usb.zip memtest86-usb.img > image/install/memtest86 rm -f image/install/memtest86-usb.zip
マニフェスト(インストールされているパッケージとバージョンの一覧)を作成する。
Ubiquityによるインストールが完了したとき、不要なパッケージが削除されるよう、filesystem.manifest-desktopから不要な行を削除している。
cd $HOME/live-ubuntu-from-scratch sudo chroot chroot dpkg-query -W --showformat='${Package} ${Version}\n' | sudo tee image/casper/filesystem.manifest sudo cp -v image/casper/filesystem.manifest image/casper/filesystem.manifest-desktop sudo sed -i '/ubiquity/d' image/casper/filesystem.manifest-desktop sudo sed -i '/casper/d' image/casper/filesystem.manifest-desktop sudo sed -i '/discover/d' image/casper/filesystem.manifest-desktop sudo sed -i '/laptop-detect/d' image/casper/filesystem.manifest-desktop sudo sed -i '/os-prober/d' image/casper/filesystem.manifest-desktop
chrootで作成した環境を圧縮し、squashfsファイルを作成する。
Liveはこのファイルが展開されて実行されるようだ。
作業にはかなりCPUを使うので、コアを多く与えておくと早くできそうだ。
cd $HOME/live-ubuntu-from-scratch sudo mksquashfs chroot image/casper/filesystem.squashfs printf $(sudo du -sx --block-size=1 chroot | cut -f1) > image/casper/filesystem.size
※ファイルが存在すると mksquashfs が失敗するので、2回目以降は実行前に削除しておく。
インストーラーによくあるREADMEファイルを作成。
cd $HOME/live-ubuntu-from-scratch cat <<EOF > image/README.diskdefines #define DISKNAME Ubuntu from scratch #define TYPE binary #define TYPEbinary 1 #define ARCH amd64 #define ARCHamd64 1 #define DISKNUM 1 #define DISKNUM1 1 #define TOTALNUM 0 #define TOTALNUM0 1 EOF
ブートローダーを準備
UEFI
[改変]UEFI+セキュアブートができるように、署名されたブートローダーとGrubが使いたい。
ファイルをパーティションの如く取り扱う方法をこの手順に教えてもらったので、それを応用してみる。
32MBの空ファイルを作り、それをVFATでフォーマットしてマウントして、そこにGrubをインストールする。
cd $HOME/live-ubuntu-from-scratch
mkdir -p work/bi
cd work
dd if=/dev/zero of=bi.img bs=1M count=32
sudo mkfs.vfat bi.img
sudo mount bi.img bi/
sudo grub-install --target x86_64-efi --efi-directory bi/ --boot-directory=bi/boot/ --removable --uefi-secure-boot
Installing for x86_64-efi platform.
Installation finished. No error reported.
※インストールされるファイルはシステム上にあるけれど、この方法だとあまり考えずに収集できる。
[改変][オプション]Ubuntuは32ビットのブートローダーを提供していない(サポート対象外)。
Debianはサポートしているので、そこからファイルをいただいて盛り込んでいく。
https://packages.debian.org/stable/admin/grub-efi-ia32-signed
https://packages.debian.org/bullseye/shim-signed
https://packages.debian.org/stable/admin/grub-efi-ia32-bin
ダウンロードしてくるファイルはリンクをたどって探すのが良いと思う。
この日は、このファイル名だった。
wget http://ftp.jp.debian.org/debian/pool/main/s/shim-signed/shim-signed_1.38+15.4-7_i386.deb
wget http://ftp.jp.debian.org/debian/pool/main/g/grub-efi-ia32-signed/grub-efi-ia32-signed_1+2.04+20_i386.deb
wget http://ftp.jp.debian.org/debian/pool/main/g/grub2/grub-efi-ia32-bin_2.04-20_i386.deb
mkdir bi32
dpkg-deb -x shim-signed_1.38+15.4-7_i386.deb bi32/
sudo cp --preserve=mode,timestamp bi32/usr/lib/shim/shimia32.efi.signed bi/EFI/BOOT/BOOTIA32.efi
dpkg-deb -x grub-efi-ia32-signed_1+2.04+20_i386.deb bi32/
sudo cp --preserve=mode,timestamps bi32/usr/lib/grub/i386-efi-signed/grubia32.efi.signed bi/EFI/BOOT/GRUBIA32.EFI
dpkg-deb -x grub-efi-ia32-bin_2.04-20_i386.deb bi32/
sudo cp --preserve=mode,timestamp -r bi32/usr/lib/grub/i386-efi bi/boot/grub/
sudo rm -r bi/boot/grub/i386-efi/monolithic/
※grub-efi-ia32-binに含まれていたmonolithic配下のefiのファイルは、署名されているファイルとmd5sum値が違っていたので消している。
[改変]できあがったEFI起動イメージをimageにコピーして、作業用ファイルをアンマウント。
sudo cp -ar bi/boot/ ../image/ sudo cp -ar bi/EFI/ ../image/ sudo umount bi sudo chown 1000:1000 -R ../image/boot/ ../image/EFI/
※オーナー設定をUIDに変更。この作業をする人が1000ならこれでいけるはず。2022/01/16追記。
[改変]64ビットのブートローダーは/efi/boot/grub.cfgを見に行くので、この先で作るgrub.cfgを見に行くように仕掛けておく。
$HOME/live-ubuntu-from-scratch/image/EFI/BOOT/grub.cfg
#search.fs_uuid XXXX-XXXX root search --set=root --file /.disk/info set prefix=(\$root)'/boot/grub' configfile \$prefix/grub.cfg
[改変][オプション]32ビットのブートローダーは/efi/debian/grub.cfgを見に行くので、この先で作るgrub.cfgを見に行くように仕掛けておく。
cd $HOME/live-ubuntu-from-scratch/image mkdir EFI/DEBIAN cat << EOF > EFI/DEBIAN/grub.cfg search --set=root --file /.disk/info set prefix=(\$root)'/boot/grub' configfile \$prefix/grub.cfg EOF
[改変]ISOを作成するときに、起動イメージとして渡すefi.imgファイルを作成する。
[オプション]32ビットのブートローダーを利用する場合は、黄色の行を加える。
cd $HOME/live-ubuntu-from-scratch/image 通常 ( dd if=/dev/zero of=efi.img bs=1M count=10 && \ sudo mkfs.vfat efi.img && \ LC_CTYPE=C mmd -i efi.img efi efi/boot boot boot/grub && \ LC_CTYPE=C mcopy -i efi.img ./EFI/BOOT/grub.cfg ::boot/grub/ && \ LC_CTYPE=C mcopy -i efi.img ./EFI/BOOT/BOOTX64.EFI ::efi/boot/ && \ LC_CTYPE=C mcopy -i efi.img ./EFI/BOOT/grubx64.efi ::efi/boot/ && \ LC_CTYPE=C mcopy -i efi.img ./EFI/BOOT/mmx64.efi ::efi/boot/ && \ mv efi.img ./boot/grub/ ) 32ビットのブートローダーをサポート ( dd if=/dev/zero of=efi.img bs=1M count=10 && \ sudo mkfs.vfat efi.img && \ LC_CTYPE=C mmd -i efi.img efi efi/boot efi/debian boot boot/grub && \ LC_CTYPE=C mcopy -i efi.img ./EFI/DEBIAN/grub.cfg ::efi/debian/ && \ LC_CTYPE=C mcopy -i efi.img ./EFI/BOOT/BOOTIA32.efi ::efi/boot/ && \ LC_CTYPE=C mcopy -i efi.img ./EFI/BOOT/GRUBIA32.EFI ::efi/boot/ && \ LC_CTYPE=C mcopy -i efi.img ./EFI/BOOT/grub.cfg ::boot/grub/ && \ LC_CTYPE=C mcopy -i efi.img ./EFI/BOOT/BOOTX64.EFI ::efi/boot/ && \ LC_CTYPE=C mcopy -i efi.img ./EFI/BOOT/grubx64.efi ::efi/boot/ && \ LC_CTYPE=C mcopy -i efi.img ./EFI/BOOT/mmx64.efi ::efi/boot/ && \ mv efi.img ./boot/grub/ )
Legacy(Grub)
[改変]Legacyで使うGrubイメージcore.imgを生成。EFI/BOOT/grub.cfgを指定しているのは、EFIと同じように/boot/grub/grub.cfgを参照したいから。
cd $HOME/live-ubuntu-from-scratch/image grub-mkstandalone \ --format=i386-pc \ --output=isolinux/core.img \ --install-modules="linux16 linux normal iso9660 biosdisk memdisk search configfile tar ls" \ --modules="linux16 linux normal iso9660 biosdisk search configfile" \ --locales="" \ --fonts="" \ "/boot/grub/grub.cfg=EFI/BOOT/grub.cfg"
[改変]CDブート用のcdboot.imgとcore.imgを結合して、boot.imgを作成。出力先をboot/grub/に変更。
GNU GRUB Manual 2.06:Images / 11 GRUB image files
Qiita / Linuxのブートシーケンス
cat /usr/lib/grub/i386-pc/cdboot.img isolinux/core.img > boot/grub/boot.img
[改変]boot.imgを作成するために作成したcore.imgを削除。
rm isolinux/core.img
[改変]Grubの設定ファイルを作成。元々の手順ではimage/isolinuxにファイルを作成していたが、どうにも起動ディスクに仕立てられなかったので、image/boot/grubに作成している。
cat << EOF > boot/grub/grub.cfg search --set=root --file /.disk/info if loadfont /boot/grub/fonts/unicode.pf2 ; then set gfxmode=auto insmod efi_gop insmod efi_uga insmod gfxterm terminal_output gfxterm else insmod all_video fi set default="0" set timeout=30 menuentry "Try Ubuntu FS without installing" { linux /casper/vmlinuz boot=casper nopersistent toram quiet splash --- initrd /casper/initrd } menuentry "Install Ubuntu FS" { linux /casper/vmlinuz boot=casper only-ubiquity quiet splash --- initrd /casper/initrd } menuentry "Check disc for defects" { linux /casper/vmlinuz boot=casper integrity-check quiet splash --- initrd /casper/initrd } menuentry "Test memory Memtest86+ (BIOS)" { linux16 /install/memtest86+ } menuentry "Test memory Memtest86 (UEFI, long load time)" { insmod part_gpt insmod search_fs_uuid insmod chain loopback loop /install/memtest86 chainloader (loop,gpt1)/efi/boot/BOOTX64.efi } EOF
[改変]併せて、EFIの場合にGrubのメニューが呼び出されるように、/.disk/infoというファイルを作っておく。
mkdir .disk echo "Ubuntu 20.04 from scratch" > .disk/info
Legacy(ISOLINUX)
[改変]USBに書き込んだときにLegacyでも起動できるHybrid ISOにするには、isolinuxが必要とのことで、そのための環境を作る。
このファイルがある・ないは直接関係ないとは思うのだけれども、Rufusというアプリケーションはこのファイルがある・ないでLegacy起動できる・できないを判断しているような節がある。
ISOLINUXを使ったISOを作った場合にも同じ選択肢が現れるように内容をそろえたが、Memtest86のISOは起動のさせ方が分からなかったので省いている。
Syslinux / Syslinux
cd $HOME/live-ubuntu-from-scratch/image cat <<EOF> isolinux/isolinux.cfg UI vesamenu.c32 MENU TITLE Boot Menu DEFAULT linux TIMEOUT 300 MENU RESOLUTION 640 480 MENU COLOR border 30;44 #40ffffff #a0000000 std MENU COLOR title 1;36;44 #9033ccff #a0000000 std MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all MENU COLOR unsel 37;44 #50ffffff #a0000000 std MENU COLOR help 37;40 #c0ffffff #a0000000 std MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std MENU COLOR msg07 37;40 #90ffffff #a0000000 std MENU COLOR tabmsg 31;40 #30ffffff #00000000 std LABEL linux MENU LABEL Try Ubuntu FS MENU DEFAULT KERNEL /casper/vmlinuz APPEND initrd=/casper/initrd boot=casper nopersistent toram quiet splash --- LABEL linux MENU LABEL Install Ubuntu FS MENU DEFAULT KERNEL /casper/vmlinuz APPEND initrd=/casper/initrd boot=casper only-ubiquity quiet splash --- LABEL linux MENU LABEL Check disc for defects MENU DEFAULT KERNEL /casper/vmlinuz APPEND initrd=/casper/initrd boot=casper integrity-check quiet splash --- LABEL memtest MENU LABEL Memtest86+ LINUX ../install/memtest86+ EOF
必要モジュールをisolinuxディレクトリにコピー。
cp -a /usr/lib/ISOLINUX/isolinux.bin isolinux/ cp -a /usr/lib/syslinux/modules/bios/* isolinux/
ISOイメージの作成
[改変]md5sum.txtファイルの作成。起動時のファイルチェックでエラーが発生するため、4つのファイルを外してある。
cd $HOME/live-ubuntu-from-scratch/image sudo /bin/bash -c "(find . -type f -print0 | xargs -0 md5sum | grep -v -e 'md5sum.txt' -e 'boot.img' -e 'efi.img' -e 'isolinux.bin' > md5sum.txt)"
[改変]ISOイメージを作成。
IOSS / 資料3: mkisofs(8) ver.2.0 man page [日本語]
debian manpages / XORRISOFS
技術評論社 / 第93回 xorrisoとUEFIブート再び[その3]
sudo xorriso \ -as mkisofs \ -iso-level 3 \ -full-iso9660-filenames \ -volid "UBUNTU_FROM_SCRATCH" \ -output ../ubuntu-from-scratch.iso \ -isohybrid-mbr /usr/lib/grub/i386-pc/boot_hybrid.img \ --grub2-mbr /usr/lib/grub/i386-pc/boot_hybrid.img \ --grub2-boot-info \ -b boot/grub/boot.img \ -no-emul-boot \ -boot-load-size 4 \ -boot-info-table \ --eltorito-catalog boot/grub/boot.cat \ -append_partition 2 0xef boot/grub/efi.img \ -eltorito-alt-boot \ -e boot/grub/efi.img \ -no-emul-boot \ -isohybrid-gpt-basdat \ ./
LegacyでISOLINUXを利用する場合はこちら。
sudo xorriso \ -as mkisofs \ -iso-level 3 \ -full-iso9660-filenames \ -volid "UBUNTU_FROM_SCRATCH" \ -output ../ubuntu-from-scratch.iso \ -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin \ -b isolinux/isolinux.bin \ -no-emul-boot \ -boot-load-size 4 \ -boot-info-table \ --eltorito-catalog isolinux/isolinux.cat \ --grub2-boot-info \ -append_partition 2 0xef boot/grub/efi.img \ -eltorito-alt-boot \ -e boot/grub/efi.img \ -no-emul-boot \ -isohybrid-gpt-basdat \ ./
Ubuntu 20.04のLive CDにはisolinuxディレクトリがあって何かが書き込まれているのだけれども、どのようなケースがどんな方法でカバーされているのかがよく分からず、同じものを作ることができなかった。
Grubでみてみると、(cd0,apple1)とか(cd0,apple2)があったので、そうしたデバイスにも対応していると言うことなのかもしれないが、今回はここまで。
さて、できあがったISOイメージを確認。
ll -h ../ubuntu-from-scratch.iso
-rw-r--r-- 1 root root 2.6G 12月 31 23:01 ../ubuntu-from-scratch.iso
思ったよりもサイズがでかい…途中で結構色々とインストールしたので、当然か。
ISOを取り出して試す
できあがったISOイメージを取り出すのに、VMwareの共有フォルダの仕組みを使う。
sudo mount -t fuse.vmhgfs-fuse -o allow_other .host:/VMware /mnt cp ../ubuntu-from-scratch.iso /mnt/ sudo umount /mnt
最初はセキュアブートができなかったが、手順をいくつか改変したことで起動できるようになっている。
また、Legacyでも、32bit UEFI+セキュアブートでも問題なく起動する。
動作を確認してみる。
- 起動時のファイルチェックでエラーが発生しなかった。
以前、ディスクイメージのカスタマイズに挑戦したときは、1つのファイルでエラーが発生していた。 - 全体に問題なくLive起動できている。
- UFWはインストールされており、非アクティブ。
- AppArmorはインストールされているが起動していない。
- ネットワークは、普通に使えている。
- 仮想ホストのネットワークアダプタが使える。
- Wi-Fiアダプタ搭載のタブレットで、問題なくアクセスポイントに接続できた。
- 音は鳴る。
- 日本語入力のために、画面右上のjaのところをクリックして、日本語→日本語(Mozc)への変更が必要。
- カスタマイズしたとおりにアプリケーションがインストールされている。
- LibreOfficeが入っていて、麻雀は入っていない。
- open-vm-toolsはインストールされていない。
- メモリに応じた動作ができている。
- 8GBのメモリを割り当てた仮想ゲストの場合、起動に必要なファイルがすべてメモリに展開される。
freeコマンドの結果available(割り当て可能なメモリ)が3.9GB。
Liveが入ったデバイスを取り外すことができる。 - 2GBのメモリしかないタブレットでは、メモリへの展開ができないので、都度デバイスからファイルを読み出すようだ。
当然、動作中にLiveが入ったデバイスを取り出してしまうと、エラーが発生する。
- 8GBのメモリを割り当てた仮想ゲストの場合、起動に必要なファイルがすべてメモリに展開される。
といったところ。全体に問題なく動いている。
手順は簡単とは言えないけれど、スクラッチでここまでのLive環境ができるのは凄い。
USBフラッシュメモリーへの書き込み
Windows
WindowsにはRufusという便利なツールがあるので、これを使って書き込めば良い。
このツールは、書き込みたいISOイメージを選択した段階で、BIOSやUEFIといった起動対応デバイスを教えてくれる。
今回の手順を実行し、BIOSまたはUEFIと表示されれば、どの環境でも起動できるようになっていると思われる。
今回の手順で作成したイメージの起動を確かめてみた。
起動方法 | Rufus(ISOイメージモード) | Rufus(ddイメージモード) | Ubuntu dd | 参考:CD起動 |
---|---|---|---|---|
UEFI 64bit(VMware) | ◯ | ◯ | ◯ | ◯ |
UEFI 64bit(現在のメインPC) | ◯ | ◯ | ◯ | 未テスト |
UEFI 32bit(Miix 2 8) | ◯ | ◯ | ◯ | 未テスト |
Legacy(VMware) | - | - | - | ◯ |
Legacy(Acerのかなり古いPC) | ◯*S | ◯*S | ◯*S | 未テスト |
*S: SYSLINUXでも起動が確認できた。
RufusでいうところのISOイメージモードでは、EFIパーティションから起動しているように見えた。
USBフラッシュメモリーの空き領域にファイルを書き込むことができる。
ddイメージモードでは、efi.imgやboot.img、SYSLINUXから起動しているように見えた。
こちらは特殊なフォーマット状態になり、空き領域0で何も書き込むことができない。
今回の手順では、メニューを定義しているgrub.cfgを1つ用意し、他の場所に置いたgrub.cfgはすべてそれを参照するようにした。
これらを作らないでISOイメージを作って実験してみれば、Grubでメニューが表示されずコマンドプロンプトが表示されるので、なんとなくどこから起動しているのかが分かってくると思う。
コマンドプロンプトが表示されたら、lsコマンドでメニューを定義しているgrub.cfgを探して、configfile (hd0,msdos2)/boot/grub/grub.cfgコマンドでメニュー表示されるので、問題発生時に試してみると、どこが悪いのかを特定できるかもしれない。
Ubuntu
ddコマンドを使って、ISOイメージを書き込むことができる。
この場合は、Rufusのddイメージモードと同様、特殊なフォーマット状態になって、読み込みはできるが書き込めない状態になる。
sudo dd if=./ubuntu-from-scratch.iso of=/dev/sdb bs=1M status=progress oflag=sync
※書き込み先のデバイスに注意。
書き込み対象となるデバイスは lsblk コマンドで大体分かると思う。
live-helperを使ってみる
Liveってなんなのか?というところを知るには、作ってみるのが一番だろうと思って探してみた。
技術評論社 / 第113回 Debian Liveのlive-helperを使ってUbuntu Liveを作成する
技術評論社 / 第114回 Debian Liveのlive-helperを使ってUbuntu Liveを作成する (2)
記事は2010年のもので、Ubuntu9.10ベースで書かれている。
テスト環境の構築
同じバージョンでないと、同じ動きはしないかもしれない…ということで、9.10をダウンロードしてくる。
Old Ubuntu Releases
※今となっては古いやつなのでダウンロード帯域に制限が掛かっているようで、ISOイメージ自体は700MB弱だけれども1時間程掛かるので、試すのであれば先にダウンロードしておくことをオススメ。
テストにはVMware Workstation 16 Player 16.2.1を利用させていただく。
英語でインストール。Ubuntu 12.04から経験し始めていたのだけれど、この時代から既になんか格好いい。
ログインサウンドもなんか格好いいんですけど。
[CTRL]+[ALT]+Tでターミナルが開かないので、メニューからターミナルを開いて、アップデートを実行。$ sudo apt-get update
404が返ってくる。
Qiita / Ubuntu で apt-get update が404になる問題
ask ubuntu / Could not resolve 'id.old-releases.ubuntu.com' [duplicate]
$ sudo sed -i.001 -e 's/archive.ubuntu.com\|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list $ sudo sed -i.002 -e 's/jp.old-/old-/g' /etc/apt/sources.list
※バックアップを取ってから、old-releasesに置き換えている。
アップデートできた。
$ sudo apt-get update … Reading package lists... Done
この先の操作を楽にするため、open-vm-toolをインストールしてみる。クリップボードの共有はできるだろうか?
$ sudo apt-get install open-vm-tools open-vm-toolbox
インストール直後はクリップボードの共有ができなかった。
だけれども、一度再起動してみたら、クリップボードの共有ができるようになっていた。
また、ウィンドウのサイズを広げると、追従してデスクトップが広がる。うん、いい感じ!
ただ、これだけでは、ホストで共有フォルダを用意してもアクセスができなかった。
LANGUI.SH / Ubuntu 9.10 In VMware - Updated
$ sudo m-a
このコマンドで、module-assistantが起動する。
再起動後に確認してみたところ、教えてくれたサイトの確認結果と完全に一致。
$ lsmod | grep vm vmsync 5104 0 vmmemctl 10120 0 vmhgfs 59080 0 vmci 33952 0
これで共有フォルダがマウントできるようになった。
さて、パッケージ全体のアップグレード。アクセス速度は256KB/s程度となっており、30分ぐらいかかる。
$ sudo apt-get dist-upgrade … After this operation, 238MB of additional disk space will be used. Do you want to continue [Y/n]?
この段階でハードディスクイメージをバックアップした。
サイズは3.3GB程だった。
live-helperを使ってみる
教えてくれる手順に沿ってコマンドを実行してみる。
$ sudo apt-get install live-helper $ mkdir -p work/live $ cd work/live
実行にあたり、リポジトリを書き換えて実行。
$ lh_config \ --mode ubuntu \ --mirror-bootstrap "http://old-releases.ubuntu.com/ubuntu/" \ --mirror-chroot "http://old-releases.ubuntu.com/ubuntu/" \ --mirror-chroot-security "http://old-releases.ubuntu.com/ubuntu" \ --mirror-binary "http://old-releases.ubuntu.com/ubuntu/" \ --mirror-binary-security "http://old-releases.ubuntu.com/ubuntu"
設定ファイルができるとのことで、この後でISOイメージを作成。
$ sudo lh_build P: Setting up cleanup function P: Begin caching bootstrap stage... P: Begin bootstrapping system... P: If the following stage fails, the most likely cause of the problem is with your mirror configuration or a caching proxy. P: Running debootstrap (download-only)... I: Retrieving Release I: Retrieving Packages I: Validating Packages … Hit http://old-releases.ubuntu.com jaunty-security/restricted Packages Reading package lists... Done P: Deconfiguring file /etc/hostname P: Deconfiguring file /bin/hostname P: Deconfiguring file /etc/resolv.conf P: Deconfiguring file /etc/hosts P: Begin unmounting filesystems...
当然ながら、これにも時間は掛かったが、できあがった。137MB!
$ ls -lah
total 137M
drwxr-xr-x 8 rohhie rohhie 4.0K 2021-12-04 09:37 .
drwxr-xr-x 3 rohhie rohhie 4.0K 2021-12-04 09:22 ..
drwxr-xr-x 5 root root 4.0K 2021-12-04 09:37 binary
-rw-r--r-- 1 root root 137M 2021-12-04 09:37 binary.iso
-rw-r--r-- 1 root root 567 2021-12-04 09:37 binary.list
-rw-r--r-- 1 root root 34K 2021-12-04 09:37 binary.packages
drwxr-xr-x 6 root root 4.0K 2021-12-04 09:37 cache
drwxr-xr-x 20 root root 4.0K 2021-12-04 09:37 chroot
drwxr-xr-x 22 rohhie rohhie 4.0K 2021-12-04 09:22 config
drwxr-xr-x 2 rohhie rohhie 4.0K 2021-12-04 09:22 scripts
drwxr-xr-x 2 rohhie rohhie 4.0K 2021-12-04 09:37 .stage
できあがったISOイメージを取り出すのに、VMwareの共有フォルダの仕組みを使う。
$ mkdir ~/work/VMware $ sudo mount -t vmhgfs .host:/VMware /home/rohhie/work/VMware/ -o uid=1000,gid=1000
取り出したISOをVMwareにマウントして起動してみると…
ということで、思ったように起動はしなかったけれど、この後で[CTRL]+[ALT]+[DELETE]を送信したところ、コンソールのまま、ubuntuでログインした状態になった。
IPアドレスは払い出されていないけれど、いくつかのサービスは動作しているようだった。
作業ディレクトリをクリアするときには、以下のコマンドを利用するとのこと。
確かに、設定ファイルがまるごと消えてしまっては困る。
$ sudo lh_clean
このコマンドは、次のMakefileにも書かれていた。
軽量デスクトップの作成
教えてくれているとおりに軽量デスクトップを作成してみる。
作業ディレクトリは ~/work/live。
~/work/live/scripts/config
#!/bin/sh MIRROR_UBUNTU="http://old-releases.ubuntu.com/ubuntu/" MIRROR_SECURITY="http://old-releases.ubuntu.com/ubuntu/" lh_config noautoconfig \ --mode ubuntu \ --distribution karmic \ --language ja \ --mirror-binary ${MIRROR_UBUNTU} \ --mirror-binary-security ${MIRROR_SECURITY} \ --mirror-bootstrap ${MIRROR_UBUNTU} \ --mirror-chroot ${MIRROR_UBUNTU} \ --mirror-chroot-security ${MIRROR_SECURITY} \ --categories "main restricted universe multiverse" \ ${@}
※赤文字は改変箇所。
~/work/live/scripts/build
#!/bin/sh lh_build noautoconfig 2>&1 | tee binary.buildlog
~/work/live/scripts/clean
#!/bin/sh lh_clean noautoconfig --all ${@} # Remove generated files rm -f config/binary config/bootstrap config/chroot config/common config/source # Remove empty directories in config tree if ls config/*/ > /dev/null 2>&1 then rmdir --ignore-fail-on-non-empty config/*/ fi if [ -d config ] then rmdir --ignore-fail-on-non-empty config fi
実行権限を付ける。
$ chmod +x scripts/*
※実行権限を付けておかないと、スクリプトが実行できない。エラーが発生しているのが分からないし、パッケージをJauntyからダウンロードしたりする。
これをmakeで実行するためのMakefileを作成。
~/work/live/Makefile
BOOTOPTION_LIVE = quiet splash debian-installer/language=ja console-setup/layoutcode?=jp console-setup/modelcode?=jp106 all: config build config: clean lh_config \ --bootloader grub \ --binary-images iso \ --bootappend-live "$(BOOTOPTION_LIVE)" \ --packages "lxde language-pack-ja language-support-ja usplash-theme-ubuntu ubiquity-frontend-gtk gparted" build: sudo lh_build clean: sudo lh_clean sudo rm -f *.buildlog
※行頭8このスペースは、TABコードに置き換える。
実行してみたところ、大体20分くらいで終了した。
$ make all sudo lh_clean P: Cleaning chroot sudo rm -f *.buildlog lh_config \ --bootloader grub \ --binary-images iso \ --bootappend-live "quiet splash debian-installer/language=ja console-setup/layoutcode?=jp console-setup/modelcode?=jp106 " \ --packages "lxde language-pack-ja language-support-ja usplash-theme-ubuntu ubiquity-frontend-gtk gparted" sudo lh_build P: Setting up cleanup function … Reading package lists... Done P: Deconfiguring file /etc/hostname P: Deconfiguring file /bin/hostname P: Deconfiguring file /etc/resolv.conf P: Deconfiguring file /etc/hosts P: Begin unmounting filesystems...
結果を確認してみる。
$ ls -lah
total 320M
drwxr-xr-x 8 rohhie rohhie 4.0K 2021-12-04 17:28 .
drwxr-xr-x 4 rohhie rohhie 4.0K 2021-12-04 17:09 ..
drwxr-xr-x 5 root root 4.0K 2021-12-04 17:27 binary
-rw-r--r-- 1 root root 276K 2021-12-04 17:27 binary.buildlog
-rw-r--r-- 1 root root 320M 2021-12-04 17:27 binary.iso
-rw-r--r-- 1 root root 315 2021-12-04 17:27 binary.list
-rw-r--r-- 1 root root 78K 2021-12-04 17:27 binary.packages
drwxr-xr-x 6 root root 4.0K 2021-12-04 17:06 cache
drwxr-xr-x 20 root root 4.0K 2021-12-04 17:27 chroot
drwxr-xr-x 22 rohhie rohhie 4.0K 2021-12-04 17:06 config
-rw-r--r-- 1 rohhie rohhie 431 2021-12-04 16:41 Makefile
drwxr-xr-x 2 rohhie rohhie 4.0K 2021-12-04 17:09 scripts
drwxr-xr-x 2 rohhie rohhie 4.0K 2021-12-04 17:28 .stage
できあがったISOをホストに取り出す。
$ sudo mount -t vmhgfs .host:/VMware /home/rohhie/work/VMware/ -o uid=1000,gid=1000 $ cp binary.iso /home/rohhie/work/VMware/ubuntu-9.10-original-live.iso
起動してみたところ、こんな感じ。
画面の文字が日本語、キーボードも日本語配列、とても軽い。
UFWやAppArmorは入っていないけれど、この方法ならば後から入れていけば良いのだろう。
記事を読み進めると、USB空起動できるシステムの作り方も書かれていて、この分なら何の問題もなく動作することだろう。
2010年には既にこんなことができる人がいて、記事を書いていたんだと思うと、素晴らしいことだなぁと思うのだった。
やったこと
ブートについて
Legacyの場合…
MBRの小さなプログラム(Master bootstrap loader)が読み込まれる
→ 起動パーティションの先頭セクターにあるプログラム(Initial Program Loader)が読み込まれる
→ OSがロードされる
という流れでOSが起動している(ざっくり過ぎるけど)。
Nobusan's Square / ブートの仕組み
UEFIはどうかというと、起動にはESP(EFI System Partition)が使われていて…
起動するディスク・パーティションを決定
→ ファームウェアのブートエントリーに登録されているUEFIアプリケーションを起動
→ bootx64.efiが起動され、mmx64.efiを使ってMOKを取り扱いつつ、grubx64.efiを起動
→ Grub2で選択されたOSがロードされる
という流れと思われた(これも超ざっくり)。
ArchWiki / Unified Extensible Firmware Interface
ArchWiki / GRUB
ArchWiki / セキュアブート
UEFIには32ビットと64ビットがあって、古いものだと32ビットだったりする。
(持っているデバイスでいうと、Miix 2 8は32ビット)
起動するUEFIアプリケーションは /EFI/boot/bootx64.efi(64ビット) 固定の場合もあると書かれていた。
拡張子efiのファイルがいくつかあるのだが、それぞれがどんな機能を持つのか調べてみた結果がこちら。
ファイル名 | 機能 |
---|---|
bootx64.efi | ブートローダー。EFIはこれを探して起動する。 取り扱うOSによるが、Ubuntuの場合はGrub2を実行しようとする。 |
grubx64.efi | Grub2ブートローダー本体(っぽい)。 |
shimx64.efi | ブートローダー。起動時にgrubx64.efiを実行しようとする。 ハッシュまたは署名鍵が見つからない場合、mmx64.efiを起動する。 インストール済みのUbuntu 20.04で確認してみたら、bootx64.efiとmd5sumの結果が一致していた。 |
mmx64.efi | MokManager.efiから名前が変わったらしい。 MOKを管理するためのツール。 |
fbx64.efi | Grubを起動する。 |
起動させるためのテクニックとして、shimx64.efiをbootx64.efiという名前で置いたりなんかもするようなので、いま、Liveシステムに入っているファイルがなんなのか良くわからなかったりもするが、これらを考慮してISOを作れば、ハイブリッドな感じで起動させられそうだ。
ディレクトリ構成
今回教えてもらった手順でいくと、casper、install、isolinuxというディレクトリができる。
それぞれなんのためのディレクトリなのか。
ディレクトリ | 機能 |
---|---|
casper | Casperはmake-liveで作成されたLiveシステムを起動する仕組み。 カーネルパラメーターにboot=casperが指定されていると、/casperからsquashfsファイルを探す。 見つかればunionfsを使って書き込み可能な環境を作ってシステムを起動する。 変更は保存されない。 |
install | Ubuntu 20.04.03にはmt86plus(179KB)が入っていた。 今回の手順ではmemtest86(500MB!!)とmemtest86+(179KB)が入っている。 mt86plusとmemtest86+はmd5sum値が一致していたので、同じファイル。 memtest86はloopbackでマウントした後chainloadしているので、ISOイメージと思われる。 |
isolinux | エミュレーションなしのモードでISO9660/El Toritoで動作するi386用のブートローダーを入れておく場所。 Ubuntu 20.04.03には大量にファイルが入っているのだけれど、isolinux.binとisolinux.cfg、boot.catが確かに入っていた。 たくさん入っているファイルについては、ここをたどっていけば見つかるかもしれない。 |
casperはLiveシステムが起動したときに、システムそのものになるディレクトリのようだ。
また、色々なシステムで起動できるようにするには、isolinuxを理解しておく必要がありそう。
軽量なISOを作るなら、memtest86(500MB!!)は外しても良さそう。
セキュアブートしているかどうか確認
現在起動しているOSがセキュアブートしているのかどうか確認してみようと考えた。
こういうことは、たいがいArch Linuxが教えてくれる。
ArchWiki / セキュアブート
Ubuntu 20.04.3 のインストールディスクから起動した状態では以下の通り。
$ sudo bootctl status
Couldn't find EFI system partition. It is recommended to mount it to /boot or /efi.
Alternatively, use --esp-path= to specify path to mount point.
System:
Firmware: n/a (n/a)
Secure Boot: enabled
Setup Mode: user
Current Boot Loader:
Product: n/a
Features: ✗ Boot counting
✗ Menu timeout control
✗ One-shot menu timeout control
✗ Default entry control
✗ One-shot entry control
✗ Support for XBOOTLDR partition
✗ Support for passing random seed to OS
✗ Boot loader sets ESP partition information
ESP: n/a
File: └─n/a
Random Seed:
Passed to OS: no
System Token: not set
Boot Loaders Listed in EFI Variables:
Title: ubuntu
ID: 0x0003
Status: active, boot-order
Partition: /dev/disk/by-partuuid/c7076d24-d43c-4fe9-95dd-958ffa481a48
File: └─/EFI/ubuntu/shimx64.efi
セキュアブートが有効になっている。
ISOの構造を調べる
USBフラッシュメモリーにddで書き込んだISOイメージがLegacyで起動しなかったことで、ディスクの構造を確認する必要が出てきた。
結論からすると、DVDから立ち上げた場合にはある程度優しく読んでくれるようだが、ISOイメージをddでUSBフラッシュメモリーに書き込んだ場合、HDDとして取り扱われるため、MBRにブートローダーを仕掛けておく必要があるようだ。
さて…通常、ディスクを入れると最初のパーティションが表示されて、その後ろにあるパーティションが見えない。
Man On a Mission / 【Linux】kpartxでループバックデバイスを簡単にマウントする
kpartxというコマンドでISOイメージのパーティションをマッピングしてくれる。
sudo kpartx -av ubuntu-from-scratch.iso add map loop14p1 (253:0): 0 5376628 linear 7:14 0 add map loop14p2 (253:1): 0 20480 linear 7:14 5376628 lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT <omit> loop14 7:14 0 2.9G 0 loop ├─loop14p1 253:0 0 2.9G 0 part └─loop14p2 253:1 0 3.9M 0 part sda 8:0 0 40G 0 disk ├─sda1 8:1 0 512M 0 part /boot/efi └─sda2 8:2 0 39.5G 0 part / sr0 11:0 1 2.6G 0 rom ll /dev/mapper/ total 0 drwxr-xr-x 2 root root 100 12月 31 06:45 ./ drwxr-xr-x 20 root root 4280 12月 31 06:45 ../ crw------- 1 root root 10, 236 12月 30 10:47 control lrwxrwxrwx 1 root root 7 12月 31 06:45 loop14p1 -> ../dm-0 lrwxrwxrwx 1 root root 7 12月 31 06:45 loop14p2 -> ../dm-1
適当なディレクトリを作ってマウントしてみたところ、確かに中身を確認することができる。
sudo mount /dev/mapper/loop14p1 mp/p1
sudo mount /dev/mapper/loop14p2 mp/p2
確認が終わったら、以下で解放。
sudo umount mp/p1
sudo umount mp/p2
sudo kpartx -d ubuntu-from-scratch.iso
loop deleted : /dev/loop14
ということで、Ubuntu 20.04.3 desktopがどのような構造なのかを確認してみたところ、2つ目のパーティションにあるファイルは、今回の手順で作成したものと大差がなかった。
もう少し何か手がかりはないか…
技術評論社 / 第93回 xorrisoとUEFIブート再び[その3]
file /mnt/ubuntu-20.04.3-desktop-amd64.iso ../ubuntu-from-scratch.iso /mnt/ubuntu-20.04.3-desktop-amd64.iso: DOS/MBR boot sector; partition 2 : ID=0xef, start-CHS (0x3ff,254,63), end-CHS (0x3ff,254,63), startsector 5271500, 8000 sectors ../ubuntu-from-scratch.iso: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", sectors/cluster 4, reserved sectors 4, root entries 512, sectors 20480 (volumes <=32 MB), Media descriptor 0xf8, sectors/FAT 20, sectors/track 32, heads 64, serial number 0x63abb652, unlabeled, FAT (16 bit) fdisk -l /mnt/ubuntu-20.04.3-desktop-amd64.iso Disk /mnt/ubuntu-20.04.3-desktop-amd64.iso: 2.88 GiB, 3071934464 bytes, 5999872 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x2cf4ba3a Device Boot Start End Sectors Size Id Type /mnt/ubuntu-20.04.3-desktop-amd64.iso1 * 0 5999871 5999872 2.9G 0 Empty /mnt/ubuntu-20.04.3-desktop-amd64.iso2 5271500 5279499 8000 3.9M ef EFI (FAT-12/16/32) fdisk -l ../ubuntu-from-scratch.iso Disk ../ubuntu-from-scratch.iso: 2.59 GiB, 2765549568 bytes, 5401464 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x3804a073 Device Boot Start End Sectors Size Id Type ../ubuntu-from-scratch.iso1 * 0 5380319 5380320 2.6G 0 Empty ../ubuntu-from-scratch.iso2 5380320 5400799 20480 10M ef EFI (FAT-12/16/32)
fdiskで見た結果はあまり変わらない。
そこでISOLINUXによるハイブリッド起動を試したところ、問題なく起動ができることを確認。
MBRに何を書くかで決まることが分かって、今回の手順が整理できた。
起きたこと
セキュアブート環境でエラー
セキュアブート環境で、エラーが発生してGrubが上手く動作しなかった。
そこで、仮想ゲストにCDをマウントしてGrubで中身を色々みようとしていたところで、このような表示が…
これ以降、このディスクは反応しなくなってしまう。
grub> ls (memdisk) (hd0) (cd0) (cd0,msdos2) grub> ls (cd0,msdos2)/boot/grub/x86_64-efi/ error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/ufs2.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/ufs1_be.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/ufs1.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/udf.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/tar.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/sfs.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/romfs.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/reiserfs.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/procfs.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/odc.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/nilfs2.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/minix_be.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/minix3_be.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/minix3.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/minix2_be.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/minix2.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/minix.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/jfs.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/hfs.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/f2fs.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/exfat.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/cpio_be.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/cpio.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/cbfs.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/bfs.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/afs.mod. error: Secure Boot forbids loading module from (cd0)/boot/grub/x86_64-efi/affs.mod. error: unknown filesystem. grub> ls (cd0,msdos2)/boot/grub/x86_64-efi/ error: unknown filesystem.
これについては、こちらで教えてくれた。
UNIX & LINUX / Signing grub for secureboot uefi: Secureboot forbids to load module (memdisk)/boot/grub/x86_64-efi/normal.mod
使えるモジュールが限られている、ということだった。
ということで、エラー表示されたファイルを、efi.imgの中から消してみる。
$ sudo mount ${HOME}/live-ubuntu-from-scratch/image/boot/grub/efi.img /mnt $ cd /mnt $ sudo rm ufs2.mod ufs1_be.mod ufs1.mod udf.mod tar.mod sfs.mod romfs.mod reiserfs.mod procfs.mod odc.mod nilfs2.mod minix_be.mod minix3_be.mod minix3.mod minix2_be.mod minix2.mod minix.mod jfs.mod hfs.mod f2fs.mod exfat.mod cpio_be.mod cpio.mod cbfs.mod bfs.mod afs.mod affs.mod $ cd ${HOME}/live-ubuntu-from-scratch/image $ sudo umount /mnt
ところが、消しても同じエラーが出るし、さらにいえば、セキュアブートではない環境では「これらのファイルがない」と怒られるのだった。
リストでもあるの?と探してみると、fs.1stというファイルがあり、そこにほぼこれらがリストアップされたファイルがある。これは…
手詰まりとなり、Ubuntu 20.04のディスクで同じ操作をしてみたところ、同じようにunknown filesystemになってしまった。
ブートできない原因はこれじゃないと分かったので検討していって、署名されたGrubをインストールすることにした。
rror: file `/boot/` not found.
UEFI(64bit)+セキュアブートの環境、ddでUSBフラッシュメモリーに書き込んだイメージで起動したところ、一瞬このメッセージが表示された後でメニューが表示される。
rror: file `/boot/` not found. error: no such device: /.disk/info error: no such device: /.disk/mini-info
※最初のeが表示されていないのは何らかの都合じゃないかと。ビデオ撮影して何度か確認したので、間違いはなさそう。
ちゃんと起動するからいいじゃん?という話はあるものの、どういうことなのかが少し気になったので調べてみた。
まず、/boot/がない件。
最初に試していた手順では、efi.imgの中に/boot/grub/grub.cfgを置いていなかった。
最初にそれを見に行くのでこのエラーを表示していた。
このファイルを置いたことで解決できた。
次に、/.disk/infoの件。
EFIイメージの場合には常に埋め込まれている文字があるらしく、それが表示されているようだ。
stackoverflow / How does the GRUB2 UEFI loader know where to look for the configuration file (or where the 2nd stage's files are located)?
実際に、Grubメニューでちょっと確認してみた。
この場合、(hd1)がUSBフラッシュメモリーそのものを表していて、(hd1,msdoc1)がISOイメージの中身らしい。
grub> ls (memdisk) (hd0) (hd1) (hd1,msdos1) (hd2) grub> ls (hd1,msdos1)/ DIR System Volume Information/ 69145 ldlinux.sys DIR boot/ DIR casper/ DIR efi/ <omit> grub> ls (hd1,msdos1)/efi/ DIR boot/ DIR debian/ grub> echo $root hd1,msdos1
では、なぜ最初のメッセージが表示されるのか。
grub> cat (memdisk)/grub.cfg if [ -z "$prefix" -o ! -e "$prefix" ]; then if ! search --file --set=root /.disk/info; then search --file --set=root /.disk/mini-info fi set prefix=($root)/boot/grub fi if [ -e $prefix/x86_64-efi/grub.cfg ]; then source $prefix/x86_64-efi/grub.cfg elif [ -e $prefix/grub.cfg ]; then source $prefix/grub.cfg → echoしてみたところ (hd1,msdos1)/boot/grub else source $cmdpath/grub.cfg → echoしてみたところ (hd1,msdos1)/EFI/BOOT fi
ということで、固定的に /.disk/info というファイルを探し、見つけたパーティションをrootにする。
そして、そのディスクの /boot/grub/grub.cfgを読み出す、といった形で起動しているようだ。
sourceコマンドというのは、ファイルを読み込んで実行するコマンド。
configfileコマンドの場合は、読み込んでメニューを即座に表示するが、sourceの場合はメニューは後から表示されるといったことが書かれている。
いずれにしても、こういう固定的な設定があるのなら、これに載っかるのが得策のように思われる。
なお、このファイルを置いたところ、最初の2単語がインストーラー表示名の先頭に表示された。
さいごに
今回は、過去のUbuntuを利用してみて、当時から素晴らしいものだったのだなぁと思ったのと、Makefileってほとんど使ったこともなかったのだけれど、これはこれでやっぱりかなり使いやすいものなんだと思ったのとで、改めてやってみて良かった。
その後で、Ubuntu 20.04の起動ディスク作成に取り組んだが、これが本当に色々とあって、まともにOSが起動してくるまでが大変だった。
起動には色々なルートがあるし、DVDに焼き込んだときと、USBフラッシュメモリーに書き込んだときとで、BIOSからの見え方が変わって動作が変わる。BIOSが優秀だと色々と察してくれたりするので、察してくれないタイプのBIOSでは設定が甘いと上手く起動できなくなったりもする。
なんとかそれっぽく起動するようになったとは思うが、お気づきの点があれば、是非教えてください。
コメントはこちらから お気軽にどうぞ ~ 投稿に関するご意見・感想・他