在折腾树莓派/香蕉派的时候,想直接复制img镜像中的文件。烧录到SD又太麻烦,就想找找有没有能直接挂载img的方式。这一找,果然还真有。

大体上分手动分配loop设备和自动分配loop设备两种方法。

手动创建loop设备

  1. 先查看第一个空闲loop设备
    1
    2
    
    sudo losetup -f  
    /dev/loop0
    
  2. 使用上一步得到的设备名,第一次创建loop设备
    1
    
    sudo losetup /dev/loop0 bananian-1501.img
    
  3. 查看信息
    1
    
    sudo fdisk -lu /dev/loop0
    

    输出内容

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    Disk /dev/loop0: 1.9 GiB, 2032664576 bytes, 3970048 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x6c70c806
    
    Device       Boot Start     End Sectors  Size Id Type
    /dev/loop0p1       2048   43007   40960   20M 83 Linux
    /dev/loop0p2      43008 3970047 3927040  1.9G 83 Linux
    

    可以看到,这个镜像有两个分区(loop0p1和loop0p2)。从第2048扇区开始(Start列),每扇区512字节(Units = sectors of 1 * 512 = 512 bytes),我们算出offset,下面mout命令会用到。

    1
    2
    
    2048*512=1048576
    43008*512=22020096
    
  4. 挂载
    1
    2
    3
    4
    5
    6
    
    mkdir boot root
    sudo losetup -o 1048576 /dev/loop1 bananian-1501.img
    sudo mount -o loop /dev/loop1 boot
    sudo losetup -o 22020096 /dev/loop3 bananian-1501.img
    sudo mount -o loop /dev/loop3 root
    ls boot root
    

    输出结果

    1
    2
    3
    4
    
    boot:
    fex script.bin uEnv.txt uEnv.txt.video-acc-off uEnv.txt.video-acc-on uImage
    root:
    bin boot dev etc home lib lost+found media mnt opt proc root run sbin selinux srv swapfile1 sys tmp usr var
    

自动创建loop设备

fdisk可以直接查看img文件,mount可以自动创建loop设备,所以上面步骤可以简化

  1. 查看信息
    1
    
    sudo fdisk -lu bananian-1501.img
    

    输出结果

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    Disk bananian-1501.img: 2032 MB, 2032664576 bytes
    255 heads, 63 sectors/track, 247 cylinders, total 3970048 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x6c70c806
    
        Device Boot              Start         End      Blocks   Id  System
    bananian-1501.img1            2048       43007       20480   83  Linux
    bananian-1501.img2           43008     3970047     1963520   83  Linux
    

    同样的方法计算出offset

    1
    2
    
    2048*512=1048576
    43008*512=22020096
    
  2. 直接mount
    1
    2
    3
    4
    
    mkdir boot root
    sudo mount -o offset=1048576 bananian-1501.img boot
    sudo mount -o offset=22020096 bananian-1501.img root
    ls boot root
    

    输出结果

    1
    2
    3
    4
    
    boot:
    fex script.bin uEnv.txt uEnv.txt.video-acc-off uEnv.txt.video-acc-on uImage
    root:
    bin boot dev etc home lib lost+found media mnt opt proc root run sbin selinux srv swapfile1 sys tmp usr var
    

    手动计算offset略微有点麻烦,可以利用expr命令。将挂载命令中offset后面的数值替换成expr命令的运算值即可,注意用反引号`。例如上面两条挂载命令可以改成以下命令。

    1
    2
    
    sudo mount -o offset=`expr 512 \* 2048` bananian-1501.img boot
    sudo mount -o offset=`expr 512 \* 43008` bananian-1501.img root
    

参考文章