SD Card 포맷 및 디스크 이미지 사용하기

7 분 소요

SBC, PC 등의 머신에서 SD Card 사용에 필요한 사항을 정리했다.

2018-08-30: 전체 내용 편집 2017-10-30: swap 추가, timezone 수정


SD Card 와 디스크 이미지 사용하기

SD Card는 Secure Digital의 약자로 Flash memory(비휘발성) 카드 포맷이다.

자세한 내용은 Wikipedia: SD Card 를 확인하자.

SD Card format

  1. Windows
  • Disk Utility를 이용한다.
  • SD Association의 SD Formatter 를 이용한다.
  1. macOS
  • Diskutility 앱을 이용한다.
  • SD Association의 SD Formatter 를 이용한다.
  1. Linux
  • fdisk, parted 명령으로 포맷할 수 있다.
  • dd 명령으로

macOS

macOS는 Disk Utility 프로그램을 명령줄에서 diskutil 명령으로 디스크에 대한 파티션, 포맷 및 점검을 할 수 있다. GUI 윈도우를 제공하지만 명령줄에서 diskutil 명령으로 파티션, 마운트 및 포맷을 할 수 있다.

명령줄에서 diskutil 명령으로 목록과 파티션 마운트를 해제하고

$ diskutil list

$ diskutil unmountDisk /dev/diskX

역시 dd 명령을 이용해 /dev/zero, /dev/urandom 을 디스크 전체에 써서 지울 수 있다.

$ sudo dd if=/dev/urandom of=/dev/diskX bs=1000000

디스크 파티션은 partitionDisk 를 사용해서 파티션할 수 있다.

$ sudo diskutil partitionDisk <Disk> GPT| FAT|exFAT|JHFS+ NAME SIZE
  • SIZE: 0b 전체.

zeros

$ diskutil reformat /dev/rdisk3

Linux

Ubuntu 등은 SD Card 슬롯에 삽입된 장치는 /dev/mmcblkX 같이 장치 이름을 붙인다. USB Stick 으로 SD Card 혹은 Micro SD Card를 사용하면 /dev/sdX 디스크 이름을 사용한다.

lsblk 명령은 디바이스 장치가 마운트 된 곳을 출력해 준다.

$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0 119.2G  0 disk
├─sda1        8:1    0  84.5G  0 part
└─sda6        8:6    0  28.9G  0 part /
mmcblk0     179:0    0   7.5G  0 disk
├─mmcblk0p2 179:2    0   6.8G  0 part /media/qkboo/ROOT
├─mmcblk0p3 179:3    0 486.1M  0 part
└─mmcblk0p1 179:1    0   200M  0 part /media/qkboo/EFI

파티션 및 포맷을 위해 마운트된 파티션을 언마운트 한다.

$ sudo umount /dev/mmcblk0p2
$ sudo umount /dev/mmcblk0p1

parted 유틸리티로 파티션을 삭제, 생성할 수 있다. 다음은 명령라인에서 옵션을 주어 사용하는 방법이다

$ sudo parted /dev/mmcblk0 rm 1
$ sudo parted /dev/mmcblk0 rm 2
$ sudo parted /dev/sdc mkpart primary ext3 4MiB 100%

결과로 mmcblk0 디스크 드라이브에 mmcblk0p1 파티션이 생성된다.

다음은 위와 같은 내용으로 fat32 파티션을 parted 를 Shell로 사용하는 예이다.

sudo parted /dev/mmcblk0
(parted) mklabel msdos
(parted) mkpart primary fat32 1MiB 100%
(parted) set 1 boot on
(parted) quit

마지막으로 파티션을 파일시스템으로 포맷해 준다.

$ sudo mkfs -V -t vfat /dev/mmcblk0p1

역시 dd 명령을 이용해 /dev/zero, /dev/urandom 을 디스크 전체에 써서 지울 수 있다.

$ sudo dd if=/dev/zero of=/dev/diskX bs=4M

Disk clone

Linux, macOS 에서 파티션 도구, dd 를 사용해서 디스크 전체, 혹은 파티션을 이미지로 추출해 생성하는 과정을 정리했다.

dd 이용하기

dd 로 디스크의 전체를 이미지 파일로 생성할 수 있다. 다만 디스크 전체 섹터를 추출하므로 디스크 용량과 같은 크기를 가진 이미지 파일이 생성된다.

dd bs=4M if=/dev/sdX of=image.gz conv=fsync

Ubuntu gparted

