技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 系统运维 --> 从磁盘映像中挂载或提取指定分区

从磁盘映像中挂载或提取指定分区

浏览:2852次  出处信息

      最近在做虚拟机相关的事,需要处理一些磁盘和分区的映像文件。如何从一个磁盘映像中挂载指定的分区到本地 Linux 文件系统呢?理论上说,可以用 dd 把该分区从磁盘映像中提取出来再挂载,不过 mount 提供了针对 loop 设备的偏移量参数,方便直接从磁盘映像中挂载指定分区。笔记如下:

      演示用的磁盘映像使用 qemu-img 制作。我们使用原生的 raw 格式,等价于磁盘上的原始数据流,保证它在任何 Linux 系统上都可以直接挂载。使用 Windows PE 工具盘启动该 qemu 虚拟机,创建一系列不同格式的分区并在其中建立几个文件。

root@lj-laptop:/opt/vm# qemu-img create -f raw vmtest.img 5Groot@lj-laptop:/opt/vm# qemu -hda ./vmtest.img -cdrom /dev/cdrom -boot d -m 256M -localtime

      磁盘分区结构如截图:

    从磁盘映像中挂载或提取指定分区

      回到宿主系统,使用 fdisk 的 -l、-u 参数查看磁盘映像。其中 -u 表示以扇区为单位显示分区起止位置,方便后续计算。

root@lj-laptop:/opt/vm# fdisk -l -u vmtest.img You must set cylinders.You can do this from the extra functions menu. Disk vmtest.img: 0 MB, 0 bytes255 heads, 63 sectors/track, 0 cylinders, total 0 sectorsUnits = sectors of 1 * 512 = 512 bytesDisk identifier: 0xbd86bd86      Device Boot      Start         End      Blocks   Id  Systemvmtest.img1              63     8193149     4096543+  83  Linuxvmtest.img2         8193150    10249469     1028160    5  Extendedvmtest.img3        10249470    10474379      112455    6  FAT16vmtest.img5         8193213     8610839      208813+  83  Linuxvmtest.img6         8610903     9028529      208813+  82  Linux swap / Solarisvmtest.img7         9028593    10249469      610438+   b  W95 FAT32

      这时我们只需要为 mount 添加 offset 参数,指定分区在磁盘映像中的逻辑地址,即可挂载这一分区。注意 offset 的单位是字节,通常一个扇区是 512 字节,因此需要用 fdisk 输出的 Start 乘以 512。以 vmtest.img3 分区为例。

root@lj-laptop:/opt/vm# mount -o loop,offset=$((10249470*512)) vmtest.img ./part/root@lj-laptop:/opt/vm# ls ./part/InFAT16.txtroot@lj-laptop:/opt/vm# umount ./part/

      如果有必要,我们可以将特定的分区从硬盘映像中提取出来,方便单独使用。通过 dd 可以完成提取,简便起见使用扇区大小 512 字节作为 bs 参数,这样 skip、count 参数很容易从 fdisk 的输出中计算出来。下面提取 vmtest.img5。

root@lj-laptop:/opt/vm# dd if=vmtest.img of=linux2.img bs=512 skip=8193213 count=$((8610839-8193213+1))417627+0 records in417627+0 records out213825024 bytes (214 MB) copied, 4.67434 s, 45.7 MB/sroot@lj-laptop:/opt/vm# mount -o loop linux2.img ./part/root@lj-laptop:/opt/vm# ls ./part/InLinux2.txt  lost+foundroot@lj-laptop:/opt/vm# umount ./part/

      到这一步,我们已经实现了从磁盘映像中挂载或提取指定分区。其中 fdisk 帮我们完成了磁盘映像的分析,直接将分区的逻辑地址显示给了我们。现在我们再借机复习一下磁盘分区表的格式,试试手工计算相关地址。这里推荐大家阅读网上这篇《解读 Windows 操作系统分区表的秘密》,其中详解过的概念这里不再赘述,下面的内容权当对这篇文章在 Linux 平台下的补充。

      首先查看磁盘映像的主引导扇区,其中分区表位于 0x1be 开始的 64 字节。

root@lj-laptop:/opt/vm# cat vmtest.img | xxd | head -32...00001b0: 0000 0000 0000 0000 86bd 86bd 0000 0001  ................00001c0: 0100 83fe 7ffd 3f00 0000 3f04 7d00 0000  ......?...?.}...00001d0: 41fe 05fe bf7d 7e04 7d00 8060 1f00 0000  A....}~.}..`....00001e0: 817e 06fe bf8b fe64 9c00 8e6e 0300 0000  .~.....d...n....00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

      对于 vmtest.img1 和 vmtest.img3 这两个主分区,我们读出它们的起始逻辑地址分别为 0x3f 和 0x9c64fe(注意在分区表中以 Little-endian 存储),换算成十进制与 fdisk 输出的一致。bash 的算术表达式支持十六进制字面值,挂载方式同上。

