Como construir uma imagem de cartão SD, sem um cartão SD?

2

Temos um processo de script que cria uma instalação incorporada de Debian Jesse em um cartão SD. As partes relevantes do script são assim:

export DISK=/dev/sdb
umount ${DISK}1   # make sure no partitions mounted at the moment
umount ${DISK}2   # ditto
dd if=/dev/zero of=${DISK} bs=1M count=16   # zero partition table zone, overkill
sfdisk --in-order --Linux --unit M ${DISK} <<-__EOF__    # make partitions
    1,48,0xE,*
    ,,,-
__EOF__

mkfs.vfat -F 16 ${DISK}1 -n boot    # install file systems
mkfs.ext4 ${DISK}2 -L rootfs

Depois disso, o auto mounter parece entrar em ação e receber o cartão SD remontado, para que possamos fazer coisas como:

cp -v ${DIR}/u-boot/spl/u-boot-spl.bin /media/$username/boot/BOOT.BIN
cp -v ${DIR}/u-boot/u-boot.img /media/$username/boot/
cp -v ${DIR}/u-boot/uEnv.txt /media/$username/boot/
rsync -axHAX --progress ${DIR}/jessieRoot/ /media/$username/rootfs/

Depois que um de nós fizer isso, podemos usar dd para copiar o conteúdo do cartão e compartilhá-lo, fazendo mais cartões sd usando dd .

O PROBLEMA com isto é duplo: 1) É muito específico para o Ubuntu / máquina agora (assume que o cartão está em sdb , etc 2) Ele precisa de um cartão real, portanto não se presta a uma máquina de construção. / p>

Existe uma maneira de fazer o acima sem um cartão?

Eu tentei usar dd para criar um arquivo 8G e depois executei sfdisk (tudo é um arquivo, certo?) e essa parte funcionou. Mas não está claro como eu executei as partes mkfs para funcionar, elas parecem querer trabalhar em arquivos de dispositivo de bloco, não em sub-regiões de um único arquivo que tenha uma tabela de partição embutida nele. E então eu tenho o problema de montá-lo. Eu suponho que eu use algum encantamento de mount -o loop , mas, novamente, não sei como fazer isso na sub-região do arquivo de imagem virtual, eu sempre apenas para baixo com arquivos .iso.

(Sinta-se livre para ser pedante, eu não sou um especialista (obviamente) com esse tipo de coisa. Eu recebo parte disso, e outras partes parecem um pouco mágicas ...)

    
por Travis Griggs 23.10.2014 / 20:03

2 respostas

4

Acho que esta página tem tudo o que você precisa.

  • em vez de sdb, use o dispositivo de loopback

  • em vez do cartão real, use o sistema de arquivos virtual

  • você está no caminho certo fazendo uso do dd para criar um arquivo para o sistema de arquivos virtual.

  • você está no caminho certo usando o dispositivo de loopback. O truque é montar o dispositivo de loopback nos deslocamentos onde as partições estão.

Este é o artigo.

A virtual filesystem is filesystem that exists in a file, which in turn exists on a physical disk. There's a lot of great things you can do with virtual file systems; the reason I was messing with them was to configure a virtual machine on a linux host. Other uses include encrypting filesystems without encrypting entire disks; Mac OS X's File Vault encrypts users home directories this way. Maybe you went ahead and made yourself one giant partition and then realized for one reason or another that you want multiple partitions! Virtual filesystems can help (to some extent) with that as well.

So how do you make a virtual file system? Easy. The first thing you need to do is make a file for the filesystem to live in. This is where 'dd' starts to come in. Consider, for example, the following command:

dd if=/dev/zero of=~/myFileSystem.img bs=1024 count=1048576

This command will read 1,048,576 blocks from /dev/zero and write them to ~/myFileSystem.img; each block is 1024 bytes, resulting in a 1 gigabyte file containing all zeroes. The actual values that you use for the blocksize (bs) and count aren't really important, the key is to get your math right: bs * count = imageSize.

So now you have your file; great. It's time to make a file system! this part is even easier... we'll create an EXT2 filesystem, using the following command:

mke2fs myFileSystem.img

You may notice a warning prompt, saying that myFileSystem.img is not a block device, would you like to proceed? We'll get to that in just a second, for now, go ahead and say yes. Everything should go smooth, it'll look just as if you'd created a filesystem on an actual disk drive. You now have a virtual file system! The only thing left to do is mount your filesystem so you can access it...

mkdir /mnt/virtual

mount -o loop ~/myFileSystem.img /mnt/virtual

Now any file you put into /mnt/virtual is actually being put directly into myFileSystem.img! Wasn't that easy?

