[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: UEFI/"BIOS" booting


i wrote:
> > - Compromise is to set the boot flag on a dummy partition of type 0x00.
> >    This is barely UEFI-compliant because the specs say that a partition of
> >    type 0x00 shall be regarded as non-existent.

Pascal Hambourg wrote:
> - I had to use the old fdisk version from Wheezy because newer versions and
> other partition editors would not allow to set the boot flag on an empty
> partition entry.

You never know what kind of user-friendly abstraction a partition editor will
apply. So portable and future-safe is only the manipulation on byte level.

The layout of the MBR partition table can be learned from
  "Structure of a classical generic MBR" 

Partition entries are 16 bytes of size and number 1 begins at offset 446.
The boot/active flag sits in the first byte of the partition entry.
The value of this byte is either 0 or 128 (= 0x80 in hex). We want 128.
Further we need to write values for partition start and size.

  # Choose target disk or image file

  # Make a backup of your MBR by
  backup_path="$HOME"/mbr_backup_of_"$(basename "$disk")"
  dd if="$disk" bs=512 count=1 conv=notrunc of="$backup_path"

  # Restore the backup to $disk would be done like this:
  #   dd if="$backup_path" bs=512 count=1 conv=notrunc of="$disk"
  # If $disk is the system disk: Have a rescue system ready which can
  # access the backup file and the system disk.

  # Choose partition and compute start of its entry
  offset=$(expr 430 + "$partno" '*' 16)

  # First set the partition entry to all zeros. So we can just hop over
  # those bytes which shall stay 0. This spares us the plight to handle
  # 0-bytes by shell commands.
  dd if=/dev/zero bs=1 count=16 conv=notrunc seek="$offset" of="$disk"

  # The boot/active flag
  # (The gesture $'\xHH' is described in man bash section QUOTING.)
  echo -n $'\x80' | dd bs=1 count=1 conv=notrunc seek="$offset" of="$disk"

  # Start C/H/S = 0/0/1
  offset=$(expr "$offset" + 2)
  echo -n $'\x01' | dd bs=1 count=1 conv=notrunc seek="$offset" of="$disk"

  # End C/H/S = 0/0/1
  offset=$(expr "$offset" + 4)
  echo -n $'\x01' | dd bs=1 count=1 conv=notrunc seek="$offset" of="$disk"

  # Sector count = 1 (start LBA is 0)
  offset=$(expr "$offset" + 6)
  echo -n $'\x01' | dd bs=1 count=1 conv=notrunc seek="$offset" of="$disk"

The task would also be a good execercise for Programmer's First C Program.

Have a nice day :)


Reply to: