1 はじめに
Raspberry Piで色々実験を行っていると、それまでの作業をなかったことにして、最初からやり直したいときがある。最初からといっても、決まりきったライブラリのインストールやビルドなどは、やり直したくない。そこで、公式のOSイメージをカスタマイズし、aptやpipを使ったインストールやライブラリのビルドを事前に行った状態のOSイメージを作成しておくことにする。
カスタムイメージを作成する方法としては、一連のインストールを終えたのちに、SDカードイメージをダンプするという手もとれる。しかし、この方法のデメリットとして、書き込み先SDカードのサイズがダンプサイズより大きくないと手間がかかることにある。同じサイズのSDカード、例えば32GBカードであっても、メーカーやロットによって微妙なサイズが異なる。同時期にかった同じメーカーとの同じ型番のSDカードにダンプイメージをコピーできなかったときのショックは極めて大きい。
また、公式のOSイメージは、起動時にパーティションサイズを自動で最大まで拡張するので、使用するSDカードのサイズに影響されないという特徴がある。
2 準備するもの
- Raspberry Pi(今回は4Bを使うが他のモデルでもいけるはず)
- Raspberry Pi OSファイル
https://www.raspberrypi.com/software/operating-systems/ - マイクロSDカード2枚
- OSイメージをカスタムするためのOSを動かすSDカード
- カスタムしたOSイメージを動かすためのSDカード
3 手順
3.1 環境の準備
まずは、カスタムイメージを操作する環境として、通常通りのOSイメージを用意する。Raspberry Pi ImagerなどでOSをSDカードに書き込む。トラブル防止のため、カスタムするOSと作業するOSは同じとする。今回はBullseye Lite 64bitを使う。起動するまでは、きわめて普通。
3.2 カスタム対象の準備
とりあえず、ユーザー名はuser、作業ディレクトリ名はホームのworkとする。
起動したら、カスタムしたいOSイメージのファイルをRPiの中に書き込む。wgetやcurlで取得してもいいし、sshなどでローカル転送してもよい。
今回は個々のファイルを使った。
https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2023-05-03/2023-05-03-raspios-bullseye-arm64-lite.img.xz
以下の状態にする。
$ ls -al /home/user/work/
-rw-r--r-- 1 xacti xacti 322504480 Sep 17 18:04 2023-05-03-raspios-bullseye-arm64-lite.img.xz
次に、パーティションテーブルからデバイスマップを作成するアプリケーションをインストールする。
$ sudo apt install kpartx
圧縮されたOSイメージを伸長する。オプション付けていないので元ファイルはなくなる。
「.xz」がとれた「2023-05-03-raspios-bullseye-arm64-lite.img」が生成される
$ unxz 2023-05-03-raspios-bullseye-arm64-lite.img.xz
3.3 パーティションのサイズ拡張
事前にルートパーティションのサイズを拡張する。というのも後述のfdiskの結果の通り、全体で1.96GiB、デフォルトのルートパーティションには1.7GBしか割り当てがない。多くのソフトウェアをインストールすると、領域不足になる。ちょっと入れるだけなら不要な作業なのでスキップしてもよい。
$ fdisk -l 2023-05-03-raspios-bullseye-arm64-lite.img
Disk 2023-05-03-raspios-bullseye-arm64-lite.img: 1.96 GiB, 2101346304 bytes, 4104192 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: 0x544c6228
Device Boot Start End Sectors Size Id Type
2023-05-03-raspios-bullseye-arm64-lite.img1 8192 532479 524288 256M c W95 FAT32 (LBA)
2023-05-03-raspios-bullseye-arm64-lite.img2 532480 4104191 3571712 1.7G 83 Linux
3.3.1 ファイルを指定したサイズに変更
全体で4GBとしておく。必要に応じてもっと大きくしてもよい。
$ truncate -s 4GiB 2023-05-03-raspios-bullseye-arm64-lite.img
確認すると「4 GiB」となっている。
$ fdisk -l 2023-05-03-raspios-bullseye-arm64-lite.img
Disk 2023-05-03-raspios-bullseye-arm64-lite.img: 4 GiB, 4294967296 bytes, 8388608 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: 0x544c6228
Device Boot Start End Sectors Size Id Type
2023-05-03-raspios-bullseye-arm64-lite.img1 8192 532479 524288 256M c W95 FAT32 (LBA)
2023-05-03-raspios-bullseye-arm64-lite.img2 532480 4104191 3571712 1.7G 83 Linux
ルートパーティションサイズの変更
ルートパーティションを1.7GBから3.5GBに拡張する。入力は以下のようにしている。「2023-05-03-raspios-bullseye-arm64-lite.img2」の開始セクタ番号は変える必要はないので、532480はそのまま使う。
p, d, 2, n, p, 2, 532480, +3.5G, p, w
ログが長いけど、つまりは2番目のパーティションを削除してから作り直している。
$ fdisk 2023-05-03-raspios-bullseye-arm64-lite.img
Welcome to fdisk (util-linux 2.36.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p
Disk 2023-05-03-raspios-bullseye-arm64-lite.img: 4 GiB, 4294967296 bytes, 8388608 sectorsUnits: 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: 0x544c6228
Device Boot Start End Sectors Size Id Type
2023-05-03-raspios-bullseye-arm64-lite.img1 8192 532479 524288 256M c W95 FAT32 (LBA)
2023-05-03-raspios-bullseye-arm64-lite.img2 532480 4104191 3571712 1.7G 83 Linux
Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 has been deleted.
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 2
First sector (2048-8388607, default 2048): 532480
Last sector, +/-sectors or +/-size{K,M,G,T,P} (532480-8388607, default 8388607): +3.5G
Created a new partition 2 of type 'Linux' and of size 3.5 GiB.
Partition #2 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: N
Command (m for help): p
Disk 2023-05-03-raspios-bullseye-arm64-lite.img: 4 GiB, 4294967296 bytes, 8388608 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: 0x544c6228
Device Boot Start End Sectors Size Id Type
2023-05-03-raspios-bullseye-arm64-lite.img1 8192 532479 524288 256M c W95 FAT32 (LBA)
2023-05-03-raspios-bullseye-arm64-lite.img2 532480 7872511 7340032 3.5G 83 Linux
Command (m for help): w
The partition table has been altered.
Syncing disks.
確認する。3.5GBに増えてる。
$ fdisk -l 2023-05-03-raspios-bullseye-arm64-lite.img
Disk 2023-05-03-raspios-bullseye-arm64-lite.img: 4 GiB, 4294967296 bytes, 8388608 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: 0x544c6228
Device Boot Start End Sectors Size Id Type
2023-05-03-raspios-bullseye-arm64-lite.img1 8192 532479 524288 256M c W95 FAT32 (LBA)
2023-05-03-raspios-bullseye-arm64-lite.img2 532480 7872511 7340032 3.5G 83 Linux
4 カスタム先のrootになる
4.1 デバイスマップ作成
kpartxを使いデバイスマップを作成
$ sudo kpartx -av 2023-05-03-raspios-bullseye-arm64-lite.img
add map loop0p1 (254:0): 0 524288 linear 7:0 8192
add map loop0p2 (254:1): 0 3571712 linear 7:0 532480
確認する。1番目のパーティションが /boot で loop0p1に対応、2番目のパーティションがルートファイルシステムでloop0p2に対応。
$ ls /dev/mapper/
control loop0p1 loop0p2
4.2 パーティションのリサイズ
パーティションのリサイズを実行。ここで、パーティションのリサイズを実行。これしないで、何度か容量不足のエラーをみた。
$ sudo fsck -n /dev/mapper/loop0p2
fsck from util-linux 2.36.1
e2fsck 1.46.2 (28-Feb-2021)
rootfs: clean, 41802/111776 files, 356622/446464 blocks
$ sudo e2fsck -f /dev/mapper/loop0p2
e2fsck 1.46.2 (28-Feb-2021)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
rootfs: 41802/111776 files (0.1% non-contiguous), 356622/446464 blocks
$ sudo resize2fs /dev/mapper/loop0p2
resize2fs 1.46.2 (28-Feb-2021)
Resizing the filesystem on /dev/mapper/loop0p2 to 917504 (4k) blocks.
The filesystem on /dev/mapper/loop0p2 is now 917504 (4k) blocks long.
4.3 マウント
マウントポイントを作成し、マウントする
$ sudo mkdir tmpmnt
$ sudo mount -t ext4 -o loop /dev/mapper/loop0p2 tmpmnt/
中身を確認すると、ルート以下のディレクトリ構成が見える。これらがカスタム対象。
$ ls tmpmnt/
bin boot dev etc home lib lost+found media mnt opt proc root run
sbin srv sys tmp usr var
領域のサイズも指定したサイズ。
$ df -h tmpmnt/
Filesystem Size Used Avail Use% Mounted on
/dev/loop1 3.5G 1.3G 2.0G 41% /home/xacti/work/tmpmnt
4.4 パッケージのインストール準備
chrootして、パッケージインストールできる状態になる。
$ sudo chroot tmpmnt/
root@raspberrypi:/#
ここから先はカスタム先のOSに対する操作となる。
時間を確認すると、タイムゾーンがBST(英国)になっている。
# date
Sun 16 Sep 10:26:14 BST 2023
aptなどでトラブルが起きると嫌なので、JSTにしておく。
# rm -f /etc/localtime
# ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# root@raspberrypi:/# date
Sun 16 Sep 18:33:31 JST 2023
update & upgradeしておく。必要ないならスキップ。
# apt update
# apt upgrade
通信ができない場合
環境によっては、DNSの影響かもしれない。自分が当たった状況では、
# nano /etc/resolv.conf
で nameserverをデフォルトの8.8.8.8から接続しているルーターのIPアドレスにした。
4.5 パッケージのインストール
ここまできたら、apt installし放題。また、/etc以下の設定ファイルをあらかじめ変更しておくことも可能。
これは自分用のメモ
apt -y install libssl-dev libcurl4-openssl-dev liblog4cplus-dev libcgroup-dev gir-to-d
apt -y install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-tools
apt -y install gstreamer1.0-plugins-bad gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly
apt -y install jq python3-pip
sudo apt -y install gir1.2-gst-rtsp-server-1.0
sudo apt -y install libcairo2-dev libxt-dev libgirepository1.0-dev
pip install pycairo PyGObject
5 後始末
コマンド履歴の削除とaptのキャッシュクリア。操作に応じて残骸ファイルの削除なども行う。
# history -c
# apt clean all
Ctrl+D でchroot状態を抜ける。
アンマウントして、デバイスマップを解除。
$ sudo umount tmpmnt
$ sudo kpartx -d 2023-05-03-raspios-bullseye-arm64-lite.img
6 カスタムOSイメージの圧縮
変更したファイルを以下のコマンドで元の形式に圧縮する。一応ファイル名を変えておく、実行環境はパワーのあるPC上とかの方がいい。xzは処理が遅い。
$ mv 2023-05-03-raspios-bullseye-arm64-lite.img 2023-05-03-raspios-bullseye-arm64-lite-custom.img
$ time xz -9 2023-05-03-raspios-bullseye-arm64-lite-custom.img
7 おまけ
ブート領域のファイルの変更もできる。
マウントを以下のようにloop0p1にすればconfig.txtなどが見えるので、変更しておけば機能の無効化やGPUメモリの変更などをあらかじめ指定しておくことができる。
$ sudo mount -t ext4 -o loop /dev/mapper/loop0p1 tmpmnt/
単なるファイル群なので、chrootなどは不要。nanoなどでファイル変更して保存すればよい。
今後
- 追加パーティションを作るようにしたい。/boot、/、/extみたいな状態。