Subject: UEFI and Unified Kernel Image

From: Mallory <[email-masked]>
Date: Sat, 23 Nov 2024 14:22:43 +0100

Ahoy there,

I'm trying to come up with a script to build a minimal Alpine image with
support for UEFI and UKI (no secureboot) via static version of apt-tools.
Yet it would seem that whatever I try, the UEFI partition comes back empty.
And the odd thing is that the `bootx64.efi` is created in the appropriate
place (see the build output). Likely, I'm missing something painfully
obvious but being new to Alpine I would appreciate some pointers as to how
I can debug the issue.

Here's the script:

#!/bin/bash

set -eux

readonly PATH=/bin:/sbin:/usr/bin:/usr/sbin
readonly DEFAULT_DISK_SIZE="2G"
readonly IMAGE="alpine.img"
readonly MIRROR=https://dl-cdn.alpinelinux.org/alpine
readonly REL=3.21
readonly ARCH=$(uname -m)
readonly APKV=2.14.4-r4
readonly REPO="${MIRROR}"/v"${REL}"/main
readonly HOST="satellite"

wait_until_settled() {
udevadm settle
blockdev --flushbufs --rereadpt "${1}"
until test -e "${1}p2"; do
echo "${1}p2 doesn't exist yet..."
sleep 1
done
}

cleanup() {
set +o errexit

if [ -n "${LOOPDEV:-}" ]; then
losetup -d "${LOOPDEV}"
fi
if [ -n "${MOUNT:-}" ] && mountpoint -q "${MOUNT}"; then
umount --recursive "${MOUNT}" || exit 1
fi
if [ -n "${TMPDIR:-}" ]; then
rm -rf "${TMPDIR}"
fi
}
trap cleanup EXIT

init() {
readonly ORIG_PWD="${PWD}"
readonly OUTPUT="${PWD}/out"
tmpdir="$(mktemp --dry-run --directory --tmpdir="${PWD}/tmp")"
readonly TMPDIR="${tmpdir}"
mkdir -p "${OUTPUT}" "${TMPDIR}"
if [ -n "${SUDO_UID:-}" ] && [ -n "${SUDO_GID:-}" ]; then
chown "${SUDO_UID}:${SUDO_GID}" "${OUTPUT}" "${TMPDIR}"
fi
cd "${TMPDIR}"

readonly MOUNT="${PWD}/mount"
mkdir "${MOUNT}"
}

setup_disk() {
truncate -s "${DEFAULT_DISK_SIZE}" "${IMAGE}"
sgdisk --align-end \
--clear \
--new 0:0:+1G --typecode=0:ef00 --change-name=0:'EFI' \
--new 0:0:0 --typecode=0:8304 --change-name=0:'alpine' \
"${IMAGE}"

LOOPDEV=$(losetup --find --partscan --show "${IMAGE}")
wait_until_settled "${LOOPDEV}"

mkfs.vfat -F 32 -n EFI "${LOOPDEV}p1"
mkfs.ext4 -L alpine -q "${LOOPDEV}p2"
mount "${LOOPDEV}p2" "${MOUNT}"
mount --mkdir "${LOOPDEV}p1" "${MOUNT}/boot/efi"
}

