aboutsummarylogtreecommitdiffstats
path: root/efistub
blob: 10c7bf6fb22da30633825298f891097b164ecf83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/bin/bash

# help message
HELP_MESSAGE="Build a bootable unified EFI kernel image

Usage: efistub [CONFIG_FILE_PATH] 
 CONFIG_FILE_PATH (optional) Path to custom config, defaults to /etc/efistub.conf

Config file variables:
 EFISTUB_LINUX       Path to kernel, defaults to /boot/vmlinuz-linux
 EFISTUB_INITRDS     An array of paths for initrd images to be included
 EFISTUB_CMDLINE     Kernel command line string
 EFISTUB_OS_RELEASE  OS release string to embed into the EFI image, defaults to the contents of /etc/os-release
 EFISTUB_UNAME       UNAME string to embed into the EFI image, defaults to the result of 'uname -a'
 EFISTUB_STUB        EFI stub base, defaults to /usr/lib/systemd/boot/efi/linuxx64.efi.stub 
 EFISTUB_DEST        Where to write the complete EFI image
"

CONFIG_FILE="/etc/efistub.conf"
UKIFY_BIN=/usr/lib/systemd/ukify

# ensure required commands are present
declare -a CMDS=("$UKIFY_BIN")
for cmd in "${CMDS[@]}"; do
 if ! command -v $cmd &> /dev/null; then
  printf '%s is requried to run this script!\n' "$cmd"
  exit -1
 fi
done
unset CMDS

# utility to check whether the last command failed
check_failed() {
 local exit_code=$?

 if [[ $exit_code -eq 0 ]]; then
  return 0
 fi

 # $1 fmt string, $2 args (optional)
 local msg="$(printf "$1" "$2"; printf TERMINATOR)"
 msg="${msg%TERMINATOR}"

 printf "$msg" >&2
 exit $exit_code
}

# print help and exit
help_and_exit() {
 # $1 fmt string, $2 args (optional)
 local msg="$(printf "$1" "$2"; printf TERMINATOR)"
 msg="${msg%TERMINATOR}"

 # $3 exit code (optional)
 local exit_code=${3:--1}

 printf "$HELP_MESSAGE"
 printf "$msg" >&2
 exit $exit_code
}

# only print help and exit if the last command failed
help_and_exit_if_failed() {
 local exit_code=$?
 if [[ $? -ne 0 ]]; then
  help_and_exit "$@" $exit_code
 fi
}

# source kernel config file (defaults below)
EFISTUB_LINUX="/boot/vmlinuz-linux"
EFISTUB_INITRDS=
EFISTUB_CMDLINE=
EFISTUB_OS_RELEASE="@/etc/os-release"
EFISTUB_UNAME="$(uname -a)"
EFISTUB_STUB="/usr/lib/systemd/boot/efi/linuxx64.efi.stub"
EFISTUB_DEST=

# use user-specified config, if specified 
if [[ ! -z "${1+x}" ]]; then
 CONFIG_FILE="$1"
fi

# ensure the provided config exists
if [[ ! -f "$CONFIG_FILE" ]]; then
 help_and_exit "\nERROR: Config file '%s' does not exist!\n" "$CONFIG_FILE"
fi
source "$CONFIG_FILE"
help_and_exit_if_failed "\nERROR: Failed to source configuration from '%s'!\n" "$CONFIG_FILE"

# validate loaded config
declare -a CONFIG_VARS=('EFISTUB_LINUX' 'EFISTUB_INITRDS' 'EFISTUB_CMDLINE' 'EFISTUB_OS_RELEASE' 'EFISTUB_UNAME' 'EFISTUB_STUB' 'EFISTUB_DEST')
for var in "${CONFIG_VARS[@]}"; do
 if [[ -z "${!var}" ]]; then
  help_and_exit "\nERROR: Missing '%s' configuration value!\n" "$var"
 fi
done

# add all initrds
for initrd in "${EFISTUB_INITRDS[@]}"; do
 INITRDS="${INITRDS} --initrd="$initrd""
done

# build unified efi image
$UKIFY_BIN build \
--linux="$EFISTUB_LINUX" \
--cmdline="$EFISTUB_CMDLINE" \
--os-release="$EFISTUB_OS_RELEASE" \
--uname="$EFISTUB_UNAME" \
--efi-arch=x64 \
--stub="$EFISTUB_STUB" \
--output="$EFISTUB_DEST" \
$INITRDS
check_failed "ERROR: Failed to build unified EFI image!\n"