56

I have to mount a .img file but I don't know what type of .img it is. How can I figure out what type of .img file it is?

# mount -t auto -o ro,loop gmapsupp.img /mnt/iso/
mount: you must specify the filesystem type
# file -k gmapsupp.img 
gmapsupp.img: x86 boot sector, code offset 0x0
#
1

7 Answers 7

62

Try running the command fdisk -l <img file>. Typically if the .img files are entire disks from say a KVM VM then they're technically a virtual disk.

Example

I've got a CentOS KVM VM which shows up like so with the file command:

$ file centostest.img 
centostest.img: x86 boot sector; partition 1: ID=0x83, active, starthead 1, startsector 63, 208782 sectors; partition 2: ID=0x8e, starthead 0, startsector 208845, 20755980 sectors, code offset 0x48

Running fdisk with it:

$ sudo /sbin/fdisk -lu /kvm/centostest.img
last_lba(): I don't know how to handle files with mode 81ed
You must set cylinders.
You can do this from the extra functions menu.

Disk /kvm/centostest.img: 0 MB, 0 bytes
255 heads, 63 sectors/track, 0 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes

              Device Boot      Start         End      Blocks   Id  System
/kvm/centostest.img1   *          63      208844      104391   83  Linux
/kvm/centostest.img2          208845    20964824    10377990   8e  Linux LVM
Partition 2 has different physical/logical endings:
     phys=(1023, 254, 63) logical=(1304, 254, 63)

If you'd like to mount one of these partitions you can do so as follows:

fdisk (cylinder output)
  • block-size of 512 bytes and the start-block is 63.
  • The offset is 512 * 63 = 32256.
fdisk (sector output)
  • block-size of 512 bytes and the start-block is 1.
  • The offset is 512 * 1 = 512.

So the mount command would be:

in cylinders
$ mount -o loop,offset=32256 centostest.img /mnt/tmp

To mount the other partition (512 * 208845 = 106928640):

$ mount -o loop,offset=106928640 centostest.img /mnt/tmp
in sectors
$ mount -o loop,offset=512 centostest.img /mnt/tmp

To mount the other partition (512 * 14 = 7168):

$ mount -o loop,offset=7168 centostest.img /mnt/tmp

NOTE

This will only work if mount can determine the type of filesystem within the "partition" you're attempting to mount. You may need to include -t auto, or be specific and tell mount that's it's -t ext4 for example.

References

6
  • # mount -t auto -o ro,loop,offset=512 gmapsupp.img /mnt/iso/ \ mount: you must specify the filesystem type
    – Luigi
    Jul 9, 2013 at 10:55
  • # fdisk -l gmapsupp.img Disk gmapsupp.img: 0 MB, 0 bytes 255 heads, 63 sectors/track, 0 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Device Boot Start End Blocks Id System gmapsupp.img1 1 9 65536 0 Empty Partition 1 has different physical/logical endings: phys=(1023, 15, 8) logical=(8, 40, 32) Partition 1 does not end on cylinder boundary.
    – Luigi
    Jul 9, 2013 at 10:58
  • @Luigi - can you post these comments as updates to your question? I can't see what's going on.
    – slm
    Jul 9, 2013 at 11:23
  • @Luigi - there is no guarantee that -t auto can identify the type of the partition. You'll have to just try others to see what works.
    – slm
    Jul 9, 2013 at 11:36
  • 1
    how to determine offset for 2nd partition? why 512x14? and my 1st partition is W95 FAT16 (LBA) -t vfat failed to mount my 1st partition.
    – Necktwi
    Aug 13, 2014 at 20:20
26

Use parted to identify offset values.

root@mysystem:~/# parted myimage.img
GNU Parted 2.3
Using /root/myimage.img
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) u
Unit?  [compact]? B
(parted) print
Model:  (file)
Disk /root/myimage.img: 8589934592B
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start        End          Size         Type     File system     Flags
 1      32256B       254983679B   254951424B   primary  ext3            boot
 2      254983680B   1274918399B  1019934720B  primary  linux-swap(v1)
 3      1274918400B  3323013119B  2048094720B  primary  ext3
 4      3323013120B  8587192319B  5264179200B  primary  ext3

(parted) 

Now you have offset values and you can use those to mount filesystems.

# mount -o loop,offset=32256 myimage.img /mnt/disk1 
# mount -o loop,offset=1274918400 myimage.img /mnt/disk2
# mount -o loop,offset=3323013120 myimage.img /mnt/disk3
3
  • 1
    One or two-line answers are often considered not that helpful. Consider expanding your explanation of your recommendation or linking to relevant documentation or helpful resources.
    – HalosGhost
    Sep 19, 2014 at 20:15
  • Definitely better with a bit of explanation, the most efficient answer for me here, thanks Fayiz / HalosGhost !
    – tisc0
    Apr 9, 2016 at 19:05
  • parted: unrecognized disk label
    – user180574
    Feb 15, 2017 at 22:15
7

I realize this thread is old but if your system is newer, like Ubuntu 20.04, you could use udiskctl:

udisksctl loop-setup --file something.img

