ラズパイ向けSDカード作成
1. バックアップを取る
code:bash
# バックアップ
## SDカードを挿す前に
$ lsblk
...
## SDカードを挿して再度
$ lsblk
...
sda 8:0 1 29.7G 0 disk
├─sda1 8:1 1 256M 0 part /media/xxx/bootfs
└─sda2 8:2 1 29.5G 0 part /media/xxx/rootfs
## ddコマンドでバックアップする前にアンマウントする
sudo umount /media/xxx/bootfs
sudo umount /media/xxx/rootfs
## ddする
sudo dd if=/dev/sda of=~/raspi_backup_$(date +%Y%m%d).img bs=4M status=progress
## 必要に応じて圧縮したい場合は以下
sudo dd if=/dev/sda bs=4M status=progress | gzip > ~/raspi_backup_$(date +%Y%m%d).img.gz
2. イメージを圧縮
2.1. 自力でがんばる
「ファイルシステム縮小 → パーティション縮小 → イメージ縮小」とする。
code:bash
# 仮想ディスクとしてマウント
$ sudo losetup -Pf --show ~/raspi_backup_20251109.img
/dev/loop0
# ファイルシステムの圧縮
## ファイルシステムの整合性チェック (準備)
$ sudo e2fsck -f /dev/loop0p2
e2fsck 1.46.5 (30-Dec-2021)
Pass 1: Checking inodes, blocks, and sizes
Inodes that were part of a corrupted orphan linked list found. Fix<y>? yes
Inode 261308 was part of the orphaned inode list. FIXED.
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
rootfs: ***** FILE SYSTEM WAS MODIFIED *****
rootfs: 212907/1925760 files (0.2% non-contiguous), 2755715/7728128 blocks
## 上記の結果から圧縮量を決定する
## rootfs: 212907/1925760 files (0.2% non-contiguous), 2755715/7728128 blocks
## - 全ブロック数: 7728128
## - 使用中ブロック数: 2755715
## - ブロックサイズ: 通常 ext4 の場合は 4KB(=4096 bytes)
## 使用中のサイズ= 2755715 × 4096 = 11287408640 bytes
## = 11287408640 * 1/(1024*1024*1024) Gbytes/bytes
## = 10.51 GB
## 10%の余裕を見て11.6GB以上とする。resize2f2は小数を扱えないので12Gとする
$ sudo resize2fs /dev/loop0p2 12G
# パーティションを圧縮
## パーティションテーブルの確認
$ sudo fdisk -l /dev/loop0
Disk /dev/loop17: 29.73 GiB, 31927042048 bytes, 62357504 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: 0xd1f84a17
Device Boot Start End Sectors Size Id Type
/dev/loop0p1 8192 532479 524288 256M c W95 FAT32 (LBA)
/dev/loop0p2 532480 62357503 61825024 29.5G 83 Linux
## パーティションテーブルの確認
$ sudo fdisk -l /dev/loop0
Disk /dev/loop17: 29.73 GiB, 31927042048 bytes, 62357504 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: 0xd1f84a17
Device Boot Start End Sectors Size Id Type
/dev/loop0p1 8192 532479 524288 256M c W95 FAT32 (LBA)
/dev/loop0p2 532480 62357503 61825024 29.5G 83 Linux # ←ココに注目
## パーティションテーブルを変更し、2番目のパーティションを縮小
$ sudo fdisk /dev/loop0
Welcome to fdisk (util-linux 2.37.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
### 第2パーティションを削除
Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 has been deleted.
### 新たに第2パーティションを作成
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-62357503, default 2048): 532480
Last sector, +/-sectors or +/-size{K,M,G,T,P} (532480-62357503, default 62357503): +12G
Created a new partition 2 of type 'Linux' and of size 12 GiB.
Partition #2 contains a ext4 signature.
Do you want to remove the signature? Yes/No: No # 今回は既存のデータを残したいのでNo
### 書き込み
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
## partprobeまたはlosetupコマンドを用いて、カーネルにパーティションを再読込させる
sudo partprobe /dev/loop0
sudo losetup -c /dev/loop0
## ファイルシステムのチェック
sudo e2fsck -f /dev/loop0p2
# イメージファイルを切り捨てる
## セクターサイズの確認
sudo fdisk -l /dev/loop0
Disk /dev/loop5: 29.73 GiB, 31927042048 bytes, 62357504 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: 0xd1f84a17
Device Boot Start End Sectors Size Id Type
/dev/loop0p1 8192 532479 524288 256M c W95 FAT32 (LBA)
/dev/loop0p2 532480 25698303 25165824 12G 83 Linux
## imgファイルのサイズ計算
echo "scale=2; (25698303+1)*512" | bc
13157531648
## imgファイルの縮小
sudo truncate --size=13157531648 ~/raspi_backup_20251109.img
# 開始セクタ532480から12GiB(=12*1024^3=12884901888 bytes)分のセクタに切り詰める。
# 532480 + 12884901888/512 -1 = 25698303
# セクタを再度サイズにして
# (25698303+1)*512=13157531648 bytes
$ truncate --size=13157531648 ~/raspi_backup_20251109.img
# デタッチ
$ sudo losetup -d /dev/loop0
# 圧縮
xz -T4 -6 ~/raspi_backup_20251109.img # ~/raspi_backup_20251109.img.xzが生成される
2.2. pishrinkを使う
code:bash
sudo apt update
sudo apt install -y wget parted gzip xz-utils pigz e2fsprogs
wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh
chmod +x pishrink.sh
sudo mv pishrink.sh /usr/local/bin/pishrink.sh
sudo pishrink.sh ~/raspi_backup_20251109.img # 圧縮して上書きされる
2.3. imgファイルの検証
code:bash
# アタッチ
sudo losetup -Pf --show ~/raspi_backup_20251109.img
# パーティションの確認
sudo fdisk -l /dev/loop0
Device Start End Sectors Size Type
/dev/loop0p1 8192 532479 524288 256M W95 FAT32
/dev/loop0p2 532480 25698303 25165824 12G Linux
# ファイルシステムのチェック
sudo e2fsck -f /dev/loop0p2
# ファイルシステムのマウント (Read-only)
sudo mkdir -p /mnt/img_root
sudo mount -o ro /dev/loop0p2 /mnt/img_root
ls /mnt/img_root
df -h /mnt/img_root
# FATパーティションの確認
sudo mkdir -p /mnt/img_boot
sudo mount -o ro /dev/loop0p1 /mnt/img_boot
ls /mnt/img_boot
# ファイルシステムのマウント(Read-Write)
sudo umount /mnt/img_root
sudo mount /dev/loop0p2 /mnt/img_root
# 終了
sudo umount /mnt/img_root
sudo umount /mnt/img_boot
sudo losetup -d /dev/loop0
3. イメージを書き込む
3.1. 書き込み先SDカードの消去
3.1.1. 方法① テーブル削除
code:bash
# アンマウント
$ sudo umount /dev/sdb1
$ sudo umount /dev/sdb2
# テーブル消去
$ sudo fdisk /dev/sdb
Command (m for help): o ← 新しい空のDOSパーティションテーブル作成
Command (m for help): w ← 保存して終了
3.1.2. 方法② ゼロ埋め
code:bash
# ゼロ埋め (システムを破損しないように注意)
sudo dd if=/dev/zero of=/dev/sdb bs=1M count=100
sync
3.1.3. 方法③ wipefsでファイルシステム情報を削除(速いがデータは残る)
code:bash
sudo wipefs -a /dev/sdb
3.2. イメージ書き込み
code:bash
sudo fdisk -l /dev/sdb
sudo dd if=~/raspi_backup.img of=/dev/sdb bs=4M conv=fsync status=progress
sync # メモリ→書き込みの転送完了を確認
3.3. SDカードのパーティション拡張
pishrink.shは自動拡張機能を有効にしたりしてくれるらしいが、pishrinkを使わずシンプルにコピーする場合は、以下のようにして拡張しておく。あるいは、ラズパイ起動後にsudo raspi-config → Expand Filesystemする。
code:bash
# パーティションの拡張
## パーティションの確認
$ sudo fdisk -l /dev/sdb
Disk /dev/sdb: 29.72 GiB, 31914983424 bytes, 62333952 sectors
Disk model: STORAGE DEVICE
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: 0xd1f84a17
Device Boot Start End Sectors Size Id Type
/dev/sdb1 8192 532479 524288 256M c W95 FAT32 (LBA)
/dev/sdb2 532480 25698303 25165824 12G 83 Linux
## パーティションテーブルの再作成
$ sudo fdisk /dev/sdb
d ← 2番のパーティション削除
n ← 新規作成
p ← primary
2 ← 番号2
532480 ← 開始セクタ
+12G ← サイズ (デフォルトを使用するということで空欄でもよい)
w ← 保存
# 再スキャン (カーネルにパーティションテーブルの変更を通知)
$ sudo partprobe /dev/sdb
# ファイルシステム拡張
sudo e2fsck -f /dev/sdb2 # Fix
sudo resize2fs /dev/sdb2 # Extend
#パーティション操作の基礎知識 も参照のこと
#ラズパイ