Ubuntu

Ubuntu22.04 Live CDを作ってみる 詳細編

Ubuntu

Ubuntu 22.04のLive CDを作ってみる。
ブラウザだけが使える程度のできるだけ小さな環境を作ろうとしている。



広告


関連記事は以下の通り。

記事説明
How to create a custom Ubuntu live from scratchGitHub mvallim氏の記事。
起動可能、かつ、インストール可能なUbuntu Liveを作成する方法を示してくれている。
Ubuntu20.04 Live DVDから起動したときに便利に使いたいUbuntuのインストーラーの中身を改造して、ISOを作り直している。
ただ、どんなデバイスでも起動できる状態にはなっていない。
Ubuntu20.04 Live CDを作ってみる 基本編mvallim氏の記事を実行し、少しカスタマイズしている。
日本語対応してみたり、ブートのあたりを少し改変。
Ubuntu20.04 Live CDを作ってみる 詳細編基本編をカスタマイズして、できるだけ小さなLive CDを目指した記事。
デスクトップのカスタマイズ、カーネルをGAからHWEに変更などを行っている。
Ubuntu22.04 Live CDを作ってみる 詳細編(この記事)20.04詳細編をベースに、22.04の変更点を反映。
その他、いくつか細かな点を改善。

Live CDができた後に、繰り返しカスタマイズすることを意識した構成になっている。

当サイトでは通常、コマンド行の先頭を#と$で書き分けたりしているのだが、コピペするコマンドがとにかく多いので、

仮想ホストで、一般ユーザーとして入力するコマンド
chrootした環境で、rootとして入力するコマンド

と、文字色・背景色で書き分けて、コマンドを一気にコピペできるようにしている。

環境構築

作業環境の構築

これまで使ってきたUbuntu 20.04の環境でも作れるとは思うのだけれども、心機一転、VMware 16 Playerで新しい仮想PCを作った。
GUIは必要ないので、デスクトップなしのサーバー版。
メモ的に残しておきたいchroot環境もあったりして、案外容量を使ったりするから、LVMでいつでもディスクを拡張できるようにしてみた。

仮想マシンには以下の設定を加えている。
~.vmx

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

HDDイメージは40GBで作成したが、20GB程しか割り当てられていなかったので、全部割り当てた。
LVMで領域を割り当てて、ファイルシステムをリサイズしている。

$ df -h
Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv   19G  6.5G   11G  38% /

$ sudo lvextend --extents +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv
  Size of logical volume ubuntu-vg/ubuntu-lv changed from 18.47 GiB (4729 extents) to <36.95 GiB (9458 extents).
  Logical volume ubuntu-vg/ubuntu-lv successfully resized.

$ sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/mapper/ubuntu--vg-ubuntu--lv is mounted on /; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 5
The filesystem on /dev/mapper/ubuntu--vg-ubuntu--lv is now 9684992 (4k) blocks long.

$ df -h
Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv   37G  6.6G   29G  19% /

共有フォルダ

仮想マシンからISOファイルを取り出す方法はいくつかあるけれど、ここでは共有フォルダを使っている。
仮想マシンが起動中にも設定が可能。

仮想マシンにはopen-vm-toolsがインストールされていたので、以下でホストPCのディレクトリをマウントできる。

$ sudo mkdir /mnt/vmware
$ sudo mount -t fuse.vmhgfs-fuse -o allow_other .host:/VMware /mnt/vmware

共有フォルダをsambaでマウントしてコピーするよりも、圧倒的に転送速度が速くて便利。

アーカイブミラー

気に入った環境を作り込むのがなかなか難しくて、何度も何度も最初からやり直したのだけれど、ダウンロードには時間が掛かるし、何度も繰り返しアクセスされるサーバーの方も迷惑だろうということで、アーカイブミラーを設置した。
Ubuntu20.04 ローカルにアーカイブミラーを立ててみる
Ubuntu22.04 既存のアーカイブミラーに22.04を追加
※ミラーする先を細かく定義できるので、22.04だけのアーカイブミラーを作ることも可能。

