aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2021-07-18 06:59:45 +0200
committerSven Gothel <[email protected]>2021-07-18 06:59:45 +0200
commit5111cc860bc750902f8e374c267c671292bcb98f (patch)
tree3323320233d5d29620f54211652f648f314a83fa
parentb492216fa0cc7e4f5005028335258cec4bb3e89b (diff)
multi-arch/boot: Handle GRUB boot-code images, showcase full feature via 'make_dualboot_image'
'make_dualboot_image' creates a new raw image file: - creating one vfat partition covering whole size - formating partition with vfat - provision GRUB boot-code (expecting 'grub' folder on vfat partition) - copy custom files to vfat partition using image file handling via NBD (updated imagetool.sh). The custom files are sourced from two sdcard diskimages folder generated with our pi-gen branch: - raspi arm64 - debian amd64 Simply copied both content into one merge folder, passed as last argument 'provisioning-dir' to this script. +++ Grub file handling takes care of both boot-code image locations, 446 bytes in MBR and the MBR gap from [512 bytes - partition-start[
-rw-r--r--data/grub-image01.binbin0 -> 4194304 bytes
-rwxr-xr-xscripts/grubimg_to_blockdevice.sh68
-rwxr-xr-xscripts/grubimg_to_file.sh50
-rwxr-xr-xscripts/make_dualboot_image.sh61
4 files changed, 179 insertions, 0 deletions
diff --git a/data/grub-image01.bin b/data/grub-image01.bin
new file mode 100644
index 0000000..5b3f6b9
--- /dev/null
+++ b/data/grub-image01.bin
Binary files differ
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
+
diff --git a/scripts/grubimg_to_file.sh b/scripts/grubimg_to_file.sh
new file mode 100755
index 0000000..96c9dbb
--- /dev/null
+++ b/scripts/grubimg_to_file.sh
@@ -0,0 +1,50 @@
+#!/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 (??)
+#
+
+if [ -z "${1}" -o -z "${2}" ]; then
+ echo "Usage: $0 <block-device (not partition)> <grub-image-file>"
+ exit 2
+fi
+
+readonly let SIZE_MBR=512
+readonly let SIZE_IMG1=446
+# 1MiB min MBR gap recommended
+readonly let MIN_IMG2_SIZE=$((1024 * 1024))
+
+BLK_DEV="${1}"
+IMG_FILE="${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_IMG_MAX=${PART_START}
+
+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 ${SIZE_IMG_MAX} bytes from start of ${BLK_DEV} to ${IMG_FILE}."
+dd if=${BLK_DEV} of=${IMG_FILE} bs=4M count=${SIZE_IMG_MAX} conv=notrunc iflag=count_bytes,skip_bytes oflag=seek_bytes,dsync
+sync
diff --git a/scripts/make_dualboot_image.sh b/scripts/make_dualboot_image.sh
new file mode 100755
index 0000000..d3896f8
--- /dev/null
+++ b/scripts/make_dualboot_image.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+#
+# Creates a new raw image file:
+# - creating one vfat partition covering whole size
+# - formating partition with vfat
+# - provision GRUB boot-code (expecting 'grub' folder on vfat partition)
+# - copy custom files to vfat partition
+#
+sdir=`dirname $(readlink -f "${BASH_SOURCE[0]}")`
+rootdir=`dirname $sdir`
+
+usage() {
+ echo "Usage: $0 <image-file> <total-size in GiB> <mount-point> <provisioning-dir>"
+}
+
+if [ -z "${1}" -o -z "${2}" -o -z "${3}" -o -z "${4}" ]; then
+ usage
+ exit 2
+fi
+
+readonly grub_image="data/grub-image01.bin"
+
+IMG_FILE="${1}"
+IMG_FILE_SIZE="${2}"
+MNT_DIR="${3}"
+SRC_DIR="${4}"
+
+dd if=/dev/zero of=${IMG_FILE} bs=4M count=${IMG_FILE_SIZE}G conv=notrunc iflag=count_bytes,skip_bytes oflag=seek_bytes,dsync status=progress
+
+sfdisk ${IMG_FILE} << EOF
+4MiB,,c,*;
+EOF
+sync
+
+nbd_dev=$(${rootdir}/imagetool.sh --connect-raw ${IMG_FILE})
+if [ -z "${nbd_dev}" ]; then
+ echo "No mapped nbd to image, NBD_DEV '${nbd_dev}', abort"
+ exit 2
+fi
+
+p1dev="/dev/mapper/${nbd_dev}p1"
+mkfs.fat -n BOOT -F 32 -v ${p1dev}
+sync
+
+${sdir}/grubimg_to_blockdevice.sh "${grub_image}" "/dev/${nbd_dev}"
+
+mount ${p1dev} ${MNT_DIR}
+cp -a ${SRC_DIR}/* ${MNT_DIR}/
+sync
+umount ${MNT_DIR}
+sync
+
+# just make sure ..
+fsck.vfat -V -y ${p1dev}
+fsck.vfat -V -y ${p1dev}
+
+${rootdir}/imagetool.sh --disconnect ${nbd_dev}
+
+echo "New image ${IMG_FILE} partitioned, formatted and provisioned with GRUB boot-code and custom files."
+