mkarchiso: copy all GRUB files to the ISO

Do not limit file copying to only grub.cfg and instead copy all GRUB configuration files and assets to both the ISO9660 and FAT image.
This will allow for including custom images, fonts, etc.

To easily match all non-configuration files (i.e. files without the .cfg extension), bash's extended glob feature will be enabled.
Actions common to multiple _make_bootmode_uefi-*.grub are split off into dedicated functions:

* _make_common_bootmode_grub_copy_to_efibootimg,
* _make_common_bootmode_grub_copy_to_isofs,
* _make_common_bootmode_grub_cfg.

Use the same du command in all efiboot_imgsize variable assignments.

Fixes #185.
This commit is contained in:
nl6720 2022-08-08 13:54:43 +03:00
parent 6ac2230953
commit b13e5e3379
No known key found for this signature in database
GPG Key ID: 5CE88535E188D369
2 changed files with 68 additions and 52 deletions

View File

@ -9,6 +9,7 @@ Added
-----
- Add ``efibootimg`` to ``mkarchiso`` to abstract the FAT image path.
- Copy all files from the ``grub`` directory to ISO9660 and the FAT image, not just only ``grub.cfg``.
Changed
-------

View File

@ -3,6 +3,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later
set -e -u
shopt -s extglob
# Control the environment
umask 0022
@ -529,18 +530,44 @@ _make_efibootimg() {
mmd -i "${efibootimg}" ::/EFI ::/EFI/BOOT
}
# Copy the grub.cfg file in efiboot.img which is used by both IA32 UEFI and x64 UEFI.
_make_efibootimg_grubcfg() {
mcopy -i "${efibootimg}" \
"${work_dir}/grub.cfg" ::/EFI/BOOT/grub.cfg
# Copy GRUB files to efiboot.img which is used by both IA32 UEFI and x64 UEFI.
_make_common_bootmode_grub_copy_to_efibootimg() {
local files_to_copy=()
files_to_copy+=("${work_dir}/grub/"*)
if compgen -G "${profile}/grub/!(*.cfg)" &> /dev/null; then
files_to_copy+=("${profile}/grub/"!(*.cfg))
fi
mcopy -i "${efibootimg}" "${files_to_copy[@]}" ::/EFI/BOOT/
}
_make_bootmode_uefi-ia32.grub.esp() {
# Copy GRUB files to efiboot.img which is used by both IA32 UEFI and x64 UEFI.
_make_common_bootmode_grub_copy_to_isofs() {
local files_to_copy=()
files_to_copy+=("${work_dir}/grub/"*)
if compgen -G "${profile}/grub/!(*.cfg)" &> /dev/null; then
files_to_copy+=("${profile}/grub/"!(*.cfg))
fi
install -m 0644 -- "${files_to_copy[@]}" "${isofs_dir}/EFI/BOOT/"
}
# Prepare GRUB configuration files
_make_common_bootmode_grub_cfg(){
local _cfg
install -d -- "${work_dir}/grub"
# Fill GRUB configuration files
sed "s|%ARCHISO_LABEL%|${iso_label}|g;
s|%INSTALL_DIR%|${install_dir}|g;
s|%ARCH%|${arch}|g" \
"${profile}/grub/grub.cfg" > "${work_dir}/grub.cfg"
for _cfg in "${profile}/grub/"*'.cfg'; do
sed "s|%ARCHISO_LABEL%|${iso_label}|g;
s|%INSTALL_DIR%|${install_dir}|g;
s|%ARCH%|${arch}|g" \
"${_cfg}" > "${work_dir}/grub/${_cfg##*/}"
done
# Add all GRUB files to the list of files used to calculate the required FAT image size.
efiboot_files+=("${work_dir}/grub/"
"${profile}/grub/"!(*.cfg))
IFS='' read -r -d '' grubembedcfg <<'EOF' || true
if ! [ -d "$cmdpath" ]; then
@ -553,6 +580,11 @@ fi
configfile "${cmdpath}/grub.cfg"
EOF
printf '%s\n' "$grubembedcfg" > "${work_dir}/grub-embed.cfg"
}
_make_bootmode_uefi-ia32.grub.esp() {
# Prepare configuration files
_run_once _make_common_bootmode_grub_cfg
# Create EFI binary
grub-mkstandalone -O i386-efi \
@ -571,22 +603,19 @@ EOF
elif [[ " ${bootmodes[*]} " =~ uefi-x64.grub.esp ]]; then
_run_once _make_bootmode_uefi-x64.grub.esp
else
efiboot_imgsize="$(du -bc "${efiboot_files[@]}" \
2>/dev/null | awk 'END { print $1 }')"
efiboot_imgsize="$(du -bcs -- "${efiboot_files[@]}" 2>/dev/null | awk 'END { print $1 }')"
# Create a FAT image for the EFI system partition
_make_efibootimg "$efiboot_imgsize"
fi
# Copy GRUB EFI binary to the default/fallback boot path
mcopy -i "${efibootimg}" \
"${work_dir}/BOOTIA32.EFI" ::/EFI/BOOT/BOOTIA32.EFI
mcopy -i "${efibootimg}" "${work_dir}/BOOTIA32.EFI" ::/EFI/BOOT/BOOTIA32.EFI
# Copy GRUB configuration files
_run_once _make_efibootimg_grubcfg
# Copy GRUB files
_run_once _make_common_bootmode_grub_copy_to_efibootimg
if [[ -e "${pacstrap_dir}/usr/share/edk2-shell/ia32/Shell_Full.efi" ]]; then
mcopy -i "${efibootimg}" \
"${pacstrap_dir}/usr/share/edk2-shell/ia32/Shell_Full.efi" ::/shellia32.efi
mcopy -i "${efibootimg}" "${pacstrap_dir}/usr/share/edk2-shell/ia32/Shell_Full.efi" ::/shellia32.efi
fi
_msg_info "Done! GRUB set up for UEFI booting successfully."
@ -598,6 +627,9 @@ _make_bootmode_uefi-ia32.grub.eltorito() {
# uefi-ia32.grub.eltorito has the same requirements as uefi-ia32.grub.esp
_run_once _make_bootmode_uefi-ia32.grub.esp
# Prepare configuration files
_run_once _make_common_bootmode_grub_cfg
# Additionally set up systemd-boot in ISO 9660. This allows creating a medium for the live environment by using
# manual partitioning and simply copying the ISO 9660 file system contents.
# This is not related to El Torito booting and no firmware uses these files.
@ -605,39 +637,22 @@ _make_bootmode_uefi-ia32.grub.eltorito() {
install -d -m 0755 -- "${isofs_dir}/EFI/BOOT"
# Copy GRUB EFI binary to the default/fallback boot path
install -m 0644 -- "${work_dir}/BOOTIA32.EFI" \
"${isofs_dir}/EFI/BOOT/BOOTIA32.EFI"
install -m 0644 -- "${work_dir}/BOOTIA32.EFI" "${isofs_dir}/EFI/BOOT/BOOTIA32.EFI"
# Copy GRUB configuration files
install -m 0644 -- "${work_dir}/grub.cfg" "${isofs_dir}/EFI/BOOT/grub.cfg"
_run_once _make_common_bootmode_grub_copy_to_isofs
# edk2-shell based UEFI shell
if [[ -e "${pacstrap_dir}/usr/share/edk2-shell/ia32/Shell_Full.efi" ]]; then
install -m 0644 -- "${pacstrap_dir}/usr/share/edk2-shell/ia32/Shell_Full.efi" \
"${isofs_dir}/shellia32.efi"
install -m 0644 -- "${pacstrap_dir}/usr/share/edk2-shell/ia32/Shell_Full.efi" "${isofs_dir}/shellia32.efi"
fi
_msg_info "Done!"
}
_make_bootmode_uefi-x64.grub.esp() {
# Fill Grub configuration files
sed "s|%ARCHISO_LABEL%|${iso_label}|g;
s|%INSTALL_DIR%|${install_dir}|g;
s|%ARCH%|${arch}|g" \
"${profile}/grub/grub.cfg" > "${work_dir}/grub.cfg"
IFS='' read -r -d '' grubembedcfg <<'EOF' || true
if ! [ -d "$cmdpath" ]; then
# On some firmware, GRUB has a wrong cmdpath when booted from an optical disc.
# https://gitlab.archlinux.org/archlinux/archiso/-/issues/183
if regexp --set=1:isodevice '^(\([^)]+\))\/?[Ee][Ff][Ii]\/[Bb][Oo][Oo][Tt]\/?$' "$cmdpath"; then
cmdpath="${isodevice}/EFI/BOOT"
fi
fi
configfile "${cmdpath}/grub.cfg"
EOF
printf '%s\n' "$grubembedcfg" > "${work_dir}/grub-embed.cfg"
# Prepare configuration files
_run_once _make_common_bootmode_grub_cfg
# Create EFI binary
grub-mkstandalone -O x86_64-efi \
@ -650,21 +665,19 @@ EOF
efiboot_files+=("${work_dir}/BOOTx64.EFI"
"${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi")
efiboot_imgsize="$(du -bc "${efiboot_files[@]}" \
2>/dev/null | awk 'END { print $1 }')"
efiboot_imgsize="$(du -bcs -- "${efiboot_files[@]}" 2>/dev/null | awk 'END { print $1 }')"
# Create a FAT image for the EFI system partition
_make_efibootimg "$efiboot_imgsize"
# Copy grub EFI binary to the default/fallback boot path
mcopy -i "${efibootimg}" \
"${work_dir}/BOOTx64.EFI" ::/EFI/BOOT/BOOTx64.EFI
# Copy GRUB EFI binary to the default/fallback boot path
mcopy -i "${efibootimg}" "${work_dir}/BOOTx64.EFI" ::/EFI/BOOT/BOOTx64.EFI
_run_once _make_efibootimg_grubcfg
# Copy GRUB files
_run_once _make_common_bootmode_grub_copy_to_efibootimg
if [[ -e "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ]]; then
mcopy -i "${efibootimg}" \
"${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ::/shellx64.efi
mcopy -i "${efibootimg}" "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ::/shellx64.efi
fi
_msg_info "Done! GRUB set up for UEFI booting successfully."
@ -676,6 +689,9 @@ _make_bootmode_uefi-x64.grub.eltorito() {
# uefi-x64.grub.eltorito has the same requirements as uefi-x64.grub.esp
_run_once _make_bootmode_uefi-x64.grub.esp
# Prepare configuration files
_run_once _make_common_bootmode_grub_cfg
# Additionally set up systemd-boot in ISO 9660. This allows creating a medium for the live environment by using
# manual partitioning and simply copying the ISO 9660 file system contents.
# This is not related to El Torito booting and no firmware uses these files.
@ -683,11 +699,10 @@ _make_bootmode_uefi-x64.grub.eltorito() {
install -d -m 0755 -- "${isofs_dir}/EFI/BOOT"
# Copy GRUB EFI binary to the default/fallback boot path
install -m 0644 -- "${work_dir}/BOOTx64.EFI" \
"${isofs_dir}/EFI/BOOT/BOOTx64.EFI"
install -m 0644 -- "${work_dir}/BOOTx64.EFI" "${isofs_dir}/EFI/BOOT/BOOTx64.EFI"
# Copy GRUB configuration files
install -m 0644 -- "${work_dir}/grub.cfg" "${isofs_dir}/EFI/BOOT"
# Copy GRUB files
_run_once _make_common_bootmode_grub_copy_to_isofs
# edk2-shell based UEFI shell
if [[ -e "${pacstrap_dir}/usr/share/edk2-shell/x64/Shell_Full.efi" ]]; then
@ -715,7 +730,7 @@ _make_bootmode_uefi-x64.systemd-boot.esp() {
"${pacstrap_dir}/boot/vmlinuz-"*
"${pacstrap_dir}/boot/initramfs-"*".img"
"${_available_ucodes[@]}")
efiboot_imgsize="$(du -bc "${efiboot_files[@]}" \
efiboot_imgsize="$(du -bcs -- "${efiboot_files[@]}" \
2>/dev/null | awk 'END { print $1 }')"
# Create a FAT image for the EFI system partition
_make_efibootimg "$efiboot_imgsize"