Create a generic sdcard.img file

Create an initial sdcard.img file:

To create an initial 2GB sdcard.img file, use fallocate, you can use the -l operator for lenghth. In this case use 2G for a 2GB sdcard.img:

fallocate -l 2G sdcard.img

Double check sdcard.img file with fdisk:

sudo fdisk -l ./sdcard.img
Disk ./sdcard.img: 2 GiB, 2147483648 bytes, 4194304 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

At this point, if need to dd data directly to the sdcard.img, you can otherwise, use the disk tools to create the partition table:

For example, to create a ext file system with a 1MB offset:

sudo sfdisk ./sdcard.img <<-__EOF__
1M,,L,*
__EOF__

Example, output:

sudo fdisk -l ./sdcard.img
Disk ./sdcard.img: 2 GiB, 2147483648 bytes, 4194304 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: 0x2bb23543

Device        Boot Start     End Sectors Size Id Type
./sdcard.img1 *     2048 4194303 4192256   2G 83 Linux

However for any further operation we need to use losetup/kpartx:

Grab an open loop device with losetup

If you are running ubuntu or anything with snap running, /dev/loop0 will defintelly not be open:

Typical non-ubuntu or without snap installed:

sudo losetup -f
/dev/loop0

Typical ubuntu or distro with snap installed:

sudo losetup -f
/dev/loop5

losetup: attache sdcard.img file with a loop device:

sudo losetup /dev/loop0 sdcard.img

kpartx add partition devmappings from loop device:

sudo kpartx -av /dev/loop0

Example, with our above partition, kpartx will output:

add map loop0p1 (254:0): 0 4192256 linear 7:0 2048

loop0 should now show up under /dev/mapper/loop*, this where we can actually mount and work with the partitions on sdcard.img file:

ls /dev/mapper/loop*
/dev/mapper/loop0p1

To format, /dev/loop0p1, run;

voodoo@hestia:~/testing$ sudo mkfs.ext4 -L rootfs /dev/mapper/loop0p1 
mke2fs 1.46.2 (28-Feb-2021)
Discarding device blocks: done                            
Creating filesystem with 524032 4k blocks and 131072 inodes
Filesystem UUID: 8b0688fe-d2c3-4cb2-98d7-04d42fe529a0
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: do

To mount, /dev/loop0p1, run;

sudo mount /dev/mapper/loop0p1 /media/rootfs/

You will no see it mounted:

voodoo@hestia:~/testing$ mount | grep rootfs
/dev/mapper/loop0p1 on /media/rootfs type ext4 (rw,relatime)

Copy your data as is at this point…

To umount and disconnect the sdcard.img, run everything backwards:

First unmount devmappings

sudo umount /dev/mapper/loop0p1

kpartx: delete the partition devmappings

sudo kpartx -d /dev/loop0

losetup: detach loop device:

sudo losetup -d /dev/loop0

#Complete:

Use any tool, dd/etcher.io to flash the sdcard.img file to your microSD card…