bootstrap() {
curl -s "${MIRROR}"/v"${REL}"/main/"${ARCH}"/apk-tools-static-${APKV}.apk |
tar xz

./sbin/apk.static --repository "${REPO}" \
--update-cache \
--allow-untrusted \
--root "${MOUNT}" \
--initdb add alpine-base

cat <<EOF >"${MOUNT}"/etc/fstab
LABEL=alpine / ext4 defaults 0 0
LABEL=EFI /boot/efi vfat defaults 0 2
EOF

echo "nameserver 1.1.1.1" > "${MOUNT}"/etc/resolv.conf
echo "${REPO}" >"${MOUNT}"/etc/apk/repositories

cat <<EOF >"${MOUNT}"/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
EOF

for a in dev dev/pts proc sys run; do mount -o bind /$a "${MOUNT}"/$a; done

chroot "${MOUNT}" /bin/sh -x <<CHROOT
mkdir -p /etc/kernel-hooks.d/
mkdir -p /etc/mkinitfs/
mkdir -p /boot/efi/EFI/Linux/

echo "cmdline=root=LABEL=alpine modules=ext4" >
/etc/kernel-hooks.d/secureboot.conf
echo "signing_disabled=yes" >> /etc/kernel-hooks.d/secureboot.conf
echo "output_dir="/boot/efi/EFI/Linux/"" >>
/etc/kernel-hooks.d/secureboot.conf
echo "output_name="bootx64.efi"" >> /etc/kernel-hooks.d/secureboot.conf
echo "disable_trigger=yes" >> /etc/mkinitfs/mkinitfs.conf

apk update
apk add linux-lts \
linux-firmware-none \
mkinitfs \
secureboot-hook \
gummiboot-efistub \

setup-hostname -n "${HOST}"

rc-update -q add devfs sysinit
rc-update -q add dmesg sysinit
rc-update -q add mdev sysinit
rc-update -q add hwdrivers sysinit

rc-update -q add hwclock boot
rc-update -q add modules boot
rc-update -q add hostname boot
rc-update -q add bootmisc boot
rc-update -q add networking boot

rc-update -q add mount-ro shutdown
rc-update -q add killprocs shutdown
rc-update -q add savecache shutdown

rc-update -q add crond default

mkdir -p /boot/efi/loader/entries

cat > /boot/efi/loader/entries/alpine.conf <<EOF
title Alpine Linux
linux /EFI/Linux/bootx64.efi
EOF

ls -la /boot/efi/EFI/Linux/
CHROOT

cp "${IMAGE}" "${OUTPUT}/"
}

main() {
if [ "$(id -u)" -ne 0 ]; then
echo "root is required"
exit 1
fi

init
setup_disk
bootstrap
}

main

And the output from the run:

