びぼうろく

北海道の人。適当にもっさりまったり書きます。さくら荘のましろが好きです。アニメとかパソコンとか

RaspberryPiでカスタムイメージを作る

RaspberryPi OSのカスタムイメージ

最近、ラズパイゼロ向けにカスタムイメージを作る事があったのだが、
ggっても簡単に手順が出てこなかったのでここに書いておく。

カスタムイメージ作成環境

Windows10 ver.2004 PC
TeraTerm
SDCardFormatter
Win32DiskImager

RaspberryPi Zero WH
・2020-08-20-raspios-buster-armhf-lite.img
microSD 16GB

Ubuntu20.04 PC*1

手順

1. OSイメージのダウンロード

RaspberryPi OSを本家からダウンロード
こういうときこそtorrentが便利。これぞtorrentの正しい使い方!
Operating system images – Raspberry Pi

2. microSDのフォーマット

windowsmicroSDを接続して、SDCardFormatterでフォーマット
すでにRaspberryPi OSが入ってる場合は、パーティションが切られてるので、
スタートWindows 管理ツールコンピューターの管理ディスクの管理
microSDを探して右クリックからパーティションを削除する

3. RaspberryPi OSを焼く

Win32DiskImagerでダウンロードしたイメージファイルを選択してWriteする
ドライブレターを間違えないようにする

4. boot領域の変更

マウントされている/bootディレクトリの直下に、sshというファイルを作成する。
これで起動時からsshを有効化する。

次に、config.txtの一番下に

dtoverlay=dwc2

を追加する。
次に、commandline.txtの1行の一番うしろに

modules-load=dwc2,g_ether

を追加する。
これでUSB OTG Etherが有効になる。

更に、同じcommandline.txtファイルにある

init=/usr/lib/raspi-config/init_resize.sh

を削除する。
これで初回起動時の自動パーティション拡張が実行されなくなる。

5. OSのぶーと

WindowsからmicroSDを取り外して、ラズパイに接続、
PCとラズパイを接続する。
ラズパイのUSBとシルクがある方のUSB端子に接続する。

6. WindowsPCからラズパイへ接続


ラズパイのUSB OTG Etherのドライバを当てるためにドライバをダウンロード
USB OTG Etherドライバ

スタートWindows 管理ツールコンピューターの管理デバイスマネージャーポート(COMとLPT)から
ラズパイ接続して増えたCOMポートを選んで
右クリックドライバーの更新コンピューターを参照してドライバーを検索
ダウンロードしたドライバフォルダを選択

ドライバがあたると、ネットワークアダプターにUSB Ethernet/RNDIS Gadgetが追加される

teratermを起動して、raspberrypi.localで接続
ユーザ名とパスワードはいつものラズパイデフォルト

※ラズパイをUSB OTG Etherでインターネットに繋ぐ場合


設定ネットワークとインターネット状態アダプターのオプションを変更する
インターネットに接続しているNICを右クリック
プロパティ共有タブ→
ネットワークの他のユーザーに、このコンピューターの(略)のチェックを入れる
ホームネットワーク接続をラズパイのUSB OTG Ether NICを選んでOK

これでラズパイがインターネットに繋がる

7. RaspberryPi OSのカスタマイズ

必要なパッケージのインストールなど、カスタムする

8. 自動パーティション拡張のサービスを抽出

4. boot領域の変更で削除したinit=/usr/lib/raspi-config/init_resize.sh
RaspberryPi OSの初回起動時に自動でSDカードのサイズに合わせてリサイズしてくれるコマンドで
リサイズ後にこの一文が自動で削除される。

これを削除することで自動拡張を防いでいたが、これを有効化する必要がある。
ただ、これをcommandlist.txtに再度追加しても、次回起動時に自動拡張は実行されない。

原因としては、/etc/init.d/resize2fs_once/etc/rc3.d/S01resize2fs_once*2が初回起動時に削除されるためだった

要は、/etc/init.d/resize2fs_once/etc/rc3.d/S01resize2fs_onceを再度追加して
commandlist.txtinit=/usr/lib/raspi-config/init_resize.shを追加すれば良い*3

初回起動前の/etc/init.d/
f:id:gari30:20200926052923p:plain

初回起動後の/etc/init.d/
f:id:gari30:20200926053239p:plain


最初にダウンロードしたRaspberryPi OSを7zipで開いて*4
/etc/init.d/resize2fs_onceをコピーを使って取り出す

取り出したファイルをTeraTermで転送してやって、/etc/init.d/に移動させる
ディレクトリの別ファイルと同じowner、同じパーミッションを設定する

cd /etc/init.d/
sudo chmod 755 resize2fs_once
sudo chown root:root resize2fs_once

次に、code>/etc/rc3.d/S01resize2fs_onceにシンボリックリンクを貼る

cd /etc/rc3.d/
sudo ln -s ../init.d/resize2fs_once S01resize2fs_once

イメージファイル抽出するために現在のパーティションサイズを確認
一番下のデバイスのEndのセクタ番号を控えておく

sudo fdisk -l

これでラズパイをシャットダウンする

sudo shutdown -h now

9. イメージファイルの抽出


microSDからイメージファイルを抽出する

1セクタサイズは固定で512バイトらしい
ベースサイズを1Mバイト(1024*1024バイト)にした場合、
[Endセクタ番号]×512÷(1024×1024)の計算結果を繰り上げて使う

今回はEndセクタ番号が3604479だったので

3604479×512÷(1024×1024) = 1759.99951172

となり、コピーするサイズは1760となる。

ここから、UbuntuPCにmicroSDをマウントする
lsblkコマンドで、SDカードのデバイス名を確認する。
今回のUbuntuPCでは/dev/sdcにマウントされていたので、

dd if=/dev/sdc of=./original.img bs=1M count=1760

を実行し、できたファイルをwindowsに転送する
USBメモリとか使うか、慣れているならそのままUbuntuPCから書き込んでもいいかも
今回はwindowsのデフォルト共有を有効にしているので、ネットワークを使ってコピーした


これでカスタムイメージファイルができた
べつのmicroSDにイメージファイルを焼いて完了!!!やったね!!*5

*1:SDカードからイメージファイルを吸い出すのに使用

*2:こいつはただのシンボリックリンク

*3:詳しくコードを読んでいないから確実ではないけどこれで実際にできたのでOKとする

*4:解答ではなくアーカイブファイルの表示

*5:ホントできてよかった