우분투 Live CD에서 gparted는 가능한 사용하지 않는 공간은 빼고 최소 크기로 줄여 줄 수 있다.

압축 이용하기

전체 디스크 크기의 이미지 파일이 너무 크면, 압축유틸리티를 이용해 저장할 수 있다.

dd bs=4M count=<size_in_MBs> if=/dev/sdX | gzip -c --fast| dd of=image.gz
dd bs=4M count=<size_in_MBs> if=/dev/sdX | xz -c --fast| dd of=image.xz

반대로 압축한 이미지 파일을 디스크로 복원하기 위해서 unzip, gunzip, xz -d 압축을 해제한 결과를 파이프로 dd로 전달한다.

dd if=/path/to/image.gz | gunzip -c | dd bs=1M of=/dev/sdY
dd if=/path/to/image.xz | xzcat | dd bs=1M of=/dev/sdY

macOS의 Disk Utility 이용

GUI인 Disk Utility에서 SD Card 디스크를 선택하고 macOS의 .dmg 이미지 파일로 저장할 수 있고, 저장시 압축 선택이 가능하다.


Disk Image를 SD Card에 쓰기

각 OS에서 dd 같은 Disk clone 도구를 사용해서 디스크 이미지를 SD Card에 쓸 수 있다.

Etcher

모든 OS 플랫폼을 지원하는 Etcher 사용을 권장한다. Etcher 을 다운받아 이미지 파일 선택해 대상 SD Card 에 GUI로 쓸 수 있다.

dd를 사용한다면 이러지는 macOS, Linux 섹션을 참조한다.

dd로 이미지 쓰기

디스크 내용을 dd 명령으로 디스크 이미지 형태로 저장할 수 있다.

$ sudo dd if=opensuse_jeos-20171030.img of=/dev/mmcblk0 bs=4m

압축 이미지로 제공하는 이미지 파일은 zcat, xzcat, gzcat 같은 표출 출력 유틸리티를 사용해, dd 명령에 파이프로 처리할 수 있다.

$ xzcat openSUSE-Leap42.2-ARM-JeOS-raspberrypi3.aarch64.raw.xz | sudo dd of=/dev/rdisk1 bs=4m; sync

이제 이미지 SD Card를 보드에 넣고 부팅한 후 시스템 설정을 시작하면 된다.

시스템 구성을 하고, 여러 설정을 한 후 백업, 복사 등을 위해, 설정한 OS 를 디스크 이미지로 복제하는 경우가 많아 이때는 dd 명령을 사용할 수 있다.


이미지 파일 다루기

백업한 디스크 이미지 파티션을 확인하고 폴더에 마운트해서 내용을 확인할 할 수 있다.

이미지 파일의 파티션 정보를 fdisk, parted 명령으로 확인할 수 있다.

fdisk 이용

$ fdisk -lu opensuse-e20.img
Disk opensuse-e20.img: 14.9 GiB, 16022241280 bytes, 31293440 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: 0xe0e3966b

Device            Boot    Start      End  Sectors   Size Id Type
opensuse-e20.img1          2048   411651   409604   200M  c W95 FAT32 (LBA)
opensuse-e20.img2        413696 30282525 29868830  14.2G 83 Linux
opensuse-e20.img3      30283776 31278554   994779 485.7M 82 Linux swap / Solaris

parted 이용

$ parted opensuse-42.3-homepi_16GB-firewalld.img
GNU Parted 3.2
Using opensuse-42.3-homepi_16GB-firewalld.img
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p
Model:  (file)
Disk opensuse-42.3-homepi_16GB-firewalld.img: 16.0GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start   End     Size    Type     File system     Flags
 1      1049kB  211MB   210MB   primary  fat16           lba
 2      212MB   15.5GB  15.3GB  primary  ext4
 3      15.5GB  16.0GB  509MB   primary  linux-swap(v1)

Byte 단위로 보려면

(parted) unit
Unit?  [compact]? B
(parted) p
Number  Start         End           Size          Type     File system     Flags
 1      1048576B      210765823B    209717248B    primary  fat16           lba
 2      211812352B    15504653311B  15292840960B  primary  ext4
 3      15505293312B  16014620159B  509326848B    primary  linux-swap(v1)

이미지 마운트

디스크 이미지는 리눅스에서 mount 명령으로 마운트 할 수 있다. mount 명령으로 실제 파티션이 시작하는 위치를 offset으로 지정해서 마운트 한다.

앞서 사용한 opensuse-42.3-homepi_16GB.img 이미지의 파티션 정보가 다음 같다고 하자.

