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







.

Posted by bloodguy
,