Last active
October 1, 2022 23:58
-
-
Save gustingonzalez/d92338c63396f0a34b01d9da781735cb to your computer and use it in GitHub Desktop.
Generates an EFI unified kernel image based on a systemd stub
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Generates an EFI image based on a systemd stub. | |
OUTPUT_PATH=$1 | |
OSREL_PATH=$2 | |
CMDLINE_PATH=$3 | |
SPLASH_PATH=$4 | |
INITRD_PATH=$5 | |
LINUX_PATH=$6 | |
# List of components that must be placed into the image. Each pair of items | |
# refers to the name of the component and its associated path. IMPORTANT: these | |
# components will be incorporated in the order in which they appear here! The | |
# arrangement of each one is based on the comments in the following commit: | |
# https://github.com/systemd/systemd/commit/0fa2cac4f0cdefaf1addd7f1fe0fd8113db9360b. | |
ORDERED_EFI_ITEMS=( | |
"osrel" $OSREL_PATH | |
"cmdline" $CMDLINE_PATH | |
"splash" $SPLASH_PATH | |
"initrd" $INITRD_PATH | |
"linux" $LINUX_PATH | |
) | |
# systemd stub, used to build the image. | |
STUB=/usr/lib/systemd/boot/efi/linuxx64.efi.stub | |
# Based on the stub, computes the placement of the first EFI component. | |
LAST_STUB_COMPONENT_INFO=$(objdump -h $STUB | tail -2 | head -1) | |
LAST_STUB_COMPONENT_SIZE=0x$(echo "$LAST_STUB_COMPONENT_INFO" | awk '{print $3}') | |
LAST_STUB_COMPONENT_OFFSET=0x$(echo "$LAST_STUB_COMPONENT_INFO" | awk '{print $4}') | |
START_OFFSET=$(($LAST_STUB_COMPONENT_OFFSET + $LAST_STUB_COMPONENT_SIZE)) | |
curr_offset=$START_OFFSET | |
for ((efi_item_number=0; efi_item_number<${#ORDERED_EFI_ITEMS[@]}; efi_item_number+=2)) ; do | |
efi_component_name=${ORDERED_EFI_ITEMS[$efi_item_number]} | |
efi_component_file=${ORDERED_EFI_ITEMS[$efi_item_number+1]} | |
# Creates a variable storing the offset (in hexa) of the current component. | |
# Its name is assigned based on the name of the latter. E.g., the variable | |
# indicating the 'linux' offset will be named 'linux_offset'. | |
declare "$efi_component_name"_offset=0x$(printf "%x\n" $curr_offset) | |
echo "The component '$efi_component_name' ('$efi_component_file') has been asigned to the section $curr_offset." | |
# Recalculates the offset to be used in the next component. | |
efi_component_size=$(stat -c%s $efi_component_file) | |
curr_offset=$(($curr_offset + $efi_component_size)) | |
done | |
# Builds the EFI image with the specified stub and components. | |
objcopy \ | |
--add-section .osrel=$OSREL_PATH --change-section-vma .osrel=$osrel_offset \ | |
--add-section .cmdline=$CMDLINE_PATH --change-section-vma .cmdline=$cmdline_offset \ | |
--add-section .splash=$SPLASH_PATH --change-section-vma .splash=$splash_offset \ | |
--add-section .initrd=$INITRD_PATH --change-section-vma .initrd=$initrd_offset \ | |
--add-section .linux=$LINUX_PATH --change-section-vma .linux=$linux_offset \ | |
$STUB $OUTPUT_PATH |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example of usage:
create-systemd-efi-image.sh BOOTx64.efi os-release.txt cmdline.txt splash.bmp initrd.lz vmlinuz