blob: b139529e9a02abccee5c5fb13b65c0b581ac8a5b [file] [log] [blame]
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
# Script to generate kernelefi.img and shimefi.img.
#
# kernelefi.img uses a kernel from cos-125-19216-104-133 and shimefi.img uses a
# shim from the same COS image.
if [[ $# -ne 2 ]]; then
echo "Usage: $0 <output_image_path> <bootx64_efi_source>"
exit 1
fi
readonly OUTPUT_IMAGE="$1"
readonly BOOT_SOURCE="$2"
readonly EFI_PART_IMAGE="efi_part.img"
# 1. Calculate required size for the partition
SOURCE_SIZE=$(stat -c%s "$BOOT_SOURCE")
# Add overhead for FAT metadata (at least 512KB for small files, total min 1MB)
EFI_SIZE_BYTES=$((SOURCE_SIZE + 512 * 1024))
if [[ $EFI_SIZE_BYTES -lt $((1024 * 1024)) ]]; then
EFI_SIZE_BYTES=$((1024 * 1024))
fi
# Align partition size to 512-byte sectors
PART_SIZE_SECTORS=$(( (EFI_SIZE_BYTES + 511) / 512 ))
# 2. Create the FAT image
truncate -s "$((PART_SIZE_SECTORS * 512))" "$EFI_PART_IMAGE"
mkfs.vfat "$EFI_PART_IMAGE"
# 3. Create directory structure and copy the EFI file
mmd -i "$EFI_PART_IMAGE" ::/efi
mmd -i "$EFI_PART_IMAGE" ::/efi/boot
mcopy -i "$EFI_PART_IMAGE" "$BOOT_SOURCE" ::/efi/boot/bootx64.efi
# 4. Define GPT layout
# Start at sector 2048 (1MiB) for alignment compatibility and to avoid
# "sector already used" errors with some versions of sfdisk.
readonly START_SECTOR=2048
# Backup GPT is 33 sectors at the end
TOTAL_SECTORS=$(( START_SECTOR + PART_SIZE_SECTORS + 33 ))
# 5. Create the final container
truncate -s "$((TOTAL_SECTORS * 512))" "$OUTPUT_IMAGE"
# 6. Initialize GPT and create the EFI partition
# EFI System Partition GUID: C12A7328-F81F-11D2-BA4B-00A0C93EC93B
echo "label: gpt
start=${START_SECTOR}, size=${PART_SIZE_SECTORS}, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name=\"EFI-SYSTEM\"" | sfdisk "$OUTPUT_IMAGE"
# 7. DD the EFI partition into the GPT image
dd if="$EFI_PART_IMAGE" of="$OUTPUT_IMAGE" bs=512 seek="${START_SECTOR}" conv=notrunc status=none
# Cleanup
rm "$EFI_PART_IMAGE"
echo "Successfully created minimal GPT image: $OUTPUT_IMAGE ($((TOTAL_SECTORS * 512 / 1024)) KiB)"