限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。
Linux allows users to create a special block device by which they can map a normal file to
a virtual block device.
所谓的 loop device
,就是一类特殊的虚拟块设备(block device)
,允许像访问块设备(block device)
一样访问普通文件(normal file)
,也就是loop device
将普通文件(normal file)
当作存储介质。
譬如在制作根文件系统时,核心步骤如下:
1. 用 dd 创建一个文件镜像
2. 用 mkfs 格式成需要的格式
3. 建立一个临时目录 temp
4. 将文件镜像 mount 到 temp 目录
5. 在 temp 目录下建立根文件系目录
6. umount temp 目录
这里就是将文件镜像当作块设备一样访问,这需要 loop device
的支持,否则将操作失败。譬如下面是一个制作 ext4
根文件系统的核心步骤:
dd if=/dev/zero of=rootfs.ext4 bs=1M count=2048 > /dev/null 2>&1
mkfs.ext4 -F -L linuxroot rootfs.ext4
mkdir temp
mount rootfs.ext4 temp # 这里需要 loop device 支持, 否则无法操作成功
......
umount temp
要开启 loop device
虚拟块设备功能,需要开启内核配置项 CONFIG_BLK_DEV_LOOP
,具体功能实现在 drivers/block/loop.c
中。可以通过查看是否生成了 loop device
设备节点,来确认内核是否开启 loop device
支持:
$ ls -l /dev/loop*
brw-rw---- 1 root disk 7, 0 11月 10 16:33 /dev/loop0
brw-rw---- 1 root disk 7, 1 11月 10 14:36 /dev/loop1
brw-rw---- 1 root disk 7, 2 11月 10 09:50 /dev/loop2
brw-rw---- 1 root disk 7, 3 11月 10 09:50 /dev/loop3
brw-rw---- 1 root disk 7, 4 11月 10 09:50 /dev/loop4
brw-rw---- 1 root disk 7, 5 11月 10 09:50 /dev/loop5
brw-rw---- 1 root disk 7, 6 11月 10 09:50 /dev/loop6
brw-rw---- 1 root disk 7, 7 11月 10 09:50 /dev/loop7
crw-rw---- 1 root disk 10, 237 11月 10 09:50 /dev/loop-control
其中设备 /dev/loop-control
是用来设置和控制块设备的字符设备节点,其它的 /dev/loop[0-7]
是虚拟块设备。初始虚拟块设备的个数可通过内核配置项 CONFIG_BLK_DEV_LOOP_MIN_COUNT
进行调整,默认是 8
个。
losetup
是一个设置和控制 loop device
的工具,更多细节请参考 man 手册。
笔者挂载了一个 ext4
的根文件系统到 temp
目录,然后分别通过 mount, lsblk, losetup
来查询挂载状态:
$ sudo mount rootfs/arm-ubuntu-16.04.img temp
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
loop0 7:0 0 2G 0 loop /home/XXX/qemu-lab/arm-ubuntu/temp
sda 8:0 0 80G 0 disk
├─sda2 8:2 0 1K 0 part
├─sda5 8:5 0 975M 0 part [SWAP]
└─sda1 8:1 0 79G 0 part /
$ mount | grep ext4
/home/XXX/qemu-lab/arm-ubuntu/rootfs/arm-ubuntu-16.04.img on /home/XXX/qemu-lab/arm-ubuntu/temp type ext4 (rw,relatime,data=ordered)
$ losetup -a
/dev/loop0: []: (/home/XXX/qemu-lab/arm-ubuntu/rootfs/arm-ubuntu-16.04.img)
$ losetup -l
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0 0 0 1 0 /home/XXX/qemu-lab/arm-ubuntu/rootfs/arm-ubuntu-16.04.img
[1] https://itsfoss.com/loop-device-linux/