アーカイブミラーは mirror.hogeserver.hogeddns.jp としていて、ウチの中ではこれで名前解決ができるようにしている。

基礎部分を作る

ブラウザが起動できるだけのLive環境を作る。

編集環境の作り込み

Live環境を構築するのに必要なパッケージをインストール。

sudo apt install binutils debootstrap squashfs-tools xorriso grub-pc-bin grub-efi-amd64-bin mtools syslinux-common isolinux unzip

debootstrapで最小構成を展開。ダウンロード先として早いものを選択する。

mkdir $HOME/live-ubuntu-from-scratch
sudo debootstrap --arch=amd64 --variant=minbase jammy $HOME/live-ubuntu-from-scratch/chroot http://ja.archive.ubuntu.com/ubuntu/

あるいは…
mkdir $HOME/live-ubuntu-from-scratch
sudo debootstrap --arch=amd64 --variant=minbase jammy $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 jammy $HOME/live-ubuntu-from-scratch/chroot http://mirror.hogeserver.hogeddns.jp/ubuntu/

作業開始時の初期設定。

sudo mount --bind /dev $HOME/live-ubuntu-from-scratch/chroot/dev
sudo mount --bind /run $HOME/live-ubuntu-from-scratch/chroot/run
sudo mount --bind /proc $HOME/live-ubuntu-from-scratch/chroot/proc
sudo mount --bind /sys $HOME/live-ubuntu-from-scratch/chroot/sys
sudo mount --bind /dev/pts $HOME/live-ubuntu-from-scratch/chroot/dev/pts
sudo chroot $HOME/live-ubuntu-from-scratch/chroot
export HOME=/root
export LC_ALL=C

chroot環境のホスト名を設定。

echo "ubuntu-fs-live" > /etc/hostname

aptのsource.listを作成。ローカルミラーを使う場合は、リリース前に修正すること。

cat <<EOF > /etc/apt/sources.list
deb http://ja.archive.ubuntu.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://ja.archive.ubuntu.com/ubuntu/ jammy main restricted universe multiverse
deb http://ja.archive.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://ja.archive.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://ja.archive.ubuntu.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://ja.archive.ubuntu.com/ubuntu/ jammy-updates main restricted universe multiverse
EOF

あるいは…
cat <<EOF > /etc/apt/sources.list
deb http://ftp.riken.go.jp/Linux/ubuntu/ jammy main restricted universe multiverse
deb-src http://ftp.riken.go.jp/Linux/ubuntu/ jammy main restricted universe multiverse
deb http://ftp.riken.go.jp/Linux/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://ftp.riken.go.jp/Linux/ubuntu/ jammy-security main restricted universe multiverse
deb http://ftp.riken.go.jp/Linux/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://ftp.riken.go.jp/Linux/ubuntu/ jammy-updates main restricted universe multiverse
EOF

ミラーサーバーを立てたなら、リリースするまでの試行錯誤は…
cat <<EOF > /etc/apt/sources.list
deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ jammy main restricted universe multiverse
deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirror.hogeserver.hogeddns.jp/ubuntu/ jammy-updates main restricted universe multiverse
EOF

等々。

updateする。

apt update

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

apt install --no-install-recommends systemd-sysv

dpkgインストール先の待避。

mkdir /var/lib/dbus
ln -fs /etc/machine-id /var/lib/dbus/machine-id
dpkg-divert --local --rename --add /sbin/initctl
ln -s /bin/true /sbin/initctl

[2回目以降のみ]/etc/resolv.confはシンボリックリンクになっているが上手く働かない。
ならばということで、最初から、ホストのsystemd-resolvdに乗っかる(最後に作り直すので、編集中はこれで問題なし)。

rm /etc/resolv.conf
cat <<EOF > /etc/resolv.conf
nameserver 127.0.0.53
EOF

