0

Suppose that an iso disk image is hidden in an unallocated free space on a disk. Note that, because it is hidden in an unallocated space, it is not recognizable to the filesystem. Assuming that the exact location and size of the image are given, how can the image be mounted?

I would like two different solutions. One solution is for the situation where the disk holding the image is write-protected* and hence the partition table on the disk cannot be modified or created.

Another solution is to modify the partition table on the disk, assuming that the disk holding the image is writable, and that the first several gigabytes on the disk holds the bootable isohybrid image of Debian installation DVD-1 of version 9.2.1 for amd64.

Note that the following is NOT what I want: using the dd command to copy the image from the hidden space into an allocated space so that the resultant duplicate image be a regular file visible to a filesystem, and then mounting the resultant image file. I want to mount the image directly from where the image is already stored.

This question has arisen from the following situation. The installer of Debian 9.2.1 comes in a set of three DVDs. DVD-1 is a bootable isohybrid image, and hence the image makes a USB stick bootable when it is burnt to the USB stick, as well as it can make a DVD bootable. I definitely prefer USB sticks to DVDs. DVD-2 and DVD-3 are normal DVD images and not bootable. Considering the sizes of these images and the sizes of USB sticks available on the market these days, it is most desirable to put all the three DVD images to one 16 GB USB stick.

DVD-1  3.7GiB  4GB
DVD-2  4.3GiB  4.65GB
DVD-3  4.4GiB  4.7GB

These days, USB sticks are either 8 GB, 16 GB, 32 GB or 64 GB. Note that a USB stick is also called a USB flash drive or USB memory.

By the dd command (or cp), the DVD-1 image must be burnt to the USB stick, starting at the sector 0 of the USB stick, which results in a 4GB partition on the USB stick, and leaves 12 GB of unallocated free space on the USB stick. By dd, DVD-2 and DVD-3 can be written into this unallocated space, which will be kept hidden from the filesystem.

The following bash script, as it downloads the three DVD images of Debian 9.2.1 for amd64, burns the images directly to /dev/sdb, which is usually a USB stick, and, after the completion of the writing, reads the resultant images to calculate the checksums in sha1, sha256 and sha512. The USB stick becomes bootable as DVD-1, assuming that the USB stick is /dev/sdb. The DVD-2 and DVD-3 will be stored in the unallocated free space, and invisible to the filesystem.

Warning: This script overwrites the disk whose device name is /dev/sdb, and the existing data on the disk will be destroyed. Therefore, newbies should stay away from this script, to avoid accidental erasure of important data.

Preparation:

curl, dd and openssl must already be installed. (curl downloads, dd writes the disk image to the USB stick, and openssl calculates the checksums. Every Mac OS X comes with curl. Some distros of Linux come with curl, but other distros do not. As for Debian 9.2.1, curl comes with DVD-2.) openssl must be capable of not only sha1 but also sha256 and sha512.

The USB stick must be unmounted but still attached and not ejected.

The device name /dev/sdb is passed to the dd command. If the device name of the USB stick to which the DVD images are to be burnt is not /dev/sdb, then modify the script, replacing /dev/sdb with the correct device name. On Linux, the boot disk is usually /dev/sda, and data disks are usually /dev/sdb, /dev/sdc, /dev/sdd and so on. On Mac OS X, the boot disk is usually /dev/disk0, and data disks are usually /dev/disk1, /dev/disk2, /dev/disk3 and so on.

To find the device name on Linux, parted -l is useful. To find the device name on MacOSX, do diskutil list and Disk Utility > Info > Disk Identifier.

This script passes dd 4K as the block size, where the suffix K (kilo) indicates 1024 bytes. The dd on Mac OS X expects a lowercase k instead of uppercase K. Thus, to run this script on Mac OS X, you need to replace K with k.

This script downloads the DVD images from cdimage.debian.org, which may be slow if you are far away from it. You might want to replace it with a mirror close to you.

#!/bin/bash

par="https://cdimage.debian.org/debian-cd/9.2.1/amd64/iso-dvd/"
    # par for the parent directory of the DVD images on the server.

ua='Mozilla/5.0 ()'  # UserAgent string to be used by curl.

vAry=()  # an array to hold the number of 4K-blocks, which is obtained
         # as the file size of the DVD image divided by 4096,
         # for each of the three DVD images.


# HTTP header
echo "Reading the HTTP header to obtain the file size"
for (( i = 1 ; i <= 3 ; i++ )) ; do
  f="debian-9.2.1-amd64-DVD-${i}.iso"
  url="$par$f"
  header=$(curl -ILRA "$ua" "$url") # HTTP header
  echo "$header"
  nBytes=$(echo "$header" | grep -E 'Content-Length: [1-9][0-9]*' | grep -oE '[1-9][0-9]*')
     # nBytes is the file size in bytes

  if [[ -z $nBytes ]]; then
    echo "${f}:  curl failed. Aborting..."
    exit 1 #@@@@@@@@@@@@@@@@@@@@@@@@@@@
  elif [[ $((nBytes%4096)) -ne 0 ]]; then
    echo "${f}:  nBytes is not divisible by 4096. Aborting..."
    exit 1 #@@@@@@@@@@@@@@@@@@@@@@@@@@@
  fi
  ((nBlk=nBytes/4096)) # the number of 4K-blocks
  vAry+=($nBlk)
  echo "$f   $nBytes   $nBlk"
  echo "${vAry[@]}"
  printf %b '----------------------------------------\n\n\n'
done


if [[ ${#vAry[@]} -eq 0 ]] # the number of elements of the array
then
  echo "The array of nBlk's is empty. Aborting..."
  exit 1 #@@@@@@@@@@@@@@@@@@@@@@@@@@@
fi

printf %b '========================================\n\n\n'

# The file sizes of DVD-1, DVD-2 and DVD-3 of Debian 9.2.1 for amd64 are
# supposed to be 3964551168, 4649189376 and 4692422656 bytes respectively,
# and the number of 4K-blocks to be 967908, 1135056 and 1145611.
# If this is the case, vAry should be (967908 1135056 1145611).


# Download
echo "Downloading to the USB stick"
unset nBlk
i=1; sk=0; for nBlk in "${vAry[@]}" ; do
  f="debian-9.2.1-amd64-DVD-${i}.iso"
  url="$par$f"
  echo "$f   $nBlk   $sk"
  curl -LRA "$ua" "$url" | dd bs=4K seek=$sk of=/dev/sdb ; sync
  ((i++))
  ((sk+=nBlk))
  printf %b '--------------------\n\n\n'
done

printf %b '========================================\n\n\n'


# Checksum
echo "Reading from the USB stick to calculate the checksum"
i=1; sk=0; for nBlk in "${vAry[@]}" ; do
  f="debian-9.2.1-amd64-DVD-${i}.iso"
  echo "$f   $sk   $nBlk"
  dd bs=4K skip=$sk count=$nBlk if=/dev/sdb | tee >(openssl sha256 | perl -pe 's/^(\(stdin\)= )?/# sha256: /' >&2) >(openssl sha1 | perl -pe 's/^(\(stdin\)= )?/# sha1: /' >&2) | openssl sha512 | perl -pe 's/^(\(stdin\)= )?/# sha512: /'
  ((i++))
  ((sk+=nBlk))
  printf %b '--------------------\n\n\n'
done

After the script has written the DVD images (of Debian 9.2.1 for amd64) into the USB stick, DVD-1 occupies 3964551168 bytes from the Byte 0, and DVD-2 occupies 4649189376 bytes from the Byte 3964551168, and DVD-3 occupies 4692422656 bytes from the Byte 8613740544, where 8613740544 = 3964551168+4649189376. The three images are stored contiguously. The USB stick is bootable and recognized as DVD-1, while DVD-2 and DVD-3 are invisible to the filesystem.

How can the hidden images DVD-2 and DVD-3 be mounted?

I would like two different solutions.

(1) One solution is for the situation where the USB stick is write-protected* and hence the partition table on the disk cannot be modified or created.

(2) Another solution is to tweak the partition table on the USB stick so that DVD-2 and DVD-3 will be recognized as independent partitions separate from the partition holding DVD-1. Or, instead of creating two extra partitions, expand the partition holding DVD-1 large enough to hold DVD-2 and DVD-3, and let the filesystem recognize DVD-2 and DVD-3 as regular iso files.

If the contiguity of the three images hinders (2) and if it is better to make some room for partition headers between the images, then I can modify the script so that there will be some room between the images.

* write-protected: Most USB sticks lack write-protection tabs. However, every SD card has a write-protection tab. A USB SD card reader/writer holding an SD card looks like a USB stick, and actually works as a USB stick, plus the capability of write-protection.

2

This is a very long question and I can't claim to have read to the end.

For a solution which does not edit the disk:

Basically what you are describing is a disk partition which is not listed in the disk's partiotn table.

When you plug in a disk and linux assigns it a device in /dev such as /dev/sda. Linux reads the partition table and also adds a device for each partition such as /dev/sda1/.

It's actually possible to manually add partitions that are not setup automatically. This doesn't add them to the disk's partition table, just to the kernel's table.

Look for the addpart menthod https://linux.die.net/man/8/addpart


For a solution which edits the disk. You just need to add a partition in the correct place on the disk (from the offset for the correct size). There are bunch of different programs which will edit the table. Such as fdisk. If you use something other than fdisk then be very careful not to farmat the partition as you create it. This will only write the partition table and not edit any of the data.

https://linux.die.net/man/8/fdisk

1

When mounting a loop device the offset and size can be specified. Eg

sudo mount -r /dev/sdb /mnt/dvd2 -o loop,offset=3964551168,sizelimit=4649189376

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.