How to create a formatted partition image file from scratch?

If on Linux, when loading the loop module, make sure you pass a max_part option to the module so that the loop devices are partitionable.

Check the current value:

cat /sys/module/loop/parameters/max_part

If it's 0:

modprobe -r loop # unload the module
modprobe loop max_part=31

To make this setting persistent, add the following line to /etc/modprobe.conf or to a file in /etc/modprobe.d if that directory exists on your system:

options loop max_part=31

If modprobe -r loop fails because “Module loop is builtin”, you'll need to add loop.max_part=31 to your kernel command line and reboot. If your bootloader is Grub2, add to it to the value of GRUB_CMDLINE_LINUX in etc/default/grub.

Now, you can create a partitionable loop device:

truncate -s64M file # no need to fill it with zeros, just make it sparse
fdisk file # create partitions
losetup /dev/loop0 file
mkfs.vfat /dev/loop0p1 # for the first partition.
mount /dev/loop0p1 /mnt/

(note that you need a relatively recent version of Linux).


losetup /dev/loop0 file -o 1048576 --sizelimit limit

Offset specified should be in bytes (1048576 = 2048 sectors * 512 bytes per sector).

mount -o loop,offset=1048576,sizelimit=limit

For more information see losetup and mount.


The following procedures allow you to mount the partitions of the image to modify them.

losetup 2.21 -P option

losetup -P -f --show my.img

Creates one /dev/loopXpY per partition.

Advantage: executable pre-installed in many distros (util-linux package).

Disadvantage: quite recent option, not present in Ubuntu 14.04.

losetup -P automation

Usage:

$ los my.img
/dev/loop0
/mnt/loop0p1
/mnt/loop0p2

$ ls /mnt/loop0p1
/whatever
/files
/youhave
/there

$ sudo losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE                                                                                      DIO
/dev/loop1         0      0         0  0 /full/path/to/my.img

$ # Cleanup.
$ losd 0
$ ls /mnt/loop0p1
$ ls /dev | grep loop0
loop0

Source:

los() (
  img="$1"
  dev="$(sudo losetup --show -f -P "$img")"
  echo "$dev"
  for part in "$dev"?*; do
    if [ "$part" = "${dev}p*" ]; then
      part="${dev}"
    fi
    dst="/mnt/$(basename "$part")"
    echo "$dst"
    sudo mkdir -p "$dst"
    sudo mount "$part" "$dst"
  done
)
losd() (
  dev="/dev/loop$1"
  for part in "$dev"?*; do
    if [ "$part" = "${dev}p*" ]; then
      part="${dev}"
    fi
    dst="/mnt/$(basename "$part")"
    sudo umount "$dst"
  done
  sudo losetup -d "$dev"
)

kpartx

sudo apt-get install kpartx
losetup -fs my.raw
sudo kpartx -a my.img
ls /dev/mapper

Output:

/dev/mapper/loop0
/dev/mapper/loop0p1

where loop0p1 is the first partition, so we can do:

mkdir -p d
sudo mount /dev/mapper/loop0p1 d

Advantage of this method: works on Ubuntu 14.04 without rebooting.