背景

Raspbianに対して各種インストールを行い,それをバックアップするため,もしくは別のRaspberry Piでも使えるようにするためにイメージをコピーしたいことがあります.ただ全く同じSDカードであったとしても容量が少しずつ異なることがありますし,異なる種類の場合には単純にイメージを吸い出した場合に入らないということがごく普通に起こります.そこで,最低限のサイズにファイルシステムを縮小し,その後,イメージを作成することにします.また,他のSDカードにイメージを入れた後,未使用の領域を使えるようにする方法も説明します.

概要

行なう内容としては以下のとおりです.

  1. ファイルシステムおよびパーティションの縮小
  2. イメージの作成
  3. 他のSDカードへイメージを展開(別ページ)
  4. 未使用の領域を使えるように拡張

環境

使用する機材を示します.

  • Raspberry Pi 3(USBポートが2つ以上あること)
  • コピー元となるSDカード(USB変換器も必要)
  • コピー先となる記憶媒体(吸い出されるイメージのサイズより大きい必要あり)
  • Raspbianの入ったSDカード(コピー元となるSDカードとは別に必要)

それぞれの機材の接続状況を下の図にまとめてみました.コピー元となるSDカードとは別の,RaspbianがインストールされているSDカードをRaspberry PiのSDカードを装着するところへ入れて起動します.ここで注意しなければならないのは,コピー元となるSDカードでOSを起動していないということです.あくまでコピー元となるSDカードは外部に接続された記憶媒体に入っているデータにすぎない状態にするということです.そのためにはUSB変換器でコピー元となるSDカードをRaspberry Piにつなぎます.

 

image01

なお,後ほど各デバイスの名前を使い,それぞれのデバイスを指定することとなります.そのためにこのページでは各デバイスの名前を次のようになったとして説明していきます.

  • コピー元となるSDカード : /dev/sda
  • コピー先となる記憶媒体 : /dev/sdb

 

方法

ファイルシステムおよびパーティションの縮小

参考にしたサイトはこちらです.さて,ここでは適正な最小値を求め,その大きさにパーティションを変更するという2点です.適正値の求め方について説明します.なお,先に述べたとおり,コピー元となるSDカードは/dev/sdaとして認識されているものとして説明します.このコピー元となるSDカードがどのようなデバイス名で認識されているか確認するには,下のようにfdiskを使います.

pi@raspberrypi:~ $ sudo fdisk -l
Disk /dev/ram0: 4 MiB, 4194304 bytes, 8192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

※中略

Disk /dev/sda: 29.8 GiB, 32010928128 bytes, 62521344 sectors
Disk model:                 
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: 0x5e3da3da

Device     Boot  Start      End  Sectors  Size Id Type
/dev/sda1         8192   532479   524288  256M  c W95 FAT32 (LBA)
/dev/sda2       532480 19732480 19200001  9.2G 83 Linux

 ここで大事なのは一番下の3行です./dev/sda1と2がデバイスとして認識されていることが分かります.さて,この/dev/sda2の適正な最小値を求めましょう.それには次のようにします.

pi@raspberrypi:~ $ sudo resize2fs -P /dev/sda2
resize2fs 1.44.5 (15-Dec-2018)
Estimated minimum size of the filesystem: 2275588

上の場合,/dev/sda2のサイズは2275588[block]です.1[block]は4[KiByte](これはext4のデフォルトで決められています)であるため,バイト数に直すとすると2275588×4×1024=9320808448[byte]となります.

このブロックサイズ,ちょうどにしてもよいのですが,ある程度余裕を見て,区切りのいい2400000[block]に縮小することとします.マウントしてあった場合,下のようにアンマウントします.

pi@raspberrypi:~umount /dev/sda2

その後,下のようにファイルシステムのチェックとサイズの変更を行います.

pi@raspberrypi:~ $ sudo e2fsck -f /dev/sda2
pi@raspberrypi:~ $ sudo resize2fs -p /dev/sda2 2400000

このままファイルシステムについては縮小しましたが,まだパーティションの縮小を行っていません.続いてはパーティションの縮小を行います.パーティションの操作にはfdiskコマンドを使います.下の図のようにまずは現状を確認します.

pi@raspberrypi:~ $ sudo fdisk -l /dev/sda
Disk /dev/sda: 29.8 GiB, 32010928128 bytes, 62521344 sectors
Disk model:                 
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: 0x5e3da3da

Device     Boot  Start      End  Sectors  Size Id Type
/dev/sda1         8192   532479   524288  256M  c W95 FAT32 (LBA)
/dev/sda2       532480 62521343 61988864 29.6G 83 Linux

