How to create a formatted partition image file from scratch?

I need to create filesystem with just one partition from nothing (/dev/zero).
I tried this sequence of commands:

dd if=/dev/zero of=mountedImage.img bs=512 count=131072
fdisk mountedImage.img
    n
    p 
    2048
    131072

Basically, I need to create 64MB image file filled with zeroes. Then I use fdisk to add a new partition for new filesystem (which should finally be FAT32), starting at sector 2048 and using all remaining sectors.

losetup /dev/loop1 mountedImage.img
mkfs -t vfat /dev/loop1

But here I’m hitting problems. If I set up a loop device and format it using mkfs -t vfat, partition table is overwritten and filesystem (FAT32) is placed to disk. I don’t need whole disk formatted with FAT32, I just need my primary partition to be so.

Does anybody know how can I format only one partition of raw disk image, not whole image?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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).

Method 2

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.

Method 3

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.

Method 4

A simple example using ext4 file system and GPT partitioned image.

truncate -s 100MiB mountedImage.img

Create a GPT Table

parted mountedImage.img mklabel gpt

Create Partition P1

parted mountedImage.img mkpart primary ext4 2MiB 30MiB

Create Partition P2

parted mountedImage.img mkpart primary ext4 30MiB 60MiB

Create Partition P3

parted mountedImage.img mkpart primary ext4 60MiB 99MiB

Say you are using the loop device /dev/loop1 (it’s always better to use sudo losetup -f to get a free loop device):

losetup /dev/loop1 mountedImage.img -> should enumerate the partitions to create devices like /dev/loop1px for each partition x represents the partition number.
[use] mkfs.ext4 /dev/loop1px -> to be done on the partition number x
[and not] mkfs.ext4 /dev/loop1 -> will only delete the partition table
Note: The partitions from the image are visible in loop device only if the module is configured for multi partition.

Please refer to the link to my blog, Creating a GPT Partitioned image from Scratch in Linux, for creating partitioned image from scratch using GPT.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x