Loopback Device
环回设备(Loopback Device)是一种用于将文件解释为真实设备的机制。 这种方法的主要优点是,在真实磁盘上使用的所有工具都可以与环回设备一起使用。
注意:本文仅介绍UNIX环境(包括Cygwin)。 有关如何在Windows上使用环回设备的信息,请参阅 diskpart。
Linux下的环回设备
Linux环回设备只能由root使用,在使用之前需要在内核中启用。
带有GRUB和EXT2的软盘映像
首先,让我们创建一个空映像。
dd if=/dev/zero of=floppy.img bs=512 count=2880
现在,让我们为挂载将其设置一下。(译者注:losetup是用于设置环回设备的Linux命令)
losetup /dev/loop0 floppy.img
现在让我们将其设置为EXT2格式。
mkfs -t ext2 /dev/loop0
挂载!
mount -t ext2 /dev/loop0 /mnt/myfloppy
创建GRUB目录。
cd /mnt/myfloppy mkdir grub
复制GRUB的第二阶段文件。(GRUB阶段[12]也可以位于/usr/lib/GRUB/)
cp /lib/grub/i386-pc/stage[12] /mnt/myfloppy/grub
为GRUB安装创建设备映射。“你需要第一部分的引语。”
echo "(fd0) /dev/loop0" > /mnt/myfloppy/grub/device.map
启动GRUB控制台以安装到引导记录中。
grub --device-map=/mnt/myfloppy/grub/device.map /dev/loop0
在GRUB控制台中:
root (fd0) setup (fd0)
注意:在使用仿真器直接读取/dev/loop0之前,必须先卸载/mnt/myfloppy,例如:
qemu -fda /dev/loop0
注意: 删除环回设备时,原始的floppy.img文件将与修改后的内容一起保存。
带有FAT16的软盘映像
创建空映像。
dd if=/dev/zero of=floppy.img bs=512 count=2880
挂载前设置。
losetup /dev/loop0 floppy.img
把它做成MSDOS格式。
mkdosfs /dev/loop0
挂载!
mount -t msdos /dev/loop0 /mnt/myfloppy
带FAT12的软盘映像
下面提到的步骤对BrokenThorn Entertainment教程很有用
创建空映像。
dd if=/dev/zero of=floppy.img bs=512 count=2880
挂载前设置。
losetup /dev/loop0 floppy.img
将其格式化为FAT12。
mkdosfs -F 12 /dev/loop0
挂载!
mount /dev/loop0 /mnt -t msdos -o "fat=12"
卸载
umount /mnt
销毁环回设备
losetup -d /dev/loop0
硬盘映像
硬盘映像包含一个MBR,然后包含许多分区,但是Linux中的 “mount” 指令适用于磁盘分区,而不是全磁盘。 要装载磁盘映像中包含的分区,我们需要确保“mount”命令只看到我们的分区,而不是整个磁盘。
创建映像
首先创建将用于磁盘映像的空文件。 我们假设磁盘的几何结构为#cylinders(柱面),16个磁头,63个扇区/磁道,512字节/扇区,这意味着每个柱面包含516096字节(16*63*512)。 确定你想要的磁盘映像的大小,并选择适当的柱面数量(我将始终使用#cylinders)。
示例: 如果我想要一个500Mb的磁盘,我会选择1000柱面 ((500*1000*1024)/516096的近似值)。
写入磁盘映像(我假设文件名为c.img):
dd if=/dev/zero of=/path/to/c.img bs=516096c count=#cylinders
说明:
dd | 用于复制和转换文件的Linux命令 |
if=/dev/zero | 源文件为/dev/ZERO,它是...*drumroll*...无限的零 |
of=/path/to/c.img | 目标文件是我们的磁盘映像 (如果不存在,dd将创建该文件) |
bs=516096c | 意味着一次读写516096字节(这只是为了简单起见) |
count=#cylinders | 复制此数量的块。由于我们将bs设置为516096字节,因此每个块是一个柱面长 |
这给我们留下了一个装满零的大小合适的文件,我们将把它用于我们的磁盘映像。
分区
现在,要在磁盘映像上创建MBR和分区表(通常你需要是root用户)。
fdisk -u -C#cylinders -S63 -H16 /path/to/c.img
说明:
fdisk | Linux DOS分区维护程序。 |
-u | 以扇区而不是柱面显示单位(我们将需要此功能)。 |
-C#cylinders | 将磁盘的柱面设置为我们的值。 |
-S63 | 将 扇区/轨道设置为63。 |
-H16 | 将 磁头/轨道设置为16。 |
/path/to/c.img | fdisk is capable of partitioning image files directly. |
在fdisk中使用以下命令:
o - 创建一个新的空DOS分区表。 n - 创建一个新分区(为简单起见,只创建一个覆盖整个磁盘的主分区)。 a - 切换可引导标志 (可选)。 p - 打印分区表。
你最终应该会得到一个如下所示的屏幕:
Disk /path/to/c.img: 516 MB, 516096000 bytes 16 heads, 63 sectors/track, 1000 cylinders, total 1008000 sectors Units = sectors of 1 * 512 = 512 bytes
Device Boot Start End Blocks Id System /path/to/c.img1 * 63 1007999 503968+ 83 Linux
显然,根据映像的大小,柱面数量,分区末端和块将有所不同。
记下起始扇区(此处63)和块计数(此处503968)。
注意:如果你打算将分区格式化为ext2fs以外的格式,那么在这里使用t命令更改分区id。 我还应该指出,磁盘制造商和程序员认为的每兆多少字节有差异。
w -将分区表写入“磁盘”并退出。
忽略有关重新读取分区表的任何错误。 因为这不是物理设备,我们真的不在乎。
我们现在在磁盘映像上有一个分区表。
不幸的是,这也意味着从现在开始,我们必须考虑这样一个事实,即我们的分区不是从映像的字节0开始的。
挂载
好的,现在我们将文件附加到环回设备,这样我们就可以在分区开始之前跳过所有内容。
losetup -o32256 /dev/loop0 /path/to/c.img
解释
-o32256 | Move the start of data 32256 bytes into the file |
我们将32256个字节移动到文件中的原因是这是分区开始的地方。 还记得我说过要注意分区的起始扇区吗(通常是63)? 因为每个扇区有512字节长,所以我们知道分区的起始字节是文件中的32256(63*512)字节。 造成这种差距的原因是,大多数 (没有真正标准的) fdisk程序除了MBR之外,没有使用第一个轨道。 然而,这些空间并不总是被浪费,一些引导加载程序(如GRUB)使用它来存储程序的部分内容。
注意:如果你没有使用建议的几何尺寸,那么你必须自己计算一下。
我们现在有一个设备 (/dev/loop0),我们可以以类似于普通分区 (例如/dev/hda1) 的方式使用它。
格式化分区
对于ext2fs,使用:
mke2fs -b1024 /dev/loop0 #blocks
说明:
mke2fs | 创建一个EXT2文件系统 |
-b1024 | 使用块大小1024 |
/dev/loop0 | 创建文件系统的设备 (这里/dev/loop0是我们的 “分区”) |
#blocks | 记得我说过要注意fdisk部分的块数吗?这就是为什么。 |
这为我们提供了一个干净的ext2格式化分区。
注意: mke2fs足够聪明,可以自己找出块大小和 #blocks,但是如果你想使用多个分区,则需要知道如何使用这些值。
对于FAT32,请使用:
mkdosfs -F32 /dev/loop0 #blocks
说明:
mkdosfs | 创建一个DOS文件系统 (在某些Linux系统上可能不存在,如果不存在,请搜索dosfstools软件包) |
-F32 | FAT 32分配表(如何使用FAT12/FAT16应该是显而易见的) |
/dev/loop0 | 与ext2fs版本相同 |
#blocks | 与ext2fs版本相同 |
这为我们提供了一个干净的FAT32格式分区(忽略软盘警告)。
注意:使用#blocks的原因与使用ext2fs相同,即可能有多个分区。
挂载分区
现在应该可以挂载分区了(因为它仍在环回设备上设置)。
命令:
mount -text2 /dev/loop0 /mnt/wherever
或者:
mount -tvfat /dev/loop0 /mnt/wherever
说明:
mount | Linux命令挂载文件系统 |
-text2 / -tvfat | 在使用文件系统时,Linux通常可以自己解决这个问题。 |
/dev/loop0 | 代表我们分区的设备 |
/mnt/wherever | 用于挂载分区的目录。 |
这应该会为你留下一个挂载良好的分区。 如果你运行df-Th,你应该得到一条类似于:
Filesystem Type Size Used Avail Use% Mounted on /dev/loop0 vfat 492M 4.0K 492M 1% /mnt/wherever
...或对于ext2fs:
Filesystem Type Size Used Avail Use% Mounted on /dev/loop0 ext2 477M 13K 452M 1% /mnt/wherever
(是的,这些是针对同一磁盘映像的。默认情况下,ext2fs保留/使用相当多的空间,甚至是空的。)
卸载、分离
好的,卸载分区并分离环回设备。
命令:
umount /dev/loop0 losetup -d /dev/loop0
说明:
umount | 用于卸载文件系统的Linux命令。 |
/dev/loop0 | 安装的设备 |
使之更容易
最后要做的一件事是简化该分区的挂载和卸载。
挂载:
mount -text2 -oloop=/dev/loop0,offset=32256 /path/to/c.img /mnt/wherever
卸载:
umount /path/to/c.img
这实质上是我们之前格式化分区时使用的losetup和mount命令的组合。 如果使用,这也意味着我们无法通过/dev/loop0访问原始 “磁盘” 或 “分区”。
另见 http://www.pixelbeat.org/scripts/lomount.sh
最后,如果你必须非常频繁地挂载和卸载该映像,并且你懒得每次都键入sudo密码,那么只需添加到/etc/fstab:
/path/to/c.img /mnt/wherever ext2 user,loop 0 0
现在你可以直接使用:
mount /mnt/wherever umount /mnt/wherever
最后
就是这样,你现在知道如何在Linux下处理硬盘映像了。 安装时,你可以以与使用普通磁盘分区完全相同的方式使用它。 多个分区是它的扩展,只需根据要使用的分区(并使用正确的块数)更改losetup命令的偏移量。
要记住的事项:
- losetup类型命令将为你提供与原始磁盘设备等效的命令 (例如/dev/hda)
- losetup-o type命令将为你提供相当于原始分区设备(例如/dev/hda1)的功能
在操作挂载的磁盘映像上的文件时,不要忘记刷新文件系统缓冲区。 在类似Unix的系统上,这可以简单地通过在你的shell中执行 sync 程序来完成。
FreeBSD下的环回设备
FreeBSD使用mdconfig。 首先,使用DD创建一个空的软盘图像 (大小为1.44 MB)。 Memdisks是动态分配的,名称显示在mdconfig命令之后。 这里假设打印了“md0”。
要挂载:
dd if=/dev/zero of=floppy.img bs=512 count=2880 mdconfig -a -t vnode -f floppy.img newfs_msdos -f 1440 /dev/md0 mount -t msdosfs /dev/md0 /mnt/myfloppy
要卸载:
umount /mnt/myfloppy mdconfig -d -u md0
OpenBSD下的环回设备
OpenBSD使用了vnconfig(8),从版本2.2开始 (也许更早 ..)。
作为root用户或使用su/sudo,下面是一个配置vnode伪磁盘设备的示例场景。
使用dd创建floppy.img文件:
dd if=/dev/zero of=/path/to/floppy.img bs=512 count=2880
配置vnd0设备:
vnconfig vnd0 /path/to/floppy.img
列出已配置的设备:
vnconfig -l 输出: vnd0: covering floppy.img on wd0a, inode 270473 vnd1: not in use vnd2: not in use vnd3: not in use
创建FAT12文件系统,然后挂载设备:
newfs_msdos -F 12 -f 1440 /dev/rvnd0c mount -t msdos /dev/vnd0i /mnt/floppy
卸下设备安装并卸载vnd0设备:
umount /mnt/floppy vnconfig -u vnd0
更多信息: vnd(4) / vnconfig(8)