事前の準備が済んだので、パッケージを更新。

apt upgrade

Liveの中身を編集

Liveシステムに必要なパッケージをインストールする。※結構時間が掛かる。

apt install --no-install-recommends \
sudo \
ubuntu-standard \
casper \
ubiquity-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

machine-idを構成。以前は、もっと前のタイミングで実行していたが、コマンドが見つからない状態だったのでココに移動。

dbus-uuidgen > /etc/machine-id

言語選択やロケールの設定を数値入力でする場合には必要ないが、選択式にしたい場合はCUI用のウィンドウライブラリをインストールする。

apt install whiptail

カーネルのインストール。どちらか一方をインストールすれば良く、比較的新しいハードウェアで使うなら、hweが良いだろう。

apt install --no-install-recommends linux-generic           ← カーネル5.15
apt install --no-install-recommends linux-generic-hwe-22.04 ← カーネル5.15 ※将来的にはこちらが新しいハードウェアに追従していく想定

The Ubuntu LTS enablement( also called HWE or Hardware Enablement) stacksは、既存のUbuntu LTSリリースに新しいカーネルとXのサポートを提供します

ウィンドウマネージャーのインストール。※結構時間が掛かる。
一旦、gnome-sessionと関係パッケージをインストールしておいた方が、各種デバイスをちゃんとコントロールするのにいい。実際、Miix 2 8で音が鳴らない問題は、この方法で回避できる。

apt install gnome-session

確認表示があったら…
Country of origin for the keyboard: 55 ← Japanese
Keyboard layout: 1 ← Japanese


その後に、ubuntu-gnome-sessionをインストールする。※結構時間が掛かる。
こちらはRecommendsをインストールしないので、FirefoxやLibreOffice、上海なんかもない、最低限っぽいインストールになる。
plymouthはspinnerに変更している。

apt install --no-install-recommends \
plymouth-theme-spinner \
ubuntu-gnome-desktop \
ubuntu-gnome-wallpapers \
yaru-theme-icon \
yaru-theme-gtk \
yaru-theme-sound \
network-manager-gnome \
libcanberra-pulse \
gvfs-backends

あわせて、こんなパッケージを一緒にインストールしてもいいかも。
apt install --no-install-recommends \
gnome-power-manager \
gnome-system-monitor \
pulseaudio-module-bluetooth

よく使うアプリケーションのインストール。–no-install-recommendsを入れていることでインストールされないip、pingコマンド、ufw、kbd、bashのコマンド補完機能を追加。

apt install --no-install-recommends \
apt-transport-https \
vim \
less \
iproute2 \
inetutils-ping \
ufw \
kbd \
bash-completion

確認表示があったら…
Character set to support: 23 ← Guess optimal character set

ファイアウォールを有効にする。

sed -i -E 's/^(ENABLED=).+$/\1yes/' /etc/ufw/ufw.conf

[オプション]Google Chromeのインストール。

wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > google.gpg
install -o root -g root -m 644 google.gpg /etc/apt/trusted.gpg.d/
echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list
rm google.gpg
apt update
apt install google-chrome-stable

[オプション]Microsoft Edgeのインストール。やり方が分かったのでメモとして書いている。
TECH+ / LinuxにMicrosoft Edgeをインストールする方法

wget -q -O - 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/edge/ stable main" > /etc/apt/sources.list.d/microsoft-edge.list
rm microsoft.gpg
apt update
apt install microsoft-edge-stable

[オプション]Firefoxのインストール。snap版は上手く動作しなかった。
1度目のリポジトリの登録が失敗するが、もう一回実行すると通る(原因は突き止めていない)。

add-apt-repository ppa:mozillateam/ppa
エラー発生
add-apt-repository ppa:mozillateam/ppa
2回目は成功
cat <<EOF > /etc/apt/preferences.d/mozilla-firefox
Package: *
Pin: release o=LP-PPA-mozillateam
Pin-Priority: 1001
EOF
apt install firefox