+ readonly PATH=/bin:/sbin:/usr/bin:/usr/sbin
+ PATH=/bin:/sbin:/usr/bin:/usr/sbin
+ readonly DEFAULT_DISK_SIZE=2G
+ DEFAULT_DISK_SIZE=2G
+ readonly IMAGE=alpine.img
+ IMAGE=alpine.img
+ readonly MIRROR=https://dl-cdn.alpinelinux.org/alpine
+ MIRROR=https://dl-cdn.alpinelinux.org/alpine
+ readonly REL=3.21
+ REL=3.21
++ uname -m
+ readonly ARCH=x86_64
+ ARCH=x86_64
+ readonly APKV=2.14.4-r4
+ APKV=2.14.4-r4
+ readonly REPO=https://dl-cdn.alpinelinux.org/alpine/v3.21/main
+ REPO=https://dl-cdn.alpinelinux.org/alpine/v3.21/main
+ readonly HOST=satellite
+ HOST=satellite
+ trap cleanup EXIT
+ main
++ id -u
+ '[' 0 -ne 0 ']'
+ init
+ readonly ORIG_PWD=/home/boojum/Documents/zzz/alpine-image-bootstrap
+ ORIG_PWD=/home/boojum/Documents/zzz/alpine-image-bootstrap
+ readonly OUTPUT=/home/boojum/Documents/zzz/alpine-image-bootstrap/out
+ OUTPUT=/home/boojum/Documents/zzz/alpine-image-bootstrap/out
++ mktemp --dry-run --directory
--tmpdir=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp
+
tmpdir=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
+ readonly
TMPDIR=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
+
TMPDIR=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
+ mkdir -p /home/boojum/Documents/zzz/alpine-image-bootstrap/out
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
+ '[' -n 1000 ']'
+ '[' -n 1000 ']'
+ chown 1000:1000 /home/boojum/Documents/zzz/alpine-image-bootstrap/out
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
+ cd /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
+ readonly
MOUNT=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
+
MOUNT=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
+ mkdir
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
+ setup_disk
+ truncate -s 2G alpine.img
+ sgdisk --align-end --clear --new 0:0:+1G --typecode=0:ef00
--change-name=0:EFI --new 0:0:0 --typecode=0:8304 --change-name=0:alpine
alpine.img
Creating new GPT entries in memory.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.
++ losetup --find --partscan --show alpine.img
+ LOOPDEV=/dev/loop1
+ wait_until_settled /dev/loop1
+ udevadm settle
+ blockdev --flushbufs --rereadpt /dev/loop1
+ test -e /dev/loop1p2
+ mkfs.vfat -F 32 -n EFI /dev/loop1p1
mkfs.fat 4.2 (2021-01-31)
+ mkfs.ext4 -L alpine -q /dev/loop1p2
+ mount /dev/loop1p2
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
+ mount --mkdir /dev/loop1p1
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/boot/efi
+ bootstrap
+ curl -s
https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/apk-tools-static-2.14.4-r4.apk
+ tar xz
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
+ ./sbin/apk.static --repository
https://dl-cdn.alpinelinux.org/alpine/v3.21/main --update-cache
--allow-untrusted --root
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
--initdb add alpine-base
fetch
https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz
(1/24) Installing alpine-baselayout-data (3.6.8-r0)
(2/24) Installing musl (1.2.5-r7)
(3/24) Installing busybox (1.37.0-r8)
Executing busybox-1.37.0-r8.post-install
(4/24) Installing busybox-binsh (1.37.0-r8)
(5/24) Installing alpine-baselayout (3.6.8-r0)
Executing alpine-baselayout-3.6.8-r0.pre-install
Executing alpine-baselayout-3.6.8-r0.post-install
(6/24) Installing ifupdown-ng (0.12.1-r6)
(7/24) Installing libcap2 (2.71-r0)
(8/24) Installing openrc (0.55.1-r2)
Executing openrc-0.55.1-r2.post-install
(9/24) Installing mdev-conf (4.7-r0)
(10/24) Installing busybox-mdev-openrc (1.37.0-r8)
(11/24) Installing alpine-conf (3.18.1-r4)
(12/24) Installing alpine-keys (2.5-r0)
(13/24) Installing alpine-release (3.21.0_alpha20240923-r0)
(14/24) Installing ca-certificates-bundle (20240705-r0)
(15/24) Installing libcrypto3 (3.3.2-r4)
(16/24) Installing libssl3 (3.3.2-r4)
(17/24) Installing ssl_client (1.37.0-r8)
(18/24) Installing zlib (1.3.1-r2)
(19/24) Installing apk-tools (2.14.4-r4)
(20/24) Installing busybox-openrc (1.37.0-r8)
(21/24) Installing busybox-suid (1.37.0-r8)
(22/24) Installing scanelf (1.3.8-r1)
(23/24) Installing musl-utils (1.2.5-r7)
(24/24) Installing alpine-base (3.21.0_alpha20240923-r0)
Executing busybox-1.37.0-r8.trigger
OK: 8 MiB in 24 packages
+ cat
+ echo 'nameserver 1.1.1.1'
+ echo https://dl-cdn.alpinelinux.org/alpine/v3.21/main
+ cat
+ for a in dev dev/pts proc sys run
+ mount -o bind /dev
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/dev
+ for a in dev dev/pts proc sys run
+ mount -o bind /dev/pts
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/dev/pts
+ for a in dev dev/pts proc sys run
+ mount -o bind /proc
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/proc
+ for a in dev dev/pts proc sys run
+ mount -o bind /sys
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/sys
+ for a in dev dev/pts proc sys run
+ mount -o bind /run
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/run
+ chroot
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
/bin/sh -x
+ mkdir -p /etc/kernel-hooks.d/
+ mkdir -p /etc/mkinitfs/
+ mkdir -p /boot/efi/EFI/Linux/
+ echo 'cmdline=root=LABEL=alpine modules=ext4'
+ echo 'signing_disabled=yes'
+ echo 'output_dir=/boot/efi/EFI/Linux/'
+ echo 'output_name=bootx64.efi'
+ echo 'disable_trigger=yes'
+ apk update
fetch
https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz
v20240923-5088-g92cc27fd38d [
https://dl-cdn.alpinelinux.org/alpine/v3.21/main]
OK: 5550 distinct packages available
+ apk add linux-lts linux-firmware-none mkinitfs secureboot-hook
gummiboot-efistub
(1/23) Installing gummiboot-efistub (48.1-r8)
(2/23) Installing linux-firmware-none (20240909-r3)
(3/23) Installing xz-libs (5.6.3-r0)
(4/23) Installing zstd-libs (1.5.6-r1)
(5/23) Installing kmod (33-r2)
(6/23) Installing lddtree (1.27-r0)
(7/23) Installing libeconf (0.6.3-r0)
(8/23) Installing libblkid (2.40.2-r4)
(9/23) Installing device-mapper-libs (2.03.28-r2)
(10/23) Installing json-c (0.18-r0)
(11/23) Installing libuuid (2.40.2-r4)
(12/23) Installing cryptsetup-libs (2.7.5-r1)
(13/23) Installing kmod-libs (33-r2)
(14/23) Installing mkinitfs (3.10.2-r1)
Executing mkinitfs-3.10.2-r1.post-install
(15/23) Installing linux-lts (6.12.0-r1)
(16/23) Installing libgcc (14.2.0-r4)
(17/23) Installing jansson (2.14-r4)
(18/23) Installing libstdc++ (14.2.0-r4)
(19/23) Installing binutils (2.43.1-r1)
(20/23) Installing efi-mkuki (0.1.0-r2)
(21/23) Installing kernel-hooks (0.2-r1)
(22/23) Installing sbsigntool (0.9.5-r2)
(23/23) Installing secureboot-hook (0.2-r2)
Executing secureboot-hook-0.2-r2.post-install
Executing busybox-1.37.0-r8.trigger
Executing kmod-33-r2.trigger
Executing mkinitfs-3.10.2-r1.trigger
Executing kernel-hooks-0.2-r1.trigger
kernel-hooks: executing hook 50-secureboot.hook (lts, 6.12.0-1, )
==> initramfs: creating /tmp/secureboot.Jlefgi/initramfs for 6.12.0-1-lts
Display ELF dependencies as a tree

Usage: lddtree [options] ELFFILE...

Options:
-a, --all Show all duplicated dependencies
-h, --help Show this help output
-l, --flat Display output in a flat format
--no-auto-root Do not automatically prefix input ELFs with ROOT
-R, --root ROOT Use this ROOT filesystem tree
-V, --version Show version information
-x, --debug Run with debugging
==> secureboot: creating UEFI Unified Kernel Image with /boot/vmlinuz-lts
==> secureboot: writing *unsigned* UEFI image to
/boot/efi/EFI/Linux//bootx64.efi (signing is disabled!)
OK: 133 MiB in 47 packages
+ setup-hostname -n satellite
+ rc-update -q add devfs sysinit
+ rc-update -q add dmesg sysinit
+ rc-update -q add mdev sysinit
+ rc-update -q add hwdrivers sysinit
+ rc-update -q add hwclock boot
+ rc-update -q add modules boot
+ rc-update -q add hostname boot
+ rc-update -q add bootmisc boot
+ rc-update -q add networking boot
+ rc-update -q add mount-ro shutdown
+ rc-update -q add killprocs shutdown
+ rc-update -q add savecache shutdown
+ rc-update -q add crond default
+ mkdir -p /boot/efi/loader/entries
+ cat
+ ls -la /boot/efi/EFI/Linux/
total 11416
drwxr-xr-x 2 root root 4096 Nov 23 13:20 .
drwxr-xr-x 3 root root 4096 Nov 23 13:20 ..
-rwxr-xr-x 1 root root 11680190 Nov 23 13:20 bootx64.efi
+ cp alpine.img /home/boojum/Documents/zzz/alpine-image-bootstrap/out/
+ cleanup
+ set +o errexit
+ '[' -n /dev/loop1 ']'
+ losetup -d /dev/loop1
+ '[' -n
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
']'
+ mountpoint -q
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
+ umount --recursive
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
+ '[' -n
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie ']'
+ rm -rf
/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie

---

From: daggs <[email-masked]>
Date: Sat, 23 Nov 2024 18:02:19 +0100

Greetings,

>Sent: Saturday, November 23, 2024 at 3:22 PM
>From: "Mallory" <[email-masked]>
>To: ~alpine/[email-masked]
>Subject: UEFI and Unified Kernel Image
>
>Ahoy there,
> 
>I'm trying to come up with a script to build a minimal Alpine image with support for UEFI and UKI (no secureboot) via static version of apt-tools. Yet it would seem that whatever I try, the UEFI partition comes back empty. And the odd thing is that the `bootx64.efi` is created in the appropriate place (see the build output). Likely, I'm missing something painfully obvious but being new to Alpine I would appreciate some pointers as to how I can debug the issue.
> 
>Here's the script:
> 
>
>#!/bin/bash 
>set -eux 
>curl -s "${MIRROR}"/v"${REL}"/main/"${ARCH}"/apk-tools-static-${APKV}.apk | tar xz 
>echo "cmdline=root=LABEL=alpine modules=ext4" > /etc/kernel-hooks.d/secureboot.conf
>echo "output_dir="/boot/efi/EFI/Linux/"" >> /etc/kernel-hooks.d/secureboot.conf
>+ MIRROR=https://dl-cdn.alpinelinux.org/alpine[https://dl-cdn.alpinelinux.org/alpine]
>+ readonly REL=3.21
>+ REL=3.21
>++ uname -m
>+ readonly ARCH=x86_64
>+ ARCH=x86_64
>+ readonly REPO=https://dl-cdn.alpinelinux.org/alpine/v3.21/main[https://dl-cdn.alpinelinux.org/alpine/v3.21/main]
>+ REPO=https://dl-cdn.alpinelinux.org/alpine/v3.21/main[https://dl-cdn.alpinelinux.org/alpine/v3.21/main]
>++ mktemp --dry-run --directory --tmpdir=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp
>+ tmpdir=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
>+ readonly TMPDIR=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
>+ TMPDIR=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
>+ mkdir -p /home/boojum/Documents/zzz/alpine-image-bootstrap/out /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
>+ '[' -n 1000 ']'
>+ '[' -n 1000 ']'
>+ chown 1000:1000 /home/boojum/Documents/zzz/alpine-image-bootstrap/out /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie
>+ readonly MOUNT=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
>+ MOUNT=/home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
>+ mkdir /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
>+ setup_disk
>+ sgdisk --align-end --clear --new 0:0:+1G --typecode=0:ef00 --change-name=0:EFI --new 0:0:0 --typecode=0:8304 --change-name=0:alpine alpine.img
>+ mount /dev/loop1p2 /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
>+ mount --mkdir /dev/loop1p1 /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/boot/efi
>+ bootstrap
>+ curl -s https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/apk-tools-static-2.14.4-r4.apk[https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/apk-tools-static-2.14.4-r4.apk]
>+ tar xz
>+ ./sbin/apk.static --repository https://dl-cdn.alpinelinux.org/alpine/v3.21/main[https://dl-cdn.alpinelinux.org/alpine/v3.21/main] --update-cache --allow-untrusted --root /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount --initdb add alpine-base
>fetch https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz[https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz]
>+ echo https://dl-cdn.alpinelinux.org/alpine/v3.21/main[https://dl-cdn.alpinelinux.org/alpine/v3.21/main]
>+ cat
>+ mount -o bind /dev /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/dev
>+ mount -o bind /dev/pts /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/dev/pts
>+ mount -o bind /proc /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/proc
>+ mount -o bind /sys /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/sys
>+ mount -o bind /run /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount/run
>+ chroot /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount /bin/sh -x
>fetch https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz[https://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz]
>v20240923-5088-g92cc27fd38d [https://dl-cdn.alpinelinux.org/alpine/v3.21/main[https://dl-cdn.alpinelinux.org/alpine/v3.21/main]]
>+ apk add linux-lts linux-firmware-none mkinitfs secureboot-hook gummiboot-efistub
>==> secureboot: writing *unsigned* UEFI image to /boot/efi/EFI/Linux//bootx64.efi (signing is disabled!)
>+ '[' -n /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount ']'
>+ mountpoint -q /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
>+ umount --recursive /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie/mount
>+ '[' -n /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie ']'
>+ rm -rf /home/boojum/Documents/zzz/alpine-image-bootstrap/tmp/tmp.u5KuNSSdie

I'm doing a similar thing which work, here is what I do:
mkfs.vfat ${DEV_POINT}1
mkfs.ext3 ${DEV_POINT}2
mkfs.ext4 ${DEV_POINT}3
mkfs.ext4 ${DEV_POINT}4
mkfs.ext4 ${DEV_POINT}5
mkfs.ext4 ${DEV_POINT}6
mount ${DEV_POINT}6 ${MNT_POINT}
mkdir -p ${MNT_POINT}/efi
mkdir -p ${MNT_POINT}/mnt/efi
mkdir -p ${MNT_POINT}/boot
mkdir -p ${MNT_POINT}/home
mkdir -p ${MNT_POINT}/tmp
mkdir -p ${MNT_POINT}/var
mount -t vfat ${DEV_POINT}1 ${MNT_POINT}/mnt/efi
mount ${DEV_POINT}2 ${MNT_POINT}/boot
mount ${DEV_POINT}3 ${MNT_POINT}/home
mount ${DEV_POINT}4 ${MNT_POINT}/tmp
mount ${DEV_POINT}5 ${MNT_POINT}/var
mount -o bind ${MNT_POINT}/mnt/efi ${MNT_POINT}/efi
cd ${MNT_POINT}/boot/
ln -sf ../efi EFI

hope it helps you

Dagg