Pour créer une image avec plusieurs partitions, une solution qui ne nécessite aucun outil sophistiqué ni accès root consiste à créer d'abord les systèmes de fichiers, puis à les concaténer.
truncate -s $IMAGE_ROOTFS_ALIGNMENT disk
truncate -s $BOOT_SPACE_ALIGNED part1
mkfs.fat part1
cat part1 >>disk
truncate -s $ROOTFS_SIZE part2
mkfs.ext4 part2
cat part2 >>disk
Ensuite, exécutez parted
ou fdisk
pour créer les partitions.
Cette approche a l'inconvénient que l'image résultante ne sera pas clairsemée.
Pour développer la réponse fournie par @gilles, voici une façon de créer une image disque contenant un système de fichiers formaté en créant d'abord un système de fichiers (de type ESP dans cet exemple) dans un fichier, puis en l'assemblant à une image disque valide; aucun périphérique racine, montage ou boucle requis :
diskimg=diskimg # filename of resulting disk image
size=$((260*(1<<20))) # desired size in bytes, 260MB in this case
alignment=1048576 # align to next MB (https://www.thomas-krenn.com/en/wiki/Partition_Alignment)
size=$(( (size + alignment - 1)/alignment * alignment )) # ceil(size, 1MB)
# mkfs.fat requires size as an (undefined) block-count; seem to be units of 1k
mkfs.fat -C -F32 -n "volname" "${diskimg}".fat $((size >> 10))
# insert the filesystem to a new file at offset 1MB
dd if="${diskimg}".fat of="${diskimg}" conv=sparse obs=512 seek=$((alignment/512))
# extend the file by 1MB
truncate -s "+${alignment}" "${diskimg}"
# apply partitioning
parted --align optimal "${diskimg}" mklabel gpt mkpart ESP "${offset}B" '100%' set 1 boot on
L'approche ci-dessus a l'avantage secondaire d'être clairsemée lorsqu'elle est utilisée sur un système de fichiers qui prend en charge les fichiers clairsemés; le fichier "262 Mo" résultant occupe moins de 200 Ko sur le disque :
du -h --apparent diskimg; du -h diskimg
262M diskimg
196K diskimg
Pour les systèmes de fichiers FAT, les utilitaires Mtools prennent en charge le fonctionnement sur un décalage dans un fichier (ext2/4/etc le fait probablement aussi ?). Cela facilite les choses, il vous suffit de créer l'image partitionnée et de travailler dessus directement :
diskimg=diskimg
size=$((260*(1<<20))) # desired size in bytes, 260MB in this case
# align to next MB (https://www.thomas-krenn.com/en/wiki/Partition_Alignment)
alignment=1048576
size=$(( (size + alignment - 1)/alignment * alignment ))
# image size is gpt + filesystem size + gpt backup
truncate -s $((size + 2*alignment)) "${diskimg}"
parted --machine --script --align optimal "${diskimg}" mklabel gpt mkpart ESP "${alignment}B" '100%' set 1 boot on
mformat -i "${diskimg}"@@"${alignment}" -t $((size>>20)) -h 64 -s 32 -v "volname"
Voici un schéma du fichier image résultant :
Vous souhaitez formater une partition dans un fichier image disque, plutôt que le fichier image entier. Dans ce cas, vous devez utiliser losetup
pour indiquer à Linux d'utiliser le fichier image comme périphérique de bouclage.
REMARQUE :losetup
nécessite des privilèges root, il doit donc être exécuté en tant que root ou avec sudo. Le /dev/loop*
les appareils qu'il utilise/crée nécessitent également des privilèges root pour y accéder et les utiliser.
par exemple (en tant que root)
# losetup /dev/loop0 ./sdcard.img
# fdisk -l /dev/loop0
Disk /dev/loop0: 1 MiB, 1048576 bytes, 2048 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: 0x54c246ab
Device Boot Start End Sectors Size Id Type
/dev/loop0p1 1 1023 1023 511.5K c W95 FAT32 (LBA)
/dev/loop0p2 1024 2047 1024 512K 83 Linux
# file -s /dev/loop0p1
/dev/loop0p1: data
# mkfs.vfat /dev/loop0p1
mkfs.fat 3.0.28 (2015-05-16)
Loop device does not match a floppy size, using default hd params
# file -s /dev/loop0p1
/dev/loop0p1: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", sectors/cluster 4, root entries 512, sectors 1023 (volumes <=32 MB) , Media descriptor 0xf8, sectors/FAT 1, sectors/track 32, heads 64, serial number 0xfa9e3726, unlabeled, FAT (12 bit)
et, enfin, détachez l'image du périphérique de bouclage :
# losetup -d /dev/loop0
Voir man losetup
pour plus de détails.