Para crear una imagen con múltiples particiones, una solución que no requiere herramientas sofisticadas o acceso de raíz es crear primero los sistemas de archivos y luego concatenarlos.
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
Luego ejecuta parted
o fdisk
para crear las particiones.
Este enfoque tiene la desventaja de que la imagen resultante no será escasa.
Para ampliar la respuesta proporcionada por @gilles, aquí hay una forma de crear una imagen de disco que contenga un sistema de archivos formateado creando primero un sistema de archivos (de tipo ESP en este ejemplo) dentro de un archivo y luego ensamblando eso en una imagen de disco válida; no se requieren dispositivos raíz, de montaje o de bucle:
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
El enfoque anterior tiene el beneficio adicional de ser escaso cuando se usa en un sistema de archivos que admite archivos escasos; el archivo "262 MB" resultante ocupa menos de 200 kB en el disco:
du -h --apparent diskimg; du -h diskimg
262M diskimg
196K diskimg
Para los sistemas de archivos FAT, las utilidades Mtools admiten la operación en un desplazamiento en un archivo (¿ext2/4/etc probablemente también lo haga?). Esto lo hace más fácil, solo crea la imagen particionada y trabaja en eso directamente:
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"
Aquí hay un diagrama del archivo de imagen resultante:
Desea formatear una partición en un archivo de imagen de disco, en lugar de todo el archivo de imagen. En ese caso, debe usar losetup
para decirle a Linux que use el archivo de imagen como un dispositivo de bucle invertido.
NOTA:losetup
requiere privilegios de root, por lo que debe ejecutarse como root o con sudo. El /dev/loop*
los dispositivos que usa/crea también requieren privilegios de root para acceder y usar.
por ejemplo (como 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)
y, finalmente, separe la imagen del dispositivo de bucle invertido:
# losetup -d /dev/loop0
Ver man losetup
para más detalles.