先ほどのファイルサイズについての縮小では,単位がblockでした.それに対してfdiskではsector単位になります.blockとsectorの関係は,実は少し前のfdisk -lにて表示されると文字列に512[byte]であることが書かれています.sda2のEndにある62521343の単位はsectorです.従って,バイトに直すと62521343×512=32010927616[byte]=およそ32[Gbyte]です.今回使用しているSDカードは32[GB]ですので,容量の最後まで使い切っている状態に現状ではなっています.これを縮小していきます.先ほど2400000[block]に縮小しましたので,これをsectorに単位を直しつつ考えていきたいと思います.まず,/dev/sda2のサイズを2400000[block]にするということなので,これをsectorにすると,1[block]=8[sector]のため,2400000×8=19200000[sector]にすればよいことになります./dev/sda2のStartが532480[sector]ですので,Endは532480+19200000=19732480[sector]にすればよいです.

では実際にパーティションを操作しましょう.はじめに,パーティションの削除を行います.下のようにfdiskのdコマンドを使います.そして,削除するパーティション番号である2を選択します.

pi@raspberrypi: $ sudo fdisk /dev/sda
Command (m for help): d
Partition number (1,2, default 2): 2

Partition 2 has been deleted.

次にパーティションを作成します.パーティションの作成には下のようにnコマンドを使います.パーティションタイプはプライマリですのでp,パーティション番号は2,パーティション開始セクタは元と同じ532480,パーティション終了セクタは先ほど計算した19732480,最後にSignatureを削除するか問い合わせられるのでN(削除しない)をそれぞれ選択します.

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-62521343, default 2048): 532480
Last sector, +/-sectors or +/-size{K,M,G,T,P} (532480-62521343, default 62521343): 19732480

Created a new partition 2 of type 'Linux' and of size 9.2 GiB.
Partition #2 contains a ext4 signature.

Do you want to remove the signature? [Y]es/[N]o: N

この後,パーティションの修正後を下のようにpコマンドを使ってします./dev/sda2のセクタ数が希望通りになっています.

Command (m for help): p

Disk /dev/sda: 29.8 GiB, 32010928128 bytes, 62521344 sectors
Disk model:                 
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: 0x5e3da3da

Device     Boot  Start      End  Sectors  Size Id Type
/dev/sda1         8192   532479   524288  256M  c W95 FAT32 (LBA)
/dev/sda2       532480 19732480 19200001  9.2G 83 Linux

最後にこの設定を書き込みます.下のようにwコマンドで反映されます.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

イメージの作成

イメージの作成にはddコマンドを使います.これはRaspbianはじめLinux系OSではよくつかわれるコマンドです.ddにて,コピーするサイズを指定することで,SDカード全てをイメージ化せず,必要な領域のみのコピーにすることができます.ddで指定するサイズの単位はKiblock(Ki=キビ,1024をあらわします)です.ということで,まずはコピーするサイズをバイトで求めてみましょう.

先ほどと同じだと思いますが,/dev/sdaのセクタを確認します.下の図のようにfdiskを使います.

pi@raspberrypi:~ $ sudo fdisk -l /dev/sda
Disk /dev/sda: 29.8 GiB, 32010928128 bytes, 62521344 sectors
Disk model:                 
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: 0x5e3da3da

Device     Boot  Start      End  Sectors  Size Id Type
/dev/sda1         8192   532479   524288  256M  c W95 FAT32 (LBA)
/dev/sda2       532480 19732480 19200001  9.2G 83 Linux

この結果,/dev/sdaの末尾は19732480[sector]であることが分かります.これをバイトに直すと,1[sector]=512[byte]ですので,19732480×512=10103029760[byte]です.今度はこれをblockに直します.1[block]=4096[byte]ですので,10103029760÷4096=2466560[block]です.ただし,ddではKiblockを用いますので,2466560÷1024=2408.75この値を切り上げて,2409[Kiblock]となります.ddコマンドは下に示すように使います.パラメタの意味ですが,bsがブロックサイズ,countが書き込みサイズ,ifがソースデバイス,ofが出力先となります.この例では出力先として外部記憶装置を/media/pi/LIVEにマウントしており,その中にbuster202001.imgという名前で保存しています.

pi@raspberrypi:~ $ sudo dd bs=4M count=2409 if=/dev/sda of=/media/pi/LIVE/buster202001.img status=progress

サイズによりますが,こちらの環境ではおよそ1時間弱,かかります.

他のSDカードへイメージを展開

こちらをご覧ください.

未使用の領域を使えるように拡張

未使用領域を使えるように拡張するには,下のユーティリティが便利です.

pi@raspberrypi:~ $ sudo raspi-config

この中の7 Advanced Options ⇒ A1 Expand Filesystem Ensures that all of the SD card storage is available で拡張できます.その後,リブートが必要になります.以上ですべての作業が終わりです.