タイムゾーンを設定する。

dpkg-reconfigure tzdata

確認表示があったら…
Geographic area: 6 ← Asia
Time zone: 79 ← Tokyo

システム時間をローカル時間扱いにする。
多くの場合、Windowsを動かしているPCでLive CDを起動するのだろうから、時間の扱いを同じにしておいた方が良いだろう。
timedatectlコマンドを使いたいところだが、それを使っても本体側の設定が変わるだけなので、設定結果を手作りする。

cat <<EOF > /etc/adjtime
0.0.0.0
0
LOCAL
EOF

Mozcと言語サポートをインストール。

apt install --no-install-recommends ibus-mozc gkbd-capplet `check-language-support -l ja`

言語サポートのうち、この環境には必要のないfcitxを削除する。

apt purge fcitx-data

Mozcをデフォルトの入力メソッドにする。

mkdir /etc/dconf/db/local.d

cat <<EOF > /etc/dconf/profile/user
user-db:user
system-db:local
EOF

cat <<EOF > /etc/dconf/db/local.d/01-customize
[org/gnome/desktop/input-sources]
mru-sources=[('ibus', 'mozc-jp'), ('xkb', 'jp')]
per-window=false
EOF

dconf update

ロケールの設定。
デフォルトロケールとして2つ目のja_JP.UTF-8を選択しており、これでデスクトップは日本語になる。
英語にしたければ、en_US を選択する。

dpkg-reconfigure locales

確認表示があったら…
Locales to be generated: 158 160 288 ← en_US ISO-8859-1, en_US.UTF-8 UTF-8, ja_JP.UTF-8.UTF-8
Default locale for the system environment: 6 ← ja_JP.UTF-8

リゾルバの設定。

rm /etc/resolv.conf
dpkg-reconfigure resolvconf

確認表示があったら…
Prepare /etc/resolv.conf for dynamic updates? [yes/no] 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は入っていないな…。

[オプション]VMware Playerで動作を試すときに便利。VMware Playerを使わないときには意味がない。

apt install open-vm-tools-desktop

最終的に使わなくなったパッケージを削除。

apt autoremove

編集環境の後始末

machie-idを削除、dpkgインストール先の待避を解除。

