我每天的任务之一是创建一个装有我们软件的 USB 闪存盘的可启动映像。该映像必须包含两个分区,第一个分区使用 FAT32 格式,第二个分区使用 EXT3 格式。在第一个分区中,我们放置 Linux 内核和一个小的启动脚本,我们将要启动的设备上引导加载程序会在启动时读取该脚本。
在第二个分区上我们放置了我们的 rootfs。
现在,我是这样操作的:
将 USB 闪存盘插入我的 Linux 计算机。找出其设备文件(这里我们假设为 /dev/sdx)
将前 600 MB 清零: dd if=/dev/zero of=/dev/sdx bs=1M count=600
创建两个分区,第一个 10 MB,第二个 500 MB: sfdisk /dev/sdx --unit S << EOF ,20000,c ,1000000,83 EOF
mkfs.vfat /dev/sdx1 mkfs.ext3 /dev/sdx2
(假设扇区大小为 512 字节!)
- 将内核和启动脚本复制到/dev/sdx1
- 将预编译的 RootFS 解压到 /dev/sdx2
- 将现成的图像从 USB 驱动器复制回我们的硬盘:dd if=/dev/sdx of=usb.img bs=1M count=520
- 将其压缩并发送给测试该软件的人员。
- 然后人们解压缩,用 dd if=usb.img of=/dev/sdx 刷新他们的 USB 磁盘,插入他们的设备并进行测试。
现在,所有这一切都已完成。明显的改进是创建一个脚本,可以自动完成所有操作。这也可以做到,但仍需保留一个手动步骤:插入 USB 闪存盘。
我在想,我们可以使用 RAM 中的块设备来代替实际的 USB 磁盘。这不仅可以省去插入 USB 磁盘的手动步骤,而且速度也会更快。
所以我需要的是 RAM 中的一个普通块设备。它可以像物理 USB 闪存盘一样分成多个分区。
我刚刚研究了这个话题,似乎唯一的选择是
- tmpfs 和 ramfs,显然不适合我
- ramdisk 和 'brd' 内核模块,加载后会创建多个 '分区':/dev/ram[0-15]
并且它们每个都可以单独格式化和使用,但是就像我说的 - 我想要一个 RAM 中的普通块设备,然后我自己将其分成 10MB 和 500MB 的两个分区,然后我就可以从那里将图像添加到我的 HDD 上的文件中。
我有什么选择?
答案1
只需使用 brd 并创建一个 brd 设备 (ram0)。使用该设备代替您的 usb 驱动器。您可以使用 sfdisk 对其进行分区,使用分区,然后使用 dd 将其内容转储到文件中。
每个 brd 设备无需使用一个文件系统。
或者(虽然有点 hack 化)您可以使用 tmpfs,创建图像文件并将其用作循环设备。这可能是实现您想要的最简单的方法。作为奖励,您已经准备好了该图像并可以立即上传。无需 dd。
# Create mountpoint for tmpfs
mkdir /tmp/tmpfs
# Mount tmpfs there
mount -t tmpfs none /tmp/tmpfs
# Create empty file of 600MB
# (it creates 599MB hole, so it does not
# consume more memory than needed)
dd if=/dev/zero of=/tmp/tmpfs/img.bin bs=1M seek=599 count=1
# Partition the image file
cfdisk /tmp/tmpfs/img.bin
# Create loop block device of it (-P makes kernel look for partitions)
losetup -P /dev/loop0 /tmp/tmpfs/img.bin
# Create filesystems
mkfs.vfat /dev/loop0p1
mkfs.ext4 /dev/loop0p2
# Now it's your turn:
# mount loop0p1 and loop0p2 and copy whatever you want and unmount it
# detach the loop device
losetup -d /dev/loop0
# May i present you with your image ...
ls -al /tmp/tmpfs/img.bin
进行修改以满足您的需要。
答案2
这类似于 Fox 的答案,但使用的是 ram disk 而不是 tmpfs。在我使用 vdbench 进行的测试中,ram disk 显示的 IOPS 高于 tmpfs(在我的计算机上连续三次测试中,IOPS 为 33k,IOPS 为 29k,总共进行了 6 次测试),并且设置起来也更容易。
# the following creates 1 device /dev/ram0 of size 600M. More elaborate parameters
# description you can see with `modinfo brd | grep parm`, ATM there's just three.
modprobe brd rd_nr=1 rd_size=614400
# Partition the image file. The following creates two GPT partitions: one of size
# 300M, and the other one takes all space that's left
sgdisk -Z --new 1::+300M --new 2 /dev/ram0
# Create filesystems
mkfs.vfat /dev/ram0p1
mkfs.ext4 /dev/ram0p2
# Now you can mount ram0p1 and ram0p2 as you would with a usual block device and copy
# your stuff there. After you `umount` it, you get a partitioned `/dev/ram0` block
# device with your files. You can make an image of it with `dd if=/dev/ram0 of=img.bin`
# for example. After you're done, to remove the ram device execute `rmmod brd`.
答案3
nbdkit-内存插件可用于用户空间实现:
$ nbdkit -U /tmp/sock memory 10G
# nbd-client -unix /tmp/sock /dev/nbd0
这是作为稀疏数组实现的,因此它可以是任意虚拟大小。添加 allocator=zstd 进行压缩。