Add AArch64 UEFI support (NVIDIA Jetson Orin)#818
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds a new aarch64_efi target so wolfBoot can run as an AArch64 UEFI application (validated on NVIDIA Jetson Orin), loading/verifying kernel.img/update.img from the ESP and booting via UEFI LoadImage/StartImage.
Changes:
- Add a new AArch64 UEFI HAL (
hal/aarch64_efi.c) plus boot glue (src/boot_aarch64_efi.c) and linker-script stub. - Extend the build system to support an AArch64 PE/COFF
wolfboot.efioutput and a new example config. - Add helper scripts and documentation for building gnu-efi for AArch64 and running under QEMU/Jetson deployment.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/scripts/build-gnu-efi-aarch64.sh | Helper to clone/build/install gnu-efi (AArch64) into the repo tree |
| tools/scripts/aarch64-efi-qemu.sh | Convenience runner for wolfboot.efi under QEMU + AAVMF |
| tools/keytools/keygen.c | Extends keystore section handling for the new UEFI target macro |
| src/boot_aarch64_efi.c | Adds UEFI-target do_boot() glue for AArch64 |
| Makefile | Makes the wolfboot.efi objcopy output format configurable per target |
| hal/aarch64_efi.ld | Empty placeholder linker script (gnu-efi script used instead) |
| hal/aarch64_efi.c | New AArch64 UEFI HAL: ESP file loading, verification, LoadImage/StartImage handoff |
| docs/Targets.md | Adds aarch64_efi target documentation (Jetson Orin + QEMU workflow) |
| config/examples/aarch64_efi.config | Example configuration for aarch64_efi |
| arch.mk | Adds aarch64_efi target build flags, gnu-efi paths, and linking rules |
| .gitignore | Ignores gnu-efi build artifacts and staging dirs for the new target |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
308bf22 to
1963856
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 22 out of 23 changed files in this pull request and generated 12 comments.
Comments suppressed due to low confidence (1)
hal/aarch64_efi.c:1
- UEFI
EFI_FILE_PROTOCOL.Open()ignores the Attributes parameter unlessEFI_FILE_MODE_CREATEis set; passingREAD_ONLY|HIDDEN|SYSTEMhere is nonstandard and can cause opens to fail on stricter firmwares. For read-only opens, pass0for the Attributes argument and keep access control viaEFI_FILE_MODE_READ.
/* aarch64_efi.c
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 22 out of 23 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (2)
hal/aarch64_efi.c:504
- open_kernel_image() stores FileSize() into a uint32_t, which truncates files >4GiB. That can lead to partial reads and confusing verification failures. Also, returning EFI_STATUS from an int-returning function can truncate the high-bit error codes on 64-bit builds; it’s safer to keep the return values as 0/-1 here since the caller doesn’t consume EFI_STATUS.
*sz = FileSize(file);
pages = (*sz / PAGE_SIZE) + 1;
wolfBoot_printf("Opening file: %s, size: %u\n", filename, *sz);
status = uefi_call_wrapper(BS->AllocatePages,
4,
hal/aarch64_efi.c:528
- On Read() failure, open_kernel_image() returns EFI_STATUS through an int return type. On AArch64, EFI_STATUS uses the high bit for errors, so truncating to int can turn errors into 0 (success) if a future caller checks it. Return -1 here (and rely on the already-printed status) to keep the int contract consistent.
if (status != EFI_SUCCESS) {
wolfBoot_printf("file Read failed: 0x%lx\n", (unsigned long)status);
uefi_call_wrapper(BS->FreePages, 2, *_addr, pages);
*_addr = 0;
return status;
1f35be7 to
d325fbd
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 15 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
hal/aarch64_efi.c:528
- open_kernel_image() assigns the UINT64 EFI file size into a uint32_t and then computes pages as (sz / PAGE_SIZE) + 1, which always over-allocates when the file is an exact multiple of PAGE_SIZE and silently truncates sizes >4GiB. Validate the file size up front and compute the page count with a proper round-up division.
*sz = FileSize(file);
pages = (*sz / PAGE_SIZE) + 1;
wolfBoot_printf("Opening file: %s, size: %u\n", filename, *sz);
Summary
Adds a generic AArch64 UEFI-application target, the direct sibling of the existing
x86_64_efitarget. wolfBoot builds aswolfboot.efi(a PE/COFF EFI application), is launched by platform UEFI firmware, verifies the next-stage image with wolfCrypt, and boots it through UEFILoadImage/StartImage. It uses only UEFI Boot Services (no SoC-specific registers), so a single binary runs on any AArch64 UEFI platform. Validated end-to-end on the NVIDIA Jetson Orin Nano (Tegra234), booting a signed L4T kernel to an Ubuntu 22.04 login prompt.Features
SIGN/HASHoptions apply), and hands off viaLoadImage/StartImage. A/B image selection uses the RAM updater.wolfboot.efiruns on any AArch64 UEFI platform rather than being tied to a board.tools/scripts/sign-efi-secureboot.shgenerates PK/KEK/db keys, sbsignswolfboot.efi, and emits the.authvariable updates so the firmware verifies wolfBoot, making the chain continuous (firmware ->wolfboot.efi-> kernel). Document-only NVIDIA PKC/SBK fuse-provisioning steps included (no fuses burned).EFI_TCG2_PROTOCOL(HashLogExtendEvent), extending both the SHA-256 and SHA-384 banks with no TPM driver of its own, then reads the PCR back (TPM2_PCR_ReadviaSubmitCommand) so the resulting value is available for attestation. Enabled withMEASURED_BOOT_TCG2=1; best-effort on platforms without a firmware TPM.SIGN=ECC384 HASH=SHA384 SPMATH=1) vs. the default ED25519/SHA256, withdocs/FIPS.mdscoping what a validated build additionally requires.pei-aarch64-littlePE output;tools/scripts/build-gnu-efi-aarch64.shbuilds the runtime from a pinned gnu-efi tag (4.0.4) for reproducibility.tools/scripts/aarch64-efi-qemu.shrunswolfboot.efiunder QEMU + AAVMF, with a--gdbmode for source-level debugging.aarch64_efi_testjob builds the gnu-efi runtime andwolfboot.efion every push, mirroring thex86_64_efijob.tegra234_testCI job, as a starting point for the future vendor-firmware-replacement path (not a validated boot path).Notable fix
For a UEFI-application target the keystore must not be placed in the
.keystorelinker section (the gnu-efi PE does not load it, soPubKeysreads back as zeros).keygen.cemits the keystore as plainconstdata foraarch64_efi, matchingx86_64_efi.Build and run
See
docs/Targets.md(NVIDIA Jetson Orin section) for the full validated L4T recipe and Secure Boot enrollment steps.Validation
kernel.img-> ED25519 verify PASS ->LoadImage/StartImage-> the real L4T kernel EFI stub runs.Verifying signature...done-> boots the signed L4T kernel -> mounts the SD rootfs -> Ubuntu 22.04.5 login prompt.wolfboot.efilaunches and boots (EFI stub: UEFI Secure Boot is enabled); an unsigned copy is refused by the firmware with a Security Violation. The kernel is signed for bothdb(so UEFILoadImageaccepts it) and wolfCrypt.EFI_TCG2_PROTOCOLreportsTPM present=1with the SHA-256 + SHA-384 banks; wolfBoot measures the kernel, command line, and DTB into PCR 9 and prints the read-back PCR value on the console.aarch64_efi(default and FIPS ECC384/SHA384) andtegra234build clean;x86_64_efiandraspi3unregressed. Secure Boot tool round-trips (sign ->sbverifyPASS; unsigned -> rejected).