Skip to content

Commit b64815c

Browse files
committed
aarch64 support: efi stub and devicetree selection
generate-zbm now understands the EFI.DeviceTree key. This key can contain one of three possible values: 1) /absolute/path/%{kernel}/to/device-tree-file.dtb 2) /absolute/path/to/device-tree-file.dtb 3) partial/path/device-tree-file.dtb If found, %{kernel} is replaced with the kernel version being built in to the EFI asset. Partial paths are appended to /boot/dtbs/dtb-$kernel/, a well-known path for device tree files used by Void Linux. Inside ZFSBootMenu, the org.zfsbootmenu:devicetree property is read. The value of this property are handled in the same order/priority as EFI.DeviceTree. %{kernel} is replaced with the kernel version that kexec is loading / executing.
1 parent f1c873a commit b64815c

File tree

2 files changed

+73
-4
lines changed

2 files changed

+73
-4
lines changed

bin/generate-zbm

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use File::stat;
1515
use File::Path qw(make_path remove_tree);
1616
use File::Glob qw(:globally :nocase);
1717
use Sort::Versions;
18+
use Config;
1819
use bigint qw(hex);
1920

2021
use Pod::Usage qw(pod2usage);
@@ -684,10 +685,12 @@ sub createUEFIBundle {
684685
}
685686
} else {
686687

687-
# For now, default stub locations are x86_64 only
688-
my @uefi_stub_defaults = qw(
689-
/usr/lib/systemd/boot/efi/linuxx64.efi.stub
690-
);
688+
my @uefi_stub_defaults;
689+
if ( $Config{archname} =~ m/x86_64/ ) {
690+
push( @uefi_stub_defaults, '/usr/lib/systemd/boot/efi/linuxx64.efi.stub' );
691+
} elsif ( $Config{archname} =~ m/aarch64/ ) {
692+
push( @uefi_stub_defaults, '/usr/lib/systemd/boot/efi/linuxaa64.efi.stub' );
693+
}
691694

692695
foreach my $stubloc (@uefi_stub_defaults) {
693696
if ( -f $stubloc ) {
@@ -771,6 +774,39 @@ sub createUEFIBundle {
771774
$uki_offset = addBundleSection( \@cmd, ".splash", $config{EFI}{SplashImage}, $uki_offset, $uki_alignment );
772775
}
773776

777+
if ( has_value $config{EFI}{DeviceTree} ) {
778+
my $dtb_try;
779+
780+
if ( $config{EFI}{DeviceTree} =~ m,^/, ) {
781+
if ( $config{EFI}{DeviceTree} =~ m/\Q%{kernel}/ ) {
782+
783+
# Possibly a templated file path
784+
$dtb_try = $config{EFI}{DeviceTree};
785+
$dtb_try =~ s/\Q%{kernel}/$runConf{kernel_version}/;
786+
} else {
787+
788+
# Possibly an absolute path to a file
789+
$dtb_try = $config{EFI}{DeviceTree};
790+
}
791+
} else {
792+
793+
# Possibly a partial path
794+
$dtb_try = sprintf( "/boot/dtbs/dtbs-%s/%s", $runConf{kernel_version}, $config{EFI}{DeviceTree} );
795+
}
796+
797+
if ( has_value $dtb_try && -f $dtb_try ) {
798+
$uki_offset = addBundleSection( \@cmd, ".dtb", $dtb_try, $uki_offset, $uki_alignment );
799+
} else {
800+
if ( has_value $dtb_try ) {
801+
printf "EFI.DeviceTree key set to '%s', file not found at '%s'\n", $config{EFI}{DeviceTree}, $dtb_try;
802+
exit 1;
803+
} else {
804+
printf "EFI.DeviceTree key set to '%s', file not found\n", $config{EFI}{DeviceTree};
805+
exit 1;
806+
}
807+
}
808+
}
809+
774810
$uki_offset = addBundleSection( \@cmd, ".initrd", $initramfs, $uki_offset, $uki_alignment );
775811

776812
# Add the kernel last, so that it can decompress without overflowing other sections

zfsbootmenu/lib/zfsbootmenu-core.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ mount_zfs() {
351351

352352
kexec_kernel() {
353353
local selected fs kernel initramfs output hook_envs
354+
local dtb_prop dtb_try dtb_file kver
354355

355356
selected="${1}"
356357
if [ -z "${selected}" ]; then
@@ -390,8 +391,39 @@ kexec_kernel() {
390391
cli_args="$( load_be_cmdline "${fs}" )"
391392
root_prefix="$( find_root_prefix "${fs}" "${mnt}" )"
392393

394+
dtb_prop="$( zfs get -H -o value org.zfsbootmenu:devicetree "${fs}" 2>/dev/null )"
395+
if [ -n "${dtb_prop}" ] && [ "${dtb_prop}" != '-' ] ; then
396+
zdebug "devicetree property set to '${dtb_prop}'"
397+
398+
# this is cursed
399+
kver="${kernel#"${kernel%%-*}"-}"
400+
401+
if [ "${dtb_prop:0:1}" = "/" ] ; then
402+
if [[ "${dtb_prop}" =~ %{kernel} ]] ; then
403+
# possibly a templated absolute path to a file
404+
dtb_try="${mnt}${dtb_prop//%\{kernel\}/$kver}"
405+
else
406+
# possibly an absolute path to a file
407+
dtb_try="${mnt}${dtb_prop}"
408+
fi
409+
else
410+
# possibly a suffix to a well-known path
411+
dtb_try="${mnt}/boot/dtbs/dtbs-${kver}/${dtb_prop}"
412+
fi
413+
414+
if [ -n "${dtb_try}" ] && [ -f "${dtb_try}" ] ; then
415+
zdebug "devicetree file exists: '${dtb_try}'"
416+
dtb_file="${dtb_try}"
417+
else
418+
zdebug "devicetree file missing: '${dtb_try}'"
419+
fi
420+
else
421+
zdebug "no devicetree property set"
422+
fi
423+
393424
if ! output="$( kexec -a -l "${mnt}${kernel}" \
394425
--initrd="${mnt}${initramfs}" \
426+
${dtb_file:+--dtb="${dtb_file}"} \
395427
--command-line="${root_prefix}${fs} ${cli_args}" 2>&1 )"
396428
then
397429
zerror "unable to load ${mnt}${kernel} and ${mnt}${initramfs} into memory"
@@ -2019,6 +2051,7 @@ zreport() {
20192051
read -r INITRD_VERSION < /VERSION
20202052
INITRD_VERSION="mkinitcpio ${INITRD_VERSION}"
20212053
elif [ -f /etc/initrd-release ] ; then
2054+
# shellcheck disable=SC1091
20222055
source /etc/initrd-release
20232056
[ -n "${DRACUT_VERSION}" ] && INITRD_VERSION="Dracut ${DRACUT_VERSION}"
20242057
fi

0 commit comments

Comments
 (0)