It will create loop devices for the partitions in the img and mount them. Cheers.

4
  • 2
    Confirmed. This worked like a charm in Ubuntu 20.10.
    – eduncan911
    Mar 17, 2021 at 15:38
  • thank you, works on raspiban 32 and 64bit as well Dec 11, 2021 at 16:13
  • Confirmed for Fedora 36 (probably since v30). Partion(s) are mounted to /run/media/$USER. Nov 10, 2022 at 11:25
  • Worked perfectly in Ubuntu 20.04! I'm mounting an image I just ddrecue'd from a corrupted SD card with our family photos, so I can try to recover them! Apr 20 at 22:07
6

Another quite simple way to mount an img file is to use kpartx tool (from the kpartx package). The explanation from the kpartx man page (run using sudo/root):

To mount all the partitions in a raw disk image:

          kpartx -av disk.img

This will output lines such as:

          loop3p1 : 0 20964762 /dev/loop3 63

The loop3p1 is the name of a device file under /dev/mapper which you can use to access the partition, for example to fsck it:

          fsck /dev/mapper/loop3p1

Mount that device on /mnt:

mount /dev/mapper/loop3p1 /mnt
   When you're done, you need to remove the devices:

          kpartx -d disk.img
2
  • This is the easiest IMO, no math and way to access block devices instead of just data Dec 22, 2021 at 14:20
  • by FAR the least error-prone, most straightforward way.
    – Gaia
    Jan 30, 2022 at 2:51
3

A modern version of the file command reports the startsector in a much more convenient way than fdisk or parted:

file $img Armbian_jw.img: DOS/MBR boot sector; partition 1 : ID=0x83, start-CHS (0x40,0,1), end-CHS (0x3ff,3,32), startsector 8192, 2883584 sectors

This one-liner output can be scripted like this:

startsector=$(file $img | sed -n -e 's/.* startsector *\([0-9]*\),.*/\1/p')
offset=$(expr $startsector '*' 512)
echo $offset
 4194304
sudo mount -o loop,offset=$offset $img /mnt
2
  • Can someone improve on this answer? My variant of "file" does not seem to show that additional information. Is there some way to use a commandline flag or compile file in a special way? I only get "data" as a result when running file on that .img file that I have; note that it was part of a .sub file too, so I have a rough clue as to what this was (I think a CD once but re-mounted or perhaps burned by nero by someone else).
    – shevy
    Aug 12, 2020 at 16:46
  • Worked for me on Ubuntu/Pop_OS! 20.10 -- printed the correct image type for a number of image files that I created from an Android phone's partitions. Thanks! Jun 25, 2021 at 20:16
3

losetup -P automation

The following scripts automatically mount all partitions of an image.

Usage:

$ los my.img
/dev/loop0
/mnt/loop0p1
/mnt/loop0p2

$ ls /mnt/loop0p1
/whatever
/files
/youhave
/there

$ sudo losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE                                                                                      DIO
/dev/loop1         0      0         0  0 /full/path/to/my.img

$ # Cleanup.
$ losd 0
$ ls /mnt/loop0p1
$ ls /dev | grep loop0
loop0

Source:

los() (
  img="$1"
  dev="$(sudo losetup --show -f -P "$img")"
  echo "$dev"
  for part in "$dev"?*; do
    if [ "$part" = "${dev}p*" ]; then
      part="${dev}"
    fi
    dst="/mnt/$(basename "$part")"
    echo "$dst"
    sudo mkdir -p "$dst"
    sudo mount "$part" "$dst"
  done
)
losd() (
  dev="/dev/loop$1"
  for part in "$dev"?*; do
    if [ "$part" = "${dev}p*" ]; then
      part="${dev}"
    fi
    dst="/mnt/$(basename "$part")"
    sudo umount "$dst"
  done
  sudo losetup -d "$dev"
)

Tested in Ubuntu 16.04.

1
  • While that is nice to have, I think a description could be useful; not everyone understands the shell stuff that is going on.
    – shevy
    Aug 12, 2020 at 16:47
1

It looks like @slm has some wonky math, or at least doesn't match the fdisk -l output. From the revisions it looks like adding the u parameter to fdisk changed from cylinders to sectors? Dunno, but it doesn't do anything on mine since the default should be sectors.

On my image:

$ fdisk -l bone-debian-7.5-2015-01-14-beaglebone.img
Disk bone-debian-7.5-2015-01-14-beaglebone.img: 3.7 GiB, 3965190144 bytes, 7744512 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: 0x00000000

Device                                     Boot     Start       End  Blocks  Id System
bone-debian-7.5-2015-01-14-beaglebone.img1 *         2048    198655   98304   e W95 FAT16 (LBA)
bone-debian-7.5-2015-01-14-beaglebone.img2         198656   3481599 1641472  83 Linux

$ sudo mount -t vfat -o loop,offset=1048576,ro bone-debian-7.5-2015-01-14-beaglebone.img /mnt

Where

offset = Block size from 'Units' x Fdisk 'Start' column

In my example fdisk is saying start at 2048 * 512 block size = 1048576.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .