Win32DiskImager로 백업한 img의 경우 SD메모리와 동일한 사이즈로 생성되기 때문에,
몇 가지 치명적인 단점이 있다.
예를 들어 OS 파티션 크기가 2G라 해도 16G 용량의 SD메모리로 생성한 img 파일은 16G 이기 때문에,
다시 복원할 때 8배의 시간이 소요되며,
16G 보다 작은 크기의 SD메모리로는 복원할 수 없게 된다.
(제조사에 따라 동일한 크기라도 안되는 경우가 있다고 함)
그러므로 생성된 img 파일의 사이즈를 줄이는 방법이 필요하다.
리사이징할 img 파일이 들어있는 외장 HDD가 있고, 리사이징을 수행할 라즈베리파이가 있다고 가정하자.
그리고 외장 HDD는 /dev/sdb1 이라고 가정하고, img 파일명은 my_os.img 라고 가정하자.
// Windows에서 img 파일을 복사했을 것이므로 외장 HDD는 NTFS일텐데,
// 라즈베리파이에서 NTFS RW을 위해 ntfs-3g가 필요함
apt-get install ntfs-3g -y
// 외장 HDD mount
mkdir -p /mnt/ext
mount /dev/sdb1 /mnt/ext
라즈베리파이는 부팅과 기타나머지, 이렇게 2개의 파티션이 존재하는데,
이 중 2번째인 기타나머지 파티션의 사이즈를 줄이게 된다.
각 단계를 수행하기 위해 몇 가지 수치가 필요하다.
fdisk -l /mnt/ext/my_os.img
Disk /mnt/ext/my_os.img: 14.9 GiB, 15931539456 bytes, 31116288 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: 0x00000000
Device Boot Start End Sectors Size Id Type
/mnt/ext/my_os.img1 16 125055 125040 61.1M b W95 FAT32
/mnt/ext/my_os.img2 125056 31116287 30991232 14.8G 83 Linux
1섹터는 512 바이트 라는 것을 알 수 있고, 나머지 필요한 수치도 계산이 가능하다.
START 섹터 = 125056
END 섹터 = 31116287
START 섹터 바이트 사이즈 = START 섹터 x 512 = 125056 x 512 = 64028672
END 섹터 바이트 사이즈 = 전체 바이트 사이즈 = 31116287 x 512 = 15931538944
계산된 수치를 바탕으로 리사이징을 수행한다.
img 파일을 block device처럼 다루기 위해 loop device에 mount 하는데, 전체 img 파일에서 2번째 파티션의 위치/크기 만큼만 mount 한다.
losetup /dev/loop0 /mnt/ext/my_os.img -o 64028672 --sizelimit 15931538944
파일시스템 체크
e2fsck -f /dev/loop0
e2fsck 1.42.12 (29-Aug-2014)
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
/dev/loop0: 53140/931056 files (0.2% non-contiguous), 381058/3873904 blocks
여기서 수치계산이 한 번 더 필요하다.
우선 2G에 해당하는 섹터수가 필요함.
2G를 바이트로 환산 = 2 x 1024 x 1024 x 1024 = 2147483648
이 수치를 섹터수로 환산 = 2147483648 / 512 = 4194304
2G에 해당하는 END 섹터 = 4194304 - 1 = 4194303
이므로,
2G에 해당하는 최종 섹터수 = END 섹터 - START 섹터 + 1 = 4194303 - 125056 + 1 = 4069249
계산된 수치를 바탕으로 resize2fs 를 실행하여, 지정한 END 섹터 바깥에 있는 block 들을 지정한 END 섹터 안으로 옮긴다.
resize2fs /dev/loop0 4069249s
resize2fs 1.42.12 (29-Aug-2014)
Resizing the filesystem on /dev/loop0 to 508656 (4k) blocks.
The filesystem on /dev/loop0 is now 508656 (4k) blocks long.
여기까지 완료했으면 loop device mount를 해제할 것
losetup -d /dev/loop0
이제 fdisk를 이용해 실제 파티션 크기를 줄인다.
fdisk /mnt/ext/my_os.img
Welcome to fdisk (util-linux 2.25.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
// p 커맨드로 파티션 상태를 확인
Command (m for help): p
Disk /mnt/ext/my_os.img: 14.9 GiB, 15931539456 bytes, 31116288 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: 0x00000000
Device Boot Start End Sectors Size Id Type
/mnt/ext/my_os.img1 16 125055 125040 61.1M b W95 FAT32
/mnt/ext/my_os.img2 125056 31116287 30991232 14.8G 83 Linux
// d 커맨드로 2번째 파티션 삭제
Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 has been deleted.
// n 커맨드로 2번째 파티션을 2G 사이즈로 재생성
// START 섹터는 동일하며, END 섹터는 위에서 계산했던 2G 사이즈에 해당되는 4194303
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 (125056-31116287, default 126976): 125056
Last sector, +sectors or +size{K,M,G,T,P} (125056-31116287, default 31116287): 4194303
Created a new partition 2 of type 'Linux' and of size 2 GiB.
// 혹시 이런게 나오면 N 입력할 것
Partition #2 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: N
// 생성된 파티션 확인
Command (m for help): p
Disk /mnt/ext/my_os.img: 14.9 GiB, 15931539456 bytes, 31116288 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: 0x00000000
Device Boot Start End Sectors Size Id Type
/mnt/ext/my_os.img1 16 125055 125040 61.1M b W95 FAT32
/mnt/ext/my_os.img2 125056 4194303 4069248 2G 83 Linux
// w 커맨드로 저장하고 빠져나옴
Command (m for help): w
The partition table has been altered.
Syncing disks.
여기까지 완료했다면 파티션은 준비되었고, 실제 img 파일의 사이즈를 리사이징한 파티션 크기로 줄여야 한다.
최종 사이즈 = (END 섹터 + 1) x 512 = (4194303 + 1) x 512 = 2147483648 (그냥 2G = 2 x 1024 x 1024 x 1024)
계산된 크기만큼 img 파일을 깎아낸다.
truncate -s 2147483648 /mnt/ext/my_os.img
여기까지 실행 후 확인해 보면 my_os.img 의 사이즈도 2G가 되어 있다.
이제 이 파일을 Windows로 옮겨 Win32DiskImager를 이용해서 SD메모리에 write 하거나,
라즈베리파이에 SD메모리를 꽂고 아래 명령어로 write를 한 후,
해당 SD메모리로 라즈베리파이 구동에 성공하면 OK
// 라즈베리파이에서 SD메모리에 OS img write
// dcfldd 설치
apt-get install dcfldd -y
// SD메모리는 /dev/sda 라고 가정
dcfldd if=/mnt/ext/my_os.img of=/dev/sda
65536 blocks (2048Mb) written.
65536+0 records in
65536+0 records out
.