Live Scan Grub Menu
lsgm.rwx.work
1#! /usr/bin/env bash
2[ "${2}" ] || exit 1
3FILE="$(realpath "${BASH_SOURCE[0]}")"
4SCRIPT="$(basename "${FILE}")"
5ROOT="$(dirname "${FILE}")"
6PROJECT="$(basename "${ROOT}")"
7
8PGP_PUB="${1}"
9ESP_ROOT="${2}"
10DATA_ROOT="${3}"
11
12function get_path_mount {
13 stat --format '%m' "${1}"
14}
15function get_mount_uuid {
16 findmnt --noheadings --output 'UUID' "${1}"
17}
18function get_path_uuid {
19 local tmp="$(get_path_mount "${1}/")"
20 get_mount_uuid "${tmp}"
21}
22ESP="$(get_path_uuid "${ESP_ROOT}")"
23if [ "${DATA_ROOT}" ] ; then
24 DATA="$(get_path_uuid "${DATA_ROOT}")"
25else
26 DATA="${ESP}"
27fi
28
29function sign {
30 if [ -d "${1}" ] ; then
31 local file
32 local files
33 readarray -t files <<< "$(find "${1}" -type f | sort)"
34 echo
35 echo "${1}"
36 for file in "${files[@]}" ; do
37 sign "${file}" "${1}"
38 done
39 fi
40 if [ -f "${1}" ] ; then
41 if [ "${2}" ] ; then
42 echo "$(realpath --relative-to "${2}" "${1}")"
43 else
44 echo "${1}"
45 fi
46 gpg \
47 --quiet \
48 --default-key "${PGP_PUB}!" \
49 --detach-sign \
50 "${1}"
51 fi
52}
53
54# imports ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
55
56source "${ROOT}/${SCRIPT%.*}.mod"
57
58# constants ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
59
60BIOS_BOOT='/usr/lib/grub/i386-pc/boot.img'
61COMPRESSION='xz'
62GRUB_HEAD='# GRUB Environment Block'
63SIGNED_GRUB='/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed'
64SIGNED_SHIM='/usr/lib/shim/shimx64.efi.signed'
65SIGNED_ARM_GRUB='/usr/lib/grub/arm64-efi-signed/grubaa64.efi.signed'
66ARM_SHIM='/usr/lib/shim/shimaa64.efi.signed'
67
68# variables ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
69
70MEMDISK_ROOT="${ESP_ROOT}/memdisk"
71MEMDISK_DIRECTORY="${MEMDISK_ROOT}/grub"
72MEMDISK_FILE="${MEMDISK_DIRECTORY}/grub.cfg"
73MEMDISK_FONTS="${MEMDISK_DIRECTORY}/fonts"
74MEMDISK_ARCHIVE="${MEMDISK_ROOT}/grub.tar"
75
76UEFI_ROOT="${ESP_ROOT}/efi"
77UEFI_DIRECTORY="${UEFI_ROOT}/boot"
78UEFI_CORE="${UEFI_DIRECTORY}/corex64.efi"
79UEFI_FILE="${UEFI_DIRECTORY}/bootx64.efi"
80UEFI_GRUB="${UEFI_DIRECTORY}/grubx64.efi"
81ARM_CORE="${UEFI_DIRECTORY}/coreaa64.efi"
82ARM_FILE="${UEFI_DIRECTORY}/bootaa64.efi"
83ARM_GRUB="${UEFI_DIRECTORY}/grubaa64.efi"
84
85BIOS_ROOT="${ESP_ROOT}/bios"
86BIOS_FILE="${BIOS_ROOT}/core.img"
87BIOS_SETUP="${BIOS_ROOT}/setup.sh"
88
89BOOT_ROOT="${ESP_ROOT}/boot"
90
91GRUB_CFG_SH="${ROOT}/grub.cfg.sh"
92GRUB_SHIGNED="${ROOT}/grubx64.efi.signed.sh"
93
94GRUB_ROOT="${BOOT_ROOT}/grub"
95GRUB_CFG="${GRUB_ROOT}/grub.cfg"
96GRUBENV="${GRUB_ROOT}/grubenv"
97GRUB_FONTS="${GRUB_ROOT}/fonts"
98GRUB_LOCALES="${GRUB_ROOT}/locale"
99GRUB_PUB="${GRUB_ROOT}/grub.pgp"
100GRUB_THEMES="${GRUB_ROOT}/themes"
101
102GRUB_ENV="${ESP_ROOT}/grub.env"
103
104LIVE_ROOT="${BOOT_ROOT}/${PROJECT}"
105
106# wipe ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
107
108echo -n "
109→ ${BOOT_ROOT}
110→ ${MEMDISK_ROOT}
111→ ${UEFI_ROOT}
112→ ${BIOS_ROOT}
113"
114rm --force --recursive \
115"${BOOT_ROOT}" "${MEMDISK_ROOT}" "${UEFI_ROOT}" "${BIOS_ROOT}"
116
117# memdisk ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
118
119echo -n "
120→ ${MEMDISK_FONTS}
121"
122mkdir --parents "${MEMDISK_FONTS}"
123
124echo -n "
125→ ${MEMDISK_FILE}
126"
127echo "\
128echo \"prefix | \${prefix}\"
129search --no-floppy --set root --fs-uuid '${ESP}'
130prefix=\"(\${root})/boot/grub\"
131echo \"prefix | \${prefix}\"
132" > "${MEMDISK_FILE}"
133echo -n "
134↙ ${GRUB_SHIGNED}
135↘ ${MEMDISK_FILE}
136"
137cat "${GRUB_SHIGNED}" >> "${MEMDISK_FILE}"
138
139echo -n "
140↙ ${MEMDISK_DIRECTORY}
141↘ ${MEMDISK_ARCHIVE}
142"
143cd "${MEMDISK_DIRECTORY}"
144tar --create --auto-compress \
145--file "${MEMDISK_ARCHIVE}" 'grub.cfg'
146cd -
147
148# uefi ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
149
150echo -n "
151→ ${UEFI_DIRECTORY}
152"
153mkdir --parents "${UEFI_DIRECTORY}"
154
155echo -n "
156↙ ${MEMDISK_ARCHIVE}
157↘ ${UEFI_FILE}
158"
159grub-mkimage \
160--compress "${COMPRESSION}" \
161--memdisk "${MEMDISK_ARCHIVE}" \
162--format 'x86_64-efi' \
163--output "${UEFI_FILE}" \
164--prefix '(memdisk)/' \
165"${MODULES[@]}"
166echo -n "
167↙ ${MEMDISK_ARCHIVE}
168↘ ${ARM_FILE}
169"
170grub-mkimage \
171--compress "${COMPRESSION}" \
172--memdisk "${MEMDISK_ARCHIVE}" \
173--format 'arm64-efi' \
174--output "${ARM_FILE}" \
175--prefix '(memdisk)/' \
176"${MODULES[@]}"
177
178if [ -f "${SIGNED_SHIM}" ] ; then
179 echo -n "
180↙ ${UEFI_FILE}
181↘ ${UEFI_GRUB}
182"
183 mv "${UEFI_FILE}" "${UEFI_GRUB}"
184 echo -n "
185↙ ${SIGNED_SHIM}
186↘ ${UEFI_FILE}
187"
188 cp "${SIGNED_SHIM}" "${UEFI_FILE}"
189fi
190if [ -f "${ARM_SHIM}" ] ; then
191 echo -n "
192↙ ${ARM_FILE}
193↘ ${ARM_GRUB}
194"
195 mv "${ARM_FILE}" "${ARM_GRUB}"
196 echo -n "
197↙ ${ARM_SHIM}
198↘ ${ARM_FILE}
199"
200 cp "${ARM_SHIM}" "${ARM_FILE}"
201fi
202
203if [ -f "${SIGNED_GRUB}" ] ; then
204 echo -n "
205↙ ${UEFI_GRUB}
206↘ ${UEFI_CORE}
207"
208 mv "${UEFI_GRUB}" "${UEFI_CORE}"
209 echo -n "
210↙ ${SIGNED_GRUB}
211↘ ${UEFI_GRUB}
212"
213 cp "${SIGNED_GRUB}" "${UEFI_GRUB}"
214fi
215if [ -f "${SIGNED_ARM_GRUB}" ] ; then
216 echo -n "
217↙ ${ARM_GRUB}
218↘ ${ARM_CORE}
219"
220 mv "${ARM_GRUB}" "${ARM_CORE}"
221 echo -n "
222↙ ${SIGNED_ARM_GRUB}
223↘ ${ARM_GRUB}
224"
225 cp "${SIGNED_ARM_GRUB}" "${ARM_GRUB}"
226fi
227
228# bios ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
229
230echo -n "
231→ ${BIOS_ROOT}
232"
233mkdir "${BIOS_ROOT}"
234
235echo -n "
236↙ ${BIOS_BOOT}
237↘ ${BIOS_ROOT}
238"
239cp "${BIOS_BOOT}" "${BIOS_ROOT}"
240
241echo -n "
242↙ ${MEMDISK_ARCHIVE}
243↘ ${BIOS_FILE}
244"
245grub-mkimage \
246--compress "${COMPRESSION}" \
247--memdisk "${MEMDISK_ARCHIVE}" \
248--format 'i386-pc' \
249--output "${BIOS_FILE}" \
250--prefix '(memdisk)/' \
251"${MODULES[@]}" "${MODULES_BIOS[@]}"
252
253echo -n "
254→ ${BIOS_SETUP}
255"
256echo -n '#! /usr/bin/env bash
257FILE="$(realpath "${BASH_SOURCE[0]}")"
258DIRECTORY="$(dirname "${FILE}")"
259
260/usr/lib/grub/i386-pc/grub-bios-setup \
261--directory "${DIRECTORY}" \
262"${1}"
263' >> "${BIOS_SETUP}"
264
265# grub ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
266
267echo -n "
268→ ${GRUB_ROOT}
269"
270mkdir --parents "${GRUB_ROOT}"
271
272# grub / cfg ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
273
274echo -n "
275↙ ${GRUB_CFG_SH}
276↘ ${GRUB_CFG}
277"
278cp "${GRUB_CFG_SH}" "${GRUB_CFG}"
279
280# grub / env ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
281
282function write_env {
283local file="${1}"
284local kv="${2}"
285local text="${GRUB_HEAD}
286${kv}"
287 while [ ${#text} -lt 1024 ] ; do
288 text="${text}#"
289 done
290 echo -n "${text}" > "${file}"
291}
292
293echo -n "
294→ ${GRUBENV}
295→ ${GRUB_ENV}
296"
297
298write_env "${GRUBENV}" "\
299live_name=${PROJECT}
300data_uuid=${DATA}
301check_squashfs=enforce
302live_from=ram
303pause=999
304time_out=10
305"
306
307write_env "${GRUB_ENV}" "\
308"
309
310# grub / fonts ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
311
312echo -n "
313→ ${GRUB_FONTS}
314"
315mkdir --parents "${GRUB_FONTS}"
316for font in $(find '/usr/share/grub' -type 'f' -name '*.pf2') ; do
317 cp "${font}" "${GRUB_FONTS}"
318done
319
320# grub / themes ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
321
322if cd '/usr/share/grub/themes' ; then
323 echo -n "
324→ ${GRUB_THEMES}
325"
326 mkdir --parents "${GRUB_THEMES}"
327 for theme in * ; do
328 if [ -f "${theme}/theme.txt" ] ; then
329 cp --recursive "${theme}" "${GRUB_THEMES}"
330 fi
331 done
332 cd -
333fi
334
335# grub / locales ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
336
337echo -n "
338→ ${GRUB_LOCALES}
339"
340mkdir --parents "${GRUB_LOCALES}"
341if cd '/usr/share/locale' ; then
342 for locale in * ; do
343 file="${locale}/LC_MESSAGES/grub.mo"
344 if [ -f "${file}" ] ; then
345 cp "${file}" "${GRUB_LOCALES}/${locale}.mo"
346 fi
347 done
348 cd -
349fi
350
351# grub / pubkey ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
352
353echo -n "
354↙ ${PGP_PUB}
355↘ ${GRUB_PUB}
356"
357gpg --export "${PGP_PUB}" > "${GRUB_PUB}"
358
359# grub / modules ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
360
361for target in 'x86_64-efi' 'i386-pc' 'arm64-efi' ; do
362 echo -n "
363↙ /usr/lib/grub/${target}
364↘ ${GRUB_ROOT}/${target}
365"
366 if cd "/usr/lib/grub/${target}" ; then
367 mkdir --parents "${GRUB_ROOT}/${target}"
368 for module in *.lst *.mod ; do
369 cp "${module}" "${GRUB_ROOT}/${target}"
370 done
371 cd -
372 fi
373done
374
375# project ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
376
377cp --recursive "${ROOT}/live" "${LIVE_ROOT}"
378
379# sign ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
380
381sign "${BIOS_ROOT}"
382sign "${UEFI_ROOT}"
383sign "${LIVE_ROOT}"
384sign "${GRUB_ROOT}"
385
386# display ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
387
388echo
389du --human-readable --summarize \
390"${BIOS_ROOT}" \
391"${UEFI_ROOT}" \
392"${LIVE_ROOT}" \
393"${GRUB_ROOT}" \
394"${ESP_ROOT}/"
395echo -n "
396 ESP: ${ESP}
397DATA: ${DATA}
398"
399
400# clean ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
401
402rm --force --recursive "${MEMDISK_ROOT}"