aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/grubimg_to_blockdevice.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/grubimg_to_blockdevice.sh')
-rwxr-xr-xscripts/grubimg_to_blockdevice.sh68
1 files changed, 68 insertions, 0 deletions
diff --git a/scripts/grubimg_to_blockdevice.sh b/scripts/grubimg_to_blockdevice.sh
new file mode 100755
index 0000000..79bb99e
--- /dev/null
+++ b/scripts/grubimg_to_blockdevice.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+#
+# GRUB Images
+# ============
+# Images (stages) holding the boot-code are stored in the following spaces:
+#
+# * [ 0 - 445] 446 bytes 1st image within MBR
+# * [446 - 511] 66 bytes partition table and signature (2 bytes)
+# * [512 - xxxxx] ~64 kB 2nd image(s+) between MBR and first partition (MBR gap)
+#
+# MBR Total Size
+# ================
+#
+# * 446 + 64 + 2 = 512
+#
+# using
+#
+# * 446 bytes – boot code
+# * 64 bytes – partition table
+# * 2 bytes – signature (??)
+#
+
+minimum() {
+ if [ $1 -lt $2 ]; then
+ echo -n $1
+ else
+ echo -n $2
+ fi
+}
+
+if [ -z "${1}" -o -z "${2}" ]; then
+ echo "Usage: $0 <grub-image-file> <block-device (not partition)>"
+ exit 2
+fi
+
+readonly SIZE_MBR=512
+readonly SIZE_IMG1=446
+# 1MiB min MBR gap recommended
+readonly let MIN_IMG2_SIZE=$((1024 * 1024))
+
+IMG_FILE="${1}"
+BLK_DEV="${2}"
+
+PARTED_OUT=`parted -s -m "${BLK_DEV}" unit B print`
+PART_NO=1
+PART_START=`echo "${PARTED_OUT}" | grep "^${PART_NO}:" | awk -F: ' { print substr($2,1,length($2)-1) } '`
+let SIZE_DEV=${PART_START}
+
+SIZE_IMG_FILE=`du -b ${IMG_FILE} | awk ' { print $1 }'`
+
+SIZE_IMG_MAX=$(minimum ${SIZE_DEV} ${SIZE_IMG_FILE})
+
+echo "Using size ${SIZE_IMG_MAX}, having image size ${SIZE_IMG_FILE} and device size ${SIZE_DEV} all in bytes."
+
+let SIZE_IMG2=${SIZE_IMG_MAX}-${SIZE_MBR}
+if [ ${SIZE_IMG2} -lt ${MIN_IMG2_SIZE} ]; then
+ echo "Available MBR gap for image2 ${SIZE_IMG2} < recommended ${MIN_IMG2_SIZE}, abort."
+ exit 2
+fi
+
+echo "Storing first 446 bytes from ${IMG_FILE} to start of ${BLK_DEV}."
+dd if=${IMG_FILE} of=${BLK_DEV} bs=4M count=${SIZE_IMG1} conv=notrunc iflag=count_bytes,skip_bytes oflag=seek_bytes,dsync
+
+echo "Storing ${SIZE_IMG2} bytes from ${IMG_FILE} starting at ${SIZE_MBR} to ${BLK_DEV} starting at ${SIZE_MBR}."
+dd if=${IMG_FILE} of=${BLK_DEV} bs=4M count=${SIZE_IMG2} skip=${SIZE_MBR} seek=${SIZE_MBR} conv=notrunc iflag=count_bytes,skip_bytes oflag=seek_bytes,dsync
+sync
+