Linux – What steps am I missing in the attempt to create bootable Linux distribution image

bootloaderdddisk-imagelinuxpartitioning

I am trying to create a distribution image (via Linux’s dd command) for an OS that will work with hard drives and flash media. I have been successful at creating the image, but I can’t get it to boot properly. I will layout of steps below:

  1. This creates a blank file to contain the entire image:

    dd if=/dev/zero of=/tmp/test.img bs=512 count=1250000
    
  2. Associates a loopback device file with the image file:

    losetup /dev/loop0 /tmp/test.img
    
  3. Before we can manipulate with parted we MUST define a media label type:

    parted -s /dev/loop0 mklabel msdos
    
  4. Make the first partition 512MB within the image file:

    parted -s -a opt /dev/loop0 mkpart primary ext2 '0%' 512MB
    
  5. Set the first partition as being “bootable”:

    parted -s /dev/loop0 set 1 boot on
    
  6. Creates an Ext2 filesystem on the first partition:

    mkfs.ext2 -b 1024 /dev/loop0p1
    
  7. Installs the stage1 of grub’s bootstrap code while preserving the partition table created above:

    dd if=/boot/grub/stage1 of=/dev/loop0 bs=446 count=1
    
  8. Installs the stage2 of grub’s bootstrap code after the first 512 bytes of the media (skipping the stage1 and partition table):

    dd if=/boot/grub/stage2 of=/dev/loop0 bs=512 seek=1
    
  9. Mount the first partition of the image file to a mount point:

    mount /dev/loop0p1 /mnt/image
    
  10. Copy all the data into the partition and umount.

  11. dd the image file to any hard drive or flash media.

Using these steps I can dd the image file to a hard drive or flash drive and boot into a grub legacy console where I can boot, but only by specifying the root, kernel, and initrd values. If I try to install grub legacy via root and setup commands, I get no errors but the device boots to gibberish. Running and fdisk -l produces:

Partition 1 has different physical/logical beginnings (non-Linux?):
phys(0,32,33) logical(0,37,14)
Partition 1 has different physical/logical endings:
phys(62,53,55) logical(336,27,19)

I think there is a problem with the way the image file is being created since it is responsible for the creation of the (messed up) partition table. Is anyone able to use these (modified) steps in order to produce a working bootable media?

Best Answer

  1. Make the first partition 512MB within the image file

    parted -s -a opt /dev/loop0 mkpart primary ext2 '0%' 512MB

In step #4 you use a utility to modify the first entry of the Partition Table, which is at the end of sector/block that also contains the bootloader of the MBR.

  1. Installs the stage1 of grub’s bootstrap code while preserving the partition table created above:

    dd if=/boot/grub/stage1 of=/dev/loop0 bs=446 count=1

In step #7 you try to install the bootloader into the first sector/block, which already contains a vailid Partition Table.
But dd is a block-transfer utility, that reads blocks from the source, and writes those blocks to the destination.

In this case the destination device is a HDD or SSD, that is presumably based on 512-(or 4096)-byte sectors. A read or write operation to a block device must be for the entire sector.
When a "short" write of only 446 bytes is attempted, the disk controller (or the OS) will oblige, but append 66 (or 3650) bytes of zeroes to pad out the sector to its proper/full length.
A block write is simply not intended for partial modification of the sector and preservation of the "unwritten portion".

This write operation, therefore, will overwite the previously installed Partition Table.

The simple solution is to perform step #7 before step #4. That will write the entire MBR sector with an empty Partition Table, and then edit just one entry.

Related Question