diff options
author | Sven Gothel <[email protected]> | 2021-07-18 06:59:45 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2021-07-18 06:59:45 +0200 |
commit | 5111cc860bc750902f8e374c267c671292bcb98f (patch) | |
tree | 3323320233d5d29620f54211652f648f314a83fa | |
parent | b492216fa0cc7e4f5005028335258cec4bb3e89b (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.bin | bin | 0 -> 4194304 bytes | |||
-rwxr-xr-x | scripts/grubimg_to_blockdevice.sh | 68 | ||||
-rwxr-xr-x | scripts/grubimg_to_file.sh | 50 | ||||
-rwxr-xr-x | scripts/make_dualboot_image.sh | 61 |
4 files changed, 179 insertions, 0 deletions
diff --git a/data/grub-image01.bin b/data/grub-image01.bin Binary files differnew file mode 100644 index 0000000..5b3f6b9 --- /dev/null +++ b/data/grub-image01.bin 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." + |