root@lj-laptop:/opt/vm# mount -o loop,offset=$((0x3f*512)) vmtest.img ./part/root@lj-laptop:/opt/vm# ls ./part/InLinux.txt  lost+foundroot@lj-laptop:/opt/vm# umount ./part/root@lj-laptop:/opt/vm# mount -o loop,offset=$((0x9c64fe*512)) vmtest.img ./part/root@lj-laptop:/opt/vm# ls ./part/InFAT16.txtroot@lj-laptop:/opt/vm# umount ./part/

      对于扩展分区 vmtest.img2,我们通过 dd 定位到它所指向的第一个逻辑分区 vmtest.img5 前面的卷引导记录,查看逻辑分区的链式分区表。

root@lj-laptop:/opt/vm# dd if=vmtest.img bs=512 skip=$((0x7d047e)) | xxd | head -32...00001b0: 0000 0000 0000 0000 0000 0000 0000 0001  ................00001c0: 41fe 83fe bf17 3f00 0000 5b5f 0600 0000  A.....?...[_....00001d0: 8118 05fe bf31 9a5f 0600 9a5f 0600 0000  .....1._..._....00001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

      vmtest.img5 相对于 vmtest.img2 的偏移量为 0x3f,按此地址挂载。

root@lj-laptop:/opt/vm# mount -o loop,offset=$(((0x7d047e+0x3f)*512)) vmtest.img ./part/root@lj-laptop:/opt/vm# ls ./part/InLinux2.txt  lost+foundroot@lj-laptop:/opt/vm# umount ./part/

      沿着链式分区表的第二条记录(即链表指针)指示的偏移量,我们可以找到第二、第三个逻辑分区(vmtest.img6、vmtest.img7)前面的卷引导记录以及这两个分区的逻辑地址。

root@lj-laptop:/opt/vm# dd if=vmtest.img bs=512 skip=$((0x7d047e+0x65f9a)) | xxd | head -32...00001b0: 0000 0000 0000 0000 0000 0000 0000 0001  ................00001c0: 8118 82fe bf31 3f00 0000 5b5f 0600 0000  .....1?...[_....00001d0: 8132 05fe bf7d 34bf 0c00 4ca1 1200 0000  .2...}4...L.....00001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.root@lj-laptop:/opt/vm# dd if=vmtest.img bs=512 skip=$((0x7d047e+0xcbf34)) | xxd | head -32...00001b0: 0000 0000 0000 0000 0000 0000 0000 0001  ................00001c0: 8132 0bfe bf7d 3f00 0000 0da1 1200 0000  .2...}?.........00001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................00001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

      取得了相应的地址,挂载或提取分区当然是轻而易举的。下面挂载了 vmtest.img7、提取了 vmtest.img5。

root@lj-laptop:/opt/vm# mount -o loop,offset=$(((0x7d047e+0xcbf34+0x3f)*512)) vmtest.img ./part/root@lj-laptop:/opt/vm# ls ./part/InFAT32.txtroot@lj-laptop:/opt/vm# umount ./part/root@lj-laptop:/opt/vm# dd if=vmtest.img of=linux2.img bs=512 skip=$((0x7d047e+0x3f)) count=$((0x65f5b))417627+0 records in417627+0 records out213825024 bytes (214 MB) copied, 4.65149 s, 46.0 MB/sroot@lj-laptop:/opt/vm# mount -o loop ./linux2.img ./part/root@lj-laptop:/opt/vm# ls ./part/InLinux2.txt  lost+foundroot@lj-laptop:/opt/vm# umount ./part/

建议继续学习:

  1. Centos挂载新硬盘开机自动挂载    (阅读:7736)
  2. 从磁盘映像中挂载或提取指定的 LVM 逻辑卷    (阅读:3892)
  3. 将远程共享文件夹挂载到linux本地目录    (阅读:3620)
  4. linux磁盘管理学习笔记(下):linux分区、挂载    (阅读:3107)
  5. Oracle hash分区的秘密    (阅读:2978)
  6. linux大于2T的磁盘使用GPT分区    (阅读:2852)
  7. LVM介绍    (阅读:2820)
  8. 如何删除品牌电脑中的隐藏分区    (阅读:2729)
  9. 用CloneZilla制作紧急恢复分区    (阅读:2660)
  10. CentOS分区规律大总结    (阅读:2555)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1