| 27 |
27 |
|
[ -d "$ROOTFS" ] || { echo "no $ROOTFS" >&2; exit 1; }
|
| 28 |
28 |
|
[ -d "$OUTPUT" ] || { echo "no $OUTPUT" >&2; exit 1; }
|
| 29 |
29 |
|
|
|
30 |
+ |
# ---------------------------------------------------------------------
|
|
31 |
+ |
# 0. Which architecture this medium is for.
|
|
32 |
+ |
#
|
|
33 |
+ |
# From `uname -m`, because the builder image is derived from the Alloy image
|
|
34 |
+ |
# and carries its kernel: the squashfs, the initramfs and the OCI layout are
|
|
35 |
+ |
# all already the architecture this is running on, and an ISO whose boot
|
|
36 |
+ |
# chain disagreed with them would boot nothing. ALLOY_ISO_ARCH overrides it
|
|
37 |
+ |
# for testing the GRUB half alone; it does not make this a cross-build.
|
|
38 |
+ |
#
|
|
39 |
+ |
# Anything but the two mappings is an explicit refusal. Falling through to a
|
|
40 |
+ |
# default would produce an ISO with the wrong EFI binary name, which fails
|
|
41 |
+ |
# as "the stick is not bootable" with no diagnosis available on the machine
|
|
42 |
+ |
# that cannot boot it.
|
|
43 |
+ |
# ---------------------------------------------------------------------
|
|
44 |
+ |
ARCH="${ALLOY_ISO_ARCH:-$(uname -m)}"
|
|
45 |
+ |
case "$ARCH" in
|
|
46 |
+ |
x86_64)
|
|
47 |
+ |
GRUB_FORMAT="x86_64-efi"
|
|
48 |
+ |
# The removable-media path from the UEFI spec. Firmware looks for this
|
|
49 |
+ |
# exact name on a medium with no boot entry of its own and nothing else,
|
|
50 |
+ |
# so it is per-architecture and is not ours to choose.
|
|
51 |
+ |
EFI_NAME="BOOTX64.EFI"
|
|
52 |
+ |
GRUB_MODULE_PKG="grub2-efi-x64-modules"
|
|
53 |
+ |
SERIAL_CONSOLES="console=ttyS0,115200" ;;
|
|
54 |
+ |
aarch64)
|
|
55 |
+ |
GRUB_FORMAT="arm64-efi"
|
|
56 |
+ |
EFI_NAME="BOOTAA64.EFI"
|
|
57 |
+ |
GRUB_MODULE_PKG="grub2-efi-aa64-modules"
|
|
58 |
+ |
# ttyAMA0 first because SBSA mandates a PL011 and that is what an Ampere
|
|
59 |
+ |
# board actually presents; ttyS0 stays listed for boards that present an
|
|
60 |
+ |
# 8250 instead. The kernel writes to every console that exists and
|
|
61 |
+ |
# ignores the ones that do not, so listing both costs nothing and losing
|
|
62 |
+ |
# the serial log on a headless arm box costs the only view of a failed
|
|
63 |
+ |
# boot. tty0 stays last, so /dev/console is still the screen.
|
|
64 |
+ |
SERIAL_CONSOLES="console=ttyAMA0,115200 console=ttyS0,115200" ;;
|
|
65 |
+ |
*)
|
|
66 |
+ |
echo "unsupported architecture: $ARCH (this builds x86_64 and aarch64)" >&2
|
|
67 |
+ |
exit 1 ;;
|
|
68 |
+ |
esac
|
|
69 |
+ |
|
|
70 |
+ |
# grub2-mkimage reads the modules for the target format out of this
|
|
71 |
+ |
# directory, and says only "cannot open directory" when they are absent.
|
|
72 |
+ |
# Name the package instead, before the several minutes of squashfs that
|
|
73 |
+ |
# would otherwise run first.
|
|
74 |
+ |
[ -d "/usr/lib/grub/$GRUB_FORMAT" ] \
|
|
75 |
+ |
|| { echo "no GRUB modules for $GRUB_FORMAT; the builder needs $GRUB_MODULE_PKG" >&2; exit 1; }
|
|
76 |
+ |
say "architecture $ARCH, $GRUB_FORMAT, $EFI_NAME"
|
|
77 |
+ |
|
| 30 |
78 |
|
# Version-sorted, not `head -1`: `ls` collates 7.1.10 before 7.1.3, so the
|
| 31 |
79 |
|
# alphabetical pick is arbitrary rather than newest. A bootc image should carry
|
| 32 |
80 |
|
# exactly one kernel, so more than one means something layered a second and the
|
| 163 |
211 |
|
# reads to find the squashfs.
|
| 164 |
212 |
|
# ---------------------------------------------------------------------
|
| 165 |
213 |
|
say "grub"
|
| 166 |
|
- |
# console= twice on purpose. The kernel writes to every console listed, so
|
| 167 |
|
- |
# serial gets a full log for headless debugging, while /dev/console resolves
|
| 168 |
|
- |
# to the last one named and so stays on the screen the user is looking at.
|
|
214 |
+ |
# console= more than once on purpose. The kernel writes to every console
|
|
215 |
+ |
# listed, so serial gets a full log for headless debugging, while
|
|
216 |
+ |
# /dev/console resolves to the last one named and so stays on the screen the
|
|
217 |
+ |
# user is looking at. Which serial lines are named is per-architecture; see
|
|
218 |
+ |
# the arch block at the top.
|
| 169 |
219 |
|
# Reversed, the installer's own output would go down the serial line and the
|
| 170 |
220 |
|
# monitor would sit black. The installer renders on tty1 explicitly
|
| 171 |
221 |
|
# (alloy-installer.service, TTYPath) and does not depend on this ordering.
|
| 172 |
|
- |
CONSOLES="console=ttyS0,115200 console=tty0"
|
|
222 |
+ |
CONSOLES="$SERIAL_CONSOLES console=tty0"
|
| 173 |
223 |
|
# SELinux on the live medium: permissive by default, off as a fallback.
|
| 174 |
224 |
|
#
|
| 175 |
225 |
|
# The live rootfs.img is built by mkfs.ext4 from a container rootfs, and it
|
| 285 |
335 |
|
configfile /boot/grub/grub.cfg
|
| 286 |
336 |
|
EOF
|
| 287 |
337 |
|
|
| 288 |
|
- |
# Our own GRUB *is* BOOTX64.EFI, with no shim in front of it.
|
|
338 |
+ |
# Our own GRUB *is* the removable-media binary, with no shim in front of it.
|
| 289 |
339 |
|
#
|
| 290 |
340 |
|
# The signed shim and signed grubx64.efi that shim expects to chain to both
|
| 291 |
341 |
|
# ship in RPMs whose files a bootc image strips out of /boot, and the
|
| 294 |
344 |
|
# either way, so this ISO needs Secure Boot off regardless of whether shim
|
| 295 |
345 |
|
# is in front of it. Signing is a distribution problem and distribution is
|
| 296 |
346 |
|
# not set up (GO task 0d7505b5); when it is, this is where shim goes.
|
|
347 |
+ |
#
|
|
348 |
+ |
# Every module named below is present in both the x86_64-efi and the
|
|
349 |
+ |
# arm64-efi target, so the list is architecture-independent and only the
|
|
350 |
+ |
# format and the output name change.
|
| 297 |
351 |
|
grub2-mkimage \
|
| 298 |
|
- |
--format=x86_64-efi \
|
|
352 |
+ |
--format="$GRUB_FORMAT" \
|
| 299 |
353 |
|
--prefix="/EFI/BOOT" \
|
| 300 |
|
- |
--output="$WORK/iso/EFI/BOOT/BOOTX64.EFI" \
|
|
354 |
+ |
--output="$WORK/iso/EFI/BOOT/$EFI_NAME" \
|
| 301 |
355 |
|
part_gpt part_msdos fat iso9660 udf normal linux echo all_video test \
|
| 302 |
356 |
|
search search_label search_fs_uuid search_fs_file gfxterm gfxterm_background \
|
| 303 |
357 |
|
configfile loadenv chain efi_gop efi_uga ls cat halt reboot minicmd \
|
| 336 |
390 |
|
# Read it back out of the filesystem rather than trusting the exit codes: a
|
| 337 |
391 |
|
# bootloader that is not in here is the one defect this whole file exists to
|
| 338 |
392 |
|
# avoid, and it is invisible everywhere else.
|
| 339 |
|
- |
mdir -i "$WORK/efiboot.img" ::/EFI/BOOT | grep -qi 'BOOTX64' \
|
| 340 |
|
- |
|| { echo "BOOTX64.EFI is not in the ESP; the medium cannot boot" >&2; exit 1; }
|
| 341 |
|
- |
say "ESP $(( EFI_KB / 1024 ))M FAT16, BOOTX64.EFI present"
|
|
393 |
+ |
#
|
|
394 |
+ |
# Checked against the name this build wrote, not a fixed one: an arm ISO
|
|
395 |
+ |
# that failed a check naming BOOTX64 would report an architecture it was
|
|
396 |
+ |
# never building for.
|
|
397 |
+ |
mdir -i "$WORK/efiboot.img" ::/EFI/BOOT | grep -qi "${EFI_NAME%.EFI}" \
|
|
398 |
+ |
|| { echo "$EFI_NAME is not in the ESP; the medium cannot boot" >&2; exit 1; }
|
|
399 |
+ |
say "ESP $(( EFI_KB / 1024 ))M FAT16, $EFI_NAME present"
|
| 342 |
400 |
|
# Deliberately not copied into $WORK/iso. It is appended to the medium as a
|
| 343 |
401 |
|
# real partition below, and El Torito is pointed at that partition rather
|
| 344 |
402 |
|
# than at a file in the tree, so a copy inside the ISO filesystem would be
|