Number  Start         End           Size          Type     File system     Flags
 1      1048576B      210765823B    209717248B    primary  fat16           lba
 2      211812352B    15504653311B  15292840960B  primary  ext4
 3      15505293312B  16014620159B  509326848B    primary  linux-swap(v1)

첫번째 파티션 시작 위치 1048576B 를 오프셋으로 삼아서 root 권한으로 mount 명령을 사용한다.

섹터 정보를 Byte 단위로 변경하려면, 파티션 정보에서 1 sector 크기가 512 를 확인하고, 이미피 파일의 파티션 시작 섹터를 곱해서 offset 범위를 계산한다.

Sector size * Start = (in the case) 512 * 8192 = 4194304 (Byte)

이제 마운트 명령 mount -o loop,ro,offset 옵션을 주고, boot와 ROOT 파티션을 마운트 해보자,

Now we have the offsets and we can use those to mount the filesystems using the loopback device:

$ sudo mount -o loop,ro,offset=1048576 opensuse-42.3-homepi_16GB.img ~/mnt/boot/
$ sudo mount -o loop,ro,offset=211812352 opensuse-42.3-homepi_16GB.img ~/mnt/ROOT/

마운트가 성공하면 df 명령 혹은 mount 명령으로 마운트한 위치를 확인할 수 있다;

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            1.5G     0  1.5G   0% /dev
tmpfs           300M  5.1M  295M   2% /run
/dev/sda6        29G  7.3G   20G  28% /
tmpfs           1.5G  188K  1.5G   1% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           1.5G     0  1.5G   0% /sys/fs/cgroup
/dev/loop0      200M  4.4M  196M   3% /home/qkboo/mnt/boot
/dev/loop1      200M  4.4M  196M   3% /home/qkboo/mnt/ROOT

/dev/loop0 파일 시스템이 지정한 마운트 위치에 마운트했다는 것을 알 수 있다.

또한 -t [fs_type] 옵션으로 파티션의 파일 시스템을 명시할 수 있다.

이미지에서 한 파티션만 마운트 하기

이미지에 있는 하나의 파티션만 마운트 할 수 있다. 1

앞의 이미지 파일 정보를 /dev/loop0 에 offset을 주고

sudo losetup -o 4194304 /dev/loop0 sda.img

Now the partition resides on /dev/loop0. You can fsck it, mount it etc

sudo fsck -fv /dev/loop0
sudo mount /dev/loop0 /mnt

Unmount

sudo umount /mnt
sudo losetup -d /dev/loop0

Truncate

질문, 원래 2GB 데비안 이미지를 16GB SD Card에 썼다. 나머지 14GB 공간을 별도로 파티션 나눌 수 있나?

먼저 이미지 파티션 정보를 얻는다.

$ fdisk -lu image.img
Disk image.img: 4096 MB, 4096000000 bytes, 8000000 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
Disk identifier: 0x000a1bc7

      Device Boot      Start         End      Blocks   Id  System
image.img1              2048     5872026     5869978    b  W95 FAT32

이미지 파티션의 끝 부분이 5872026 으로 5872026 * 512 = 2,8Gb 이고, 나머지는 안쓰는 공간이다.

truncate 도구로 현재 파티션에서 빈공간을 잘라낸다. 다만 블럭 수가 0에서 시작하므로 섹터 수에 1을 더해준다.2

$ truncate --size=$[(5872026+1)*512] image.img

Repair & Corruption

프롬프트에서 다음 명령으로 해당 파티션을 점검한다.

# fsck -fy /dev/mmcblk0p2
# reboo

혹은 다음 부팅시 처리할 수 있도록 한다.

# touch /forcefsck
# reboot

Check Bad sector

터미널에서 SD Card 삽입/추출 및 점검시 섹터 에러를 확인하기 위해 dmesg 로 감시할 수 있다. 다음 명령은 dmesg 가 발생하면, 내용 중 마지막 15줄을 터미널로 출력해 준다.

$ watch "dmesg | tail -15"

hdparam

hdparam

$ sudo hdparm -t /dev/mmcblk0

/dev/mmcblk0:
 Timing buffered disk reads:  58 MB in  3.09 seconds =  18.80 MB/sec

badblocks

$ sudo badblocks -n -v /dev/mmcblk0

Recovering

GNU ddrescue is a data recovery tool. It copies data from one file or block device (hard disc, cdrom, etc) to another, trying to rescue the good parts first in case of read errors.

https://www.gnu.org/software/ddrescue/

참조

댓글남기기