25 Jan

Creating an image file from a local directory on Linux

Sometimes I wish to create disk image files using a directory on my local computer. It’s an easy task with Linux, which can be accomplished with only a couple of commands.

The main scenario for when I wish to create a disk image is when creating a .img file that can be written straight to a SD card (for example Arch Linux for the Raspberry Pi comes as a tar.gz of the root filesystem rather than an image file) or used with QEMU as the hard disk.

The following steps (that I use for creating an Arch Linux SD card image file) will take you through creating an image file and writing the files you wish to it.

Create an 8GB image file:

dd if=/dev/zero of=newfile.img bs=1M count=8192

Partition the image file:

fdisk ./newfile.img

I usually create 2 partitions, a FAT partition of about 100M for the boot files and the rest of the image a ext4 for the root filesystem.

Mount the image file using the loopback device. (I used the -f switch to find the next available loop device rather than explicitly specifying one)

sudo losetup -Pf ./newfile.img

The image file should now be visible as a block device on /dev/loopX where X is 0 if you don’t have any other loop devices

Running the following should give similiar output as below:

[[email protected] blog]$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0         7:0    0     1G  0 loop 
├─loop0p1   259:6    0   100M  0 loop 
└─loop0p2   259:7    0   933M  0 loop

Format the partitions

sudo mkfs.vfat /dev/loop0p1
sudo mkfs.ext4 /dev/loop0p2

Mount the partitions:

mkdir p1
mkdir p2
sudo mount /dev/loop0p1 p1
sudo mount /dev/loop0p2 p2

You can now copy anything across my moving your files into directories p1 or p2.

For example, as I usually create SD card images from the Arch Linux ARM root filesystem tar.gz. I do the following:

sudo bsdtar -xpf ArchLinuxARM-rpi-latest.tar.gz -C p2
sync
sudo mv p2/boot/* p1

Clean up:
At this point we just need to clean up and unmount the image file and detach the loop back device:

sudo umount p1 p2
sudo losetup -d /dev/loop0

You should now have a nicely prepared image file. You can also mount existing image files using losetup, as we did above.