truncate -s 0 /etc/machine-id
rm /sbin/initctl
dpkg-divert --rename --remove /sbin/initctl
apt clean
rm -rf /tmp/*
export HISTSIZE=0
exit
sudo rm $HOME/live-ubuntu-from-scratch/chroot/root/.bash_history

マウントポイントの解除。

sudo umount $HOME/live-ubuntu-from-scratch/chroot/dev/pts
sudo umount $HOME/live-ubuntu-from-scratch/chroot/sys
sudo umount $HOME/live-ubuntu-from-scratch/chroot/proc
sudo umount $HOME/live-ubuntu-from-scratch/chroot/run
sudo umount $HOME/live-ubuntu-from-scratch/chroot/dev

Live CDに収録するファイルを集める

CDイメージのディレクトリimage、およびサブディレクトリを作り、ブートイメージと初期RAMディスクをコピーする。

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

マニフェスト(インストールされているパッケージとバージョンの一覧)を作成する。

cd $HOME/live-ubuntu-from-scratch
sudo chroot chroot dpkg-query -W --showformat='${Package} ${Version}\n' | sudo tee image/casper/filesystem.manifest > /dev/null
sudo cp 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

[2回目以降のみ]squashfsファイルが存在すると生成時に失敗するので、事前に削除しておく。

sudo rm $HOME/live-ubuntu-from-scratch/image/casper/filesystem.squashfs

chrootで作成した環境を圧縮し、squashfsファイルを作成する。※これには時間が掛かる。

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ファイルを作成。

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(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/

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ビットのブートローダーを利用する場合は、黄色の行を加える。

通常
(
   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を生成。

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"

※もしかしたら、cp -ar /usr/lib/grub/i386-pc/ boot/grub/ といったコピーが必要かもしれないが、ウチではなくても問題なかった。

CDブート用のcdboot.imgとcore.imgを結合して、boot.imgを作成。そして、boot.imgができたので、core.imgを削除。

cat /usr/lib/grub/i386-pc/cdboot.img isolinux/core.img > boot/grub/boot.img
rm isolinux/core.img

Grub Menu

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 toram" {
   linux /casper/vmlinuz boot=casper nopersistent toram quiet splash noprompt ---
   initrd /casper/initrd
}

menuentry "Try Ubuntu FS" {
   linux /casper/vmlinuz boot=casper nopersistent quiet splash noprompt ---
   initrd /casper/initrd
}

menuentry "Check disc for defects" {
   linux /casper/vmlinuz boot=casper integrity-check quiet splash ---
   initrd /casper/initrd
}
EOF

併せて、EFIの場合にGrubのメニューが呼び出されるように、/.disk/infoというファイルを作っておく。

mkdir .disk
echo "Ubuntu 22.04 from scratch" > .disk/info

Legacy(ISOLINUX)

Grubで起動する環境を構築しているが、起動時に何らかの理由でISOLINUXのファイルを読みに行くかもしれないので、その場合でも起動ができるようにファイルを用意しておく。

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 toram
 MENU DEFAULT
 KERNEL /casper/vmlinuz
 APPEND initrd=/casper/initrd boot=casper nopersistent toram quiet splash ---

LABEL linux
 MENU LABEL Try Ubuntu FS
 MENU DEFAULT
 KERNEL /casper/vmlinuz
 APPEND initrd=/casper/initrd boot=casper nopersistent 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 ---
EOF

搭載RAMが2GBのMiix 2 8では、toram指定をしてOSを読み込むとデスクトップが表示できない問題が発生する。
ギリギリRAMの中に収まるからメモリにロードしてしまい、その後にメモリ不足で動作できないようだった。
そのため、toram指定を外した選択肢を用意している。

必要モジュールを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イメージを作成。

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 1.6G May  7 09:20 ../ubuntu-from-scratch.iso

※最低限のつもりだったけれども、それでも1.6GBあった。

Gnome Desktop Managerをインストールしていることもあってか、思ったよりはサイズが小さくならなかった印象。

ISOを取り出して試す

できあがったISOイメージを取り出すのに、VMwareの共有フォルダの仕組みを使う。

sudo mount -t fuse.vmhgfs-fuse -o allow_other .host:/VMware /mnt
cp ../ubuntu-from-scratch.iso /mnt/
sudo umount /mnt

8GBをアサインした仮想環境で、起動直後にfreeコマンドを実行してavailableを確認したところ、5.5GBであり、ISOイメージのサイズ削減がそのまま反映されたようだ。だいぶ小さな環境ができあがった。

再編集

これまでの作業でできたLive CDは最低限過ぎるので、あれこれと再編集したくなるはずなので、再編集の手順だけを切り出して整理する(実際、何度この手順をやり直したか知れない…)。

編集環境に入る

編集をはじめるために以下を実行。

sudo mount --bind /dev $HOME/live-ubuntu-from-scratch/chroot/dev
sudo mount --bind /run $HOME/live-ubuntu-from-scratch/chroot/run
sudo mount --bind /proc $HOME/live-ubuntu-from-scratch/chroot/proc
sudo mount --bind /sys $HOME/live-ubuntu-from-scratch/chroot/sys
sudo mount --bind /dev/pts $HOME/live-ubuntu-from-scratch/chroot/dev/pts
sudo chroot $HOME/live-ubuntu-from-scratch/chroot
export HOME=/root
export LC_ALL=C
dbus-uuidgen > /etc/machine-id
ln -fs /etc/machine-id /var/lib/dbus/machine-id
dpkg-divert --local --rename --add /sbin/initctl
ln -s /bin/true /sbin/initctl
rm /etc/resolv.conf
cat <<EOF > /etc/resolv.conf
nameserver 127.0.0.53
EOF
apt update

これでLive環境が編集できるようになる。細かな編集をしてもいいし、パッケージをインストールしたり、アンインストールしてもいい。

編集

chroot環境で、パッケージの追加・削除、各種設定変更など、Live環境に組み込みたいことを実施。

casperを含むinitramfsへの変更を実行したときや、古いカーネルを削除してシェイプアップしたときには、

dpkg-reconfigure initramfs-tools

を実行しておく。

編集環境から抜けてISOを作る

編集が終わったら、chroot環境から抜けてISOを作る。

apt -f autoremove
rm /etc/resolv.conf
dpkg-reconfigure resolvconf

確認表示があったら…
Prepare /etc/resolv.conf for dynamic updates? [yes/no] yes

後は、問いかけもなくすーっと流れていく処理。

truncate -s 0 /etc/machine-id
rm /sbin/initctl
dpkg-divert --rename --remove /sbin/initctl
apt clean
rm -rf /tmp/*
export HISTSIZE=0
exit
sudo rm $HOME/live-ubuntu-from-scratch/chroot/root/.bash_history

sudo umount $HOME/live-ubuntu-from-scratch/chroot/dev/pts
sudo umount $HOME/live-ubuntu-from-scratch/chroot/sys
sudo umount $HOME/live-ubuntu-from-scratch/chroot/proc
sudo umount $HOME/live-ubuntu-from-scratch/chroot/run
sudo umount $HOME/live-ubuntu-from-scratch/chroot/dev

cd $HOME/live-ubuntu-from-scratch
sudo cp chroot/boot/vmlinuz-**-**-generic image/casper/vmlinuz
sudo cp chroot/boot/initrd.img-**-**-generic image/casper/initrd

sudo chroot chroot dpkg-query -W --showformat='${Package} ${Version}\n' | sudo tee image/casper/filesystem.manifest > /dev/null
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

sudo rm image/casper/filesystem.squashfs
sudo mksquashfs chroot image/casper/filesystem.squashfs
printf $(sudo du -sx --block-size=1 chroot | cut -f1) > image/casper/filesystem.size

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)"
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 \
   ./

sudo mount -t fuse.vmhgfs-fuse -o allow_other .host:/VMware /mnt
cp ../ubuntu-from-scratch.iso /mnt/
sudo umount /mnt

だいたいこんなところだろうと思われる。

細かな設定

カスタマイズに関して整理したこと。過去に整理したものへのリンク。
必要なことが出てきたら、ここに追記していく。

GNOMEデスクトップの細かな設定
入力メソッドをMozcにして、背景画像を変更し、ブランクスクリーンを「しない」に変更するなど。

Microsoft Edgeの設定
起動時にキーリングを聞かれることへの対応、ブックマークの設定など。

古いカーネルの削除
気が付くとカーネルがバージョンアップしていて、容量が大きくなっている件への対応。

カーネルGAからHWEへの差し替え
mvallim氏の手順でGAをインストールしたところ、新しいハードウェアに追従できていなかった。
カーネルをHWEに差し替えて色々な環境でXが上手く使えるようにする。

参考サイト

今回も色々なサイトにお世話になりました。ありがとうございました。

FireFoxはsnapでインストールしても上手く動かなかった。
omg! ubuntu! / How to Install Firefox as a .Deb on Ubuntu 22.04 (Not a Snap)
Launchpad / Firefox ESR and Thunderbird stable builds

コンソールを日本語化するにはどうすれば良いのか調べていたところ見つけた情報。
余白の余白 / debian wheezy 端末 chmod 0666 /dev/fb0で起動することができた。
Qiita / メモ: framebufferを利用 fepの導入ができた。
HacoLab / 【FreeBSD】仮想コンソールで日本語入力したい(uim-fep+mozc) 入力モードの切り替えができた。

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