Fantastic. Now that you know how to make a virtual filesytsem, why not make a while virtual disk image? What's the difference you ask? A disk image is going to have a partition table that defines some number of partitions, and each partition contains its own filesystem; so a virtual filesystem is essentially a "virtual partition" of a virtual disk image; the virtual disk image contains multiple virtual filesystems, and a virtual partition table that describes where the bounds of each partition are.

Creating a virtual disk image starts out the same; the first thing you need is a big empty file, just you created above. This time, though, instead of making a file system, we'll want to partition the file using fdisk. To make things a little nicer though, we're going to throw loopback devices into the mix. You should make sure you have loopback device support enabled in your kernel (most distributions do by default; but if you're a kernel compiling linux junky, you might wanna check ). So we'll create a big file, and attach it to a loopback device, as follows:

dd if=/dev/zero of=~/myDisk.img bs=1024 count=1048576

losetup /dev/loop0 ~/myDisk.img

By attaching the disk image to the loopback device, we can use /dev/loop0 the same way we would use ~/myDisk.img; the main difference is that /dev/loop0 is a what's known as a "block device". You'd have to ask someone with more experience than I've got what precisely this gets you, but what I do know is that the filesystem utilities work better with block devices than they do with the flat files. Plus, it's fun.

So good, we've got a big empty file attached to a loopback device (/dev/loop0)... now it's time to create partitions in the disk image. To do this, we'll run fdisk on our loopback device:

fdisk /dev/loop0

Lets create three partitions... if you're following this, you should already be familiar with fdisk, so go ahead and create the following: Device Boot Start End Blocks Id System

/dev/loop0p1 1 17 136521 83 Linux

/dev/loop0p2 18 80 506047+ 82 Linux swap

/dev/loop0p3 81 130 401625 83 Linux

Once you've made your partitions, write your changes and quit fdisk. What we'll need to do next is create filesystems on each partition. Remember how easy that was back with Virtual Filesystems? Not quite so much anymore...

Not to panic though... the trouble is that "mkfs" can't "reach into" our virtual disk image and make a filesystem just on individual partition. Infact, if you try, you'll probably wind up wiping our your virtual disk image and having to rerun fdisk . So what to do... what to do?? Loopback devices to the rescue. What we'll do is attach a loopback device to the myDisk.img file at the specific offsets where each partition begins.

It's helpful then to look at the partitions in terms of blocks. Execute the following command:

fdisk -ul /dev/loop0

should look (hopefully exactly) like this:

Disk /dev/loop0: 1073 MB, 1073741824 bytes

255 heads, 63 sectors/track, 130 cylinders, total 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

  Device Boot      Start         End      Blocks   Id  System

/dev/loop0p1 63 273104 136521 83 Linux

/dev/loop0p2 273105 1285199 506047+ 82 Linux swap

/dev/loop0p3 1285200 2088449 401625 83 Linux

These numbers are important for the math... we'll use the losetup command like we did before, only this time we'll reach in specifically to the start of each of the three partitions. losetup takes offsets as the number of bytes to skip at the beginning of the file. The output from fdisk -ul /dev/loop0 shows us that the first partition starts at block 63, and that each block is 512 bytes. So partition 1 starts at byte 32,256

losetup -o 32256 /dev/loop1 /dev/loop0

That command reaches 32,256 bytes into /dev/loop0 and mounts it at /dev/loop1. Remember that since /dev/loop0 is attached the myDisk.img file, this is the same as reaching 32,256 bytes into that file... follow? Ok, good. Same logic for partitions 2 and 3:

losetup -o 139829760 /dev/loop2 /dev/loop0

losetup -o 658022400 /dev/loop3 /dev/loop0

So now we have four loopback devices set up; /dev/loop0 is attached to the myDisk.img file. /dev/loop1 is the first partition of the virtual disk represented by /dev/loop0; /dev/loop2 is the 2_nd, and /dev/loop3 is the 3_rd.

Now it's finally time to make those file systems! This is now just as easy as making a regular filesystem, since that's all we're doing. Remember, mkfs doesn't know the device isn't a physical device! We'll make three kinds of file systems, an ext2 file system for partition 1, a swap filesystem for partition 2, and an XFS fileystem for partition 3:

mkfs /dev/loop1

mkswap /dev/loop2

mkfs.xfs /dev/loop3

Since loop1, loop2, and loop3 are tied directly to loop0, and loop0 is ~/myDisk.img, everything that we just did to loop1, loop2, and loop3 affected myDisk.img directly! We can now mount /dev/loop3, for instance, on /mnt/virtual as an XFS file system, and use it as a regular file system!

So I hope you found that helpful... you can do some pretty neat things with virtual file systems and virtual disk images; and loopback devices make a world of difference for making things go smooth.

    
por 24.10.2014 / 06:24
0

A resposta aceita para este problema é factualmente correta, mas - enquanto escrevo isso cinco anos depois - há uma abordagem mais simples que deve funcionar para a maioria das pessoas. Fazer malabarismos manuais com compensações e criar múltiplos dispositivos de loopback é, em geral, desnecessário. A 'arma secreta' para criar imagens de sistemas de arquivos virtuais na maioria das distribuições Linux atualmente é a opção -P para o comando losetup :

-P, --partscan
              Force the kernel to scan the partition table on a newly created loop device.

Você pode basicamente pensar em -P como a opção "fingir que este arquivo é um disco ". Um exemplo deve deixar isso claro. Este comando cria um arquivo de imagem de 4GB preenchido com zeros:

$ dd if=/dev/zero of=./sdcard.img bs=1024 count=4194304
4194304+0 records in
4194304+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 39.7914 s, 108 MB/s

O seguinte comando mapeia o primeiro dispositivo de loopback disponível para este arquivo, e o faz de tal forma que o kernel interpreta os bytes no começo como uma tabela de partições :

$ sudo losetup -fP ./sdcard.img

$ losetup --list
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0         0      0         0  0 /home/evadeflow/Desktop/sdcard.img

Pode parecer uma coisa pequena, mas passar -P significa que agora você pode usar ferramentas como fdisk para particionar o 'disco' mapeado via /dev/loop0 . Aqui, eu crio uma partição de 128 MB no começo e uma segunda partição para abrigar todo o espaço restante:

$ sudo fdisk /dev/loop0
GNU Fdisk 1.3.0a
Copyright (C) 1998 - 2006 Free Software Foundation, Inc.
...
Using /dev/loop0
Command (m for help): p

Disk /dev/loop0: 4 GB, 4293596160 bytes
255 heads, 63 sectors/track, 522 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

     Device Boot      Start         End      Blocks   Id  System
Command (m for help): n
Partition type
   e   extended
   p   primary partition (1-4)
p
First cylinder  (default 0cyl):
Last cylinder or +size or +sizeMB or +sizeKB  (default 521cyl): +128M
Command (m for help): n
Partition type
   e   extended
   p   primary partition (1-4)
p
First cylinder  (default 15cyl):
Last cylinder or +size or +sizeMB or +sizeKB  (default 521cyl):
Command (m for help): p

Disk /dev/loop0: 4 GB, 4293596160 bytes
255 heads, 63 sectors/track, 522 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

     Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1               1          16      128488   83  Linux
Warning: Partition 1 does not end on cylinder boundary.
/dev/loop0p2              16         522     4064445   83  Linux
Command (m for help): w
Information: Don't forget to update /etc/fstab, if necessary.


Writing all changes to /dev/loop0.

Observe que o Linux criou novos dispositivos de loopback em seu nome para cada uma das duas partições: /dev/loop0p1 e /dev/loop0p2 . Você pode ver o relacionamento deles com /dev/loop executando lsblk :

$ lsblk /dev/loop0
NAME      MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0       7:0    0     4G  0 loop
├─loop0p1 259:2    0 122.1M  0 loop
└─loop0p2 259:3    0   3.9G  0 loop

Para preencher essas partições, você pode criar sistemas de arquivos usando os dispositivos de loopback /dev/loop0p1 e /dev/loop0p2 , depois simplesmente montar eles, e copiar arquivos para os pontos de montagem. O processo parece meio assim:

$ sudo mkfs.ext4 /dev/loop0p1
$ sudo mkfs.ext4 /dev/loop0p2
$ mkdir part1-stuff part2-stuff
$ sudo mount /dev/loop0p1 ./part1-stuff
$ sudo mount /dev/loop0p2 ./part2-stuff
$ cp /stuff-source/part1/* ./part1-stuff
$ cp /stuff-source/part2/* ./part2-stuff
$ sudo umount ./part1-stuff
$ sudo umount ./part2-stuff

Quando as partições estiverem do jeito que você deseja, basta "desanexar" /dev/loop0 do arquivo usando:

$ sudo losetup -d /dev/loop0

Observe que isso também desanexa os dispositivos /dev/loop0p1 e /dev/loop0p2 que o Linux criou para você.

Assim, em resumo, a resposta aceita permanece 100% correta e fornece informações valiosas sobre o que está acontecendo embaixo das capas. Mas se a losetup da sua distribuição suportar a opção -P , você pode usar apenas ferramentas de particionamento padrão e permitir que o Linux manipule a criação (e exclusão ) do loop 'sub-device' para cada partição. / p>     

por 26.03.2019 / 15:41