55

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

61

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
  • 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
5

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.

3
  • 1
    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 at 11:25
4

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 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.