Skip to content

ports/uefi: Add new port for the UEFI firmware environment. - #19432

Open
nickovs wants to merge 8 commits into
micropython:masterfrom
nickovs:port-uefi
Open

nickovs wants to merge 8 commits into
micropython:masterfrom
nickovs:port-uefi

Conversation

@nickovs

@nickovs nickovs commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR introduces a new port to allow MicroPython to run on a PC under the UEFI firmware, prior to a full OS booting. While PCs are not microcontrollers, the pre-boot firmware environment has similarities both in terms of the limited platform and the direct access hardware (since the code runs in "Ring 0"). The port supports both Intel (x64) and ARM (aa64) UEFI platforms.

The UEFI port provides comprehensive wrappers around most of the UEFI API surface. This allows Python code to discover and access hardware, read and write firmware variables and settings, directly interact with extensible EFI protocols and manage the boot process, up to and including implementing custom OS bootloaders in Python.

Most common blocking operations (stdio, socket, sleep etc) support asyncio and async support for UEFI events is provided.

The port provides access to firmware networking on machines which support this, using the standard MicroPython network module. Note that this initial port lacks support for Wi-Fi pending hardware and drivers for testing this. TLS support can be enabled either using mbedTLS or by connecting to the EFI_TLS protocol if the host's firmware provides this. The choice is compile-time; using EFI_TLS saves 190KB of 610KB but not all network-enabled firmwares support this.

NOTE: The build process for this port makes extensive use of Docker to handle the cross-platform nature of the port.

Testing

This code has extensive UEFI-specific testing that runs under the QEUM PC emulator within Docker containers, as well as supporting QEMU testing in local machines where possible. These tests cover all the parts of the UEFI API surface that I could find a way to test. The PR also includes a set of sample code that exercises the UEFI API which can be used for manual testing.

Trade-offs and Alternatives

This code was designed specifically to make minimal changes to the base MicroPython distribution (and succeeded, since it makes no changes). In practice no compromises needed to be made, which vindicates the MicroPython porting API. The code here supports TLS through either mbedTLS (the default) or use of the EFI_TLS protocol. This is controlled by a compile-time switch (TLS=mbedtls|efi|none). While the UEFI spec provides a protocol for supporting TLS (a) many platforms don't implement this and (b) when they do it's often based on an outdated version of OpenSSL. On the other hand, using a firmware-provided version of TLS cuts the binary size by about 30%. In most cases the mbedTLS version should be used by if a PC OEM were to want to include MicroPython in their ROM the EFI_TLS version would be more appropriate.

Generative AI

Some of the code here was typed by Claude, but the architecture, design and planning was entirely human!

@nickovs

nickovs commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

I should add, the TianoCore/EDK2 open source firmware stack includes a port of MicroPython, but this was forked from MicroPython in 2018 and widely diverges from the current mainline. Part of the intention here is to have upstream for UEFI in the mainline code.

@dpgeorge dpgeorge added the ports Relates to multiple ports, or a new/proposed port label Jul 5, 2026
@dpgeorge

dpgeorge commented Jul 5, 2026

Copy link
Copy Markdown
Member

Related old issue: #7053

This PR introduces a new port to allow MicroPython to run on a PC under
the UEFI firmware, prior to a full OS booting. While PCs are not
microcontrollers, the pre-boot firmware environment has similarities
both in terms of the limited platform and the direct access hardware
(since the code runs in "Ring 0"). The port supports both Intel (x64)
and ARM (aa64) UEFI platforms.

The UEFI port provides comprehensive wrappers around most of the UEFI
API surface. This allows Python code to discover and access hardware,
read and write firmware variables and settings, directly interact with
extensible EFI protocols and manage the boot process, up to and
including implementing custom OS bootloaders in Python.

The port provides access to firmware networking on machines which
support this, using the standard MicroPython `network` module. Note
that this initial port lacks support for Wi-Fi pending hardware and
drivers for testing this. TLS support can be enabled either using
mbedTLS or by connecting to the EFI_TLS protocol if the host's firmware
provides this. The choice is compile-time; using EFI_TLS saves 190KB of
610KB but not all network-enabled firmwares support this.

NOTE: The build process for this port makes extensive use of Docker to
handle the cross-platform nature of the port.

Some of the code here was typed by Claude, but the architecture, design
and planning was entirely human!

Signed-off-by: Nicko van Someren <[email protected]>
@dlech

dlech commented Jul 5, 2026 •

Copy link
Copy Markdown
Contributor

19k lines is way too much for a single commit or to review at once!

And I didn't see any tests added, but maybe I missed them? I would expect them to run on CI.

But of course before doing work in that direction, we should agree this is something we want in MicroPython in the first place.

@nickovs

nickovs commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

@dlech Yes, 19K lines is a lot, but there is a lot of new functionality here. This is both a port to make MicroPython run on a new platform and extensive support for the runtime on that platform. I squashed the commits because every single time I've submitted a multi-commit PR to MicroPython in the past I've been asked to squash them into one.

This commit includes extensive tests which can be run automatically (they are a conditional component of main.c, use make test to run them all) as well as banks for manual tests in the samples directory.

The code takes pains to make no changes whatsoever to py/*, which is why there are no new tests for that.

I confess that I don't know enough about the CI system for me to add tests there, but I'm open to suggestions.

@dpgeorge

dpgeorge commented Jul 5, 2026

Copy link
Copy Markdown
Member

As a comparison with another PR that adds a new port: PR #18910 is 18.5k lines, adds basic REPL, UART and Pin capabilities, and is almost ready for merging.

@nickovs
nickovs force-pushed the port-uefi branch 3 times, most recently from d37d012 to 9db2523 Compare July 7, 2026 00:44
The `network` module now surfaces Wi-Fi interfaces when present and allows
them to be configured as a client.

Note that the EFI Wi-Fi protocols do not support configuring interfaces as
APs, so this functionality is unavailable on the `uefi` port.

Signed-off-by: Nicko van Someren <[email protected]>
@nickovs

nickovs commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

I had a chance to test the Wi-Fi support, so I have now pushed a commit with wireless networking (and updated documentation to match). Note that the EFI wireless networking protocol doesn't support AP mode, so nor does this port.

Comment thread docs/uefi/quickref.rst Outdated
@Gadgetoid

Gadgetoid commented Jul 8, 2026 •

Copy link
Copy Markdown
Contributor

On top of docs domments, I think ports/uefi/TODO.md‎ also uses an awful lot of words to say not a lot (including some very obvious Claude tells- honestly, why is everything a story?). Effectively there's no native emitter because there is no native emitter. That change might be completely orthogonal to this port? (used by, but no co-dependent upon?)

Looks like the test harness and fixtures got lumped in with the port, too, I had to be very explicit about getting those folded into the right places, using the right method (took a couple tries). Should probably be in /tools and /tests with reasoning for why the existing harnesses and methods don't apply (if they can't apply).

I think separate commits make sense where they address separate concerns- ie one for docs, one for the port, one for tests. Often those are useful for reviewing, but not really necessary for merging- thus a last-minute squash.

(note: I don't know much about eufi, but I've been fighting Claude to get large changes into the right shape for upstream lately)

note: open a new prompt and: "Review this uefi port. How closely does it adhere to the explcit and implicit standards of the rest of the micropython codebase? Lay out some suggestions for improvement."

edit: Just took my own advice on one of my own PRs (remembering to ask the right question it is half the battle) and got served a sizeable list of fixes 😆

Comment thread ports/uefi/main.c Outdated
@codecov

codecov Bot commented Jul 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.52%. Comparing base (1454c3e) to head (2d1ba0f).
⚠️ Report is 186 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff            @@
##           master   #19432    +/-   ##
========================================
  Coverage   98.51%   98.52%            
========================================
  Files         177      180     +3     
  Lines       22927    23244   +317     
========================================
+ Hits        22586    22900   +314     
- Misses        341      344     +3     
Flag Coverage Δ
unix-coverage-32bit 98.52% <ø> (?)
unix-coverage-64bit 98.48% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jul 12, 2026 •

Copy link
Copy Markdown

Code size report:

Reference:  rp2: Build with -fno-math-errno to use the hardware sqrt instruction. [772df1a]
Comparison: uefi: Relocated UEFI examples to examples/uefi directory. [merge of 2d1ba0f]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
      esp32:    +0 +0.000% ESP32_GENERIC
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@nickovs
nickovs force-pushed the port-uefi branch 3 times, most recently from 10cba3d to 1e7ad16 Compare July 12, 2026 19:16
A new test infrastructure in ports/uefi/tests has been added to allow
running of the standard MicroPython test suite on QEMU-emulated instances
running UEFI firmware.

All standard tests that can be run on the headless UEFI instances have
been enabled.

The original, hard-wired bring-up test infrastructure has been removed.
All previous Docker-based tests that fit within the standard testing
framework have been ported and moved to tests/ports/uefi. The test coverage
has been expanded to cover the vast majority of the EFI API surface.

A new CI workflow has been added in .github/workflows/ports_uefi.yml to
perform full test suite execution through GitHub actions.

The time and date handling has been reworked to run the real datetime as
used by machine.RTC and the time()/time_ns()/localtime() off the same
clock. Real time is read at startup and synced if the user makes a change,
but all API calls use fast CPU timers as the time basis in normal operation
to avoid disparities between "real time" and "CPU time" APIs. Note that the
machine_timer test is known to have load-sensitive flakiness when run under
emulation. Its failure here causes a warning rather than a test suite
failure.

The MICROPY_CONFIG_ROM_LEVEL setting has been moved to the "extra features"
level which enabled a handful of features that were previously not on by
default.

A handful of bugs and missing implementations revealed by the more
comprehensive testing have been fixed.

Signed-off-by: Nicko van Someren <[email protected]>
@nickovs

nickovs commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

I've stripped out the embedded bring-up testing, built out a test framework for running the standard test suite on MicroPython on UEFI on QEMU emulation and added a stack of port-specific tests to test everything that I can under emulation. I expanded the standard modules to include "extra features" and fixed a handful of integration points that stemmed from those. I've also added CI integration for all of this and it all passes.

In addition to the test/CI work above, I think I've address @Gadgetoid's comments on the documentation and port TODO.md file.

@Gadgetoid

Copy link
Copy Markdown
Contributor

Making progress, but you'll forgive me for fighting fire with fire here. It's a lot of code in which I can trivially spot a lot of things that don't seem right, but can't always elucidate why. What follows is a guided code review using Claude and focussing on some of the things that stuck out to me in particular, plus some things it manifested on its own. It's an unholy wall of text but comparing a read of it with my spelunking into this code I broadly agree on points I understand, and concede on points I do not (efi/eufi ambiguity may have some reason I don't fathom).

On top of this I'd say, why GzipFile? It's not used by the codebase anywhere and just seems to be dead-weight that's orthogonal to the port. It probably also belongs in micropython-lib if it doesn't already have a counterpart. A port-specific implementation of Gzip makes no sense. The same applies to ssl.py.

modules/uefi/event.py defines an unused private variable _BY_REGISTER_NOTIFY which appears nowhere else in the codebase. Claude walked right on past that and needs specific prompting to dig into the modules to find issues (not done here)

modules/uefi/status.py is it really necessary to store a counts on fingers 64bit int when only the least significant byte has any information?

modules/uefi/buffer.py - this is what slices are for?:

        for i in range(len(data)):
            dst[i] = data[i]

Is modules/uefi/guid.py doing struct.pack stuff manually? And an O(n) scan of globals() on every call?

modules/uefi/boot.py both _utf16le and _utf16le_decode seem to crop up in other places, with _utf16le_decode having two functions with identical names and different behaviour?

Anyway I got distracted finding things (could follow-up with a Python code review if it's handy) , here's what Claude had to say (note this is pretty surface level stuff, but it takes a lot of effort to coax it deeper):

UEFI port, review recommendations

A review of ports/uefi/ against MicroPython conventions, focused on structure,
standards adherence, and maintainability for a reviewer with no UEFI background.

The port itself is strong: the C is well-sectioned and heavily commented, the hard
parts (MS-ABI GC constraint, the TPL/ISR-to-scheduler bridge, runtime stack sizing) are
explained where they live, and it ships real Sphinx docs (docs/uefi/,
docs/library/uefi.*.rst) plus a CI workflow. Almost every item below is subtraction:
the port is scrupulously consistent, but consistent about applying maximum ceremony to
everything, and a reviewer reads that ceremony as noise before reaching the good code.

Priorities: P1 blocks a clean upstream read; P2 is a clear improvement; P3 is
polish.


1. Namespaces & naming

1.1 Collapse the efi / uefi dual namespace (P1)

The same efi_event_type is exposed under three spellings:

  • a standalone builtin efi module - import efi -> efi.Event (modefi.c:247),
  • folded into _uefi and re-exported by the Python package as uefi.Event
    (moduefi_raw.c:895, modules/uefi/event.py:34),
  • documented only as uefi.event (docs/library/uefi.event.rst).

A newcomer meets efi.Event, uefi.Event, _uefi.Event, files modefi.c +
moduefi_raw.c, headers efi*.h, sources uefi_*.c, and tests efi_*.py - with no rule
for when it is "efi" and when it is "uefi". Pick one user-facing spelling (the docs commit
to uefi), drop the standalone efi module, fold the Event type solely under _uefi, and
update the help() text (main.c:453) and tests/ports/uefi/efi_event.py.

1.2 Rename mod*_uefi.c to the idiomatic bare names (P2)

modnetwork_uefi.c, modsocket_uefi.c, modtime_uefi.c, modtls_efitls.c all register
plainly-named modules (network, socket, tls). esp32/unix name these modnetwork.c /
modsocket.c / modtime.c; the _uefi / _efitls suffix decorates nothing. Rename and
update SRC_C, SRC_QSTR, and MICROPY_PY_TIME_INCLUDEFILE.

1.3 Make the file-prefix convention explicit (P3)

There is a sensible but undocumented split: uefi_*.c = port infrastructure (event, time,
vfs, gccollect), mod*.c = Python-visible modules, efi*.h = firmware ABI headers. State
it once in the README file-map (see 6.1) so it stops looking arbitrary.


2. Non-source scaffolding littering the port root

No other MicroPython port ships a Dockerfile, docker/, scripts/, samples/, or
test-images/ at the port root - none of the 12 checked. Around 1,825 lines of shell +
Python workflow code currently sit interleaved with the port source, so a reviewer cannot
tell port source from build convenience from personal debris.

2.1 Delete throwaway debugging rigs (P1)

scripts/net/_pcap_dhcp.sh, _pcap_long.sh, _pcap_probe.sh, _diag_debugcon.sh - the
_ prefix, hardcoded cd /work/ports/uefi, mktemp -d, one-shot pcap dumps - are "chasing
a DHCP bug" scripts, not infrastructure. Delete. scripts/net/net_probe.py (14 KB) and
run_net_probe.sh are the same category at larger size - drop or move out of tree.

2.2 scripts/ is a grab bag (P2)

After 2.1, keep only what make run / make debug actually invoke
(run.sh, debug.sh, env.sh, and run-gfx.sh if still wired). triage.sh (post-failure
log dump) is borderline - keep only if a make target uses it; otherwise drop.

2.3 docker/ is four scripts hiding two variant axes (P2)

build-ovmf.sh, build-ovmf-net.sh, build-ovmf-release.sh, build-ovmf-release-net.sh
are really {NOOPT, RELEASE} x {no-net, net} over the Dockerfile's ovmf-builder /
ovmf-net-builder stages. Collapse to one script parameterized by build type + network,
so the variant matrix is legible instead of copy-pasted four ways.

2.4 Quarantine the toolchain/firmware scaffolding (P2)

Dockerfile, docker/, test-images/build-test-os.sh are defensible for a hard-to-repro
cross-toolchain (clang/lld PE + OVMF/AAVMF) and better than "figure it out yourself", but
since no other port does this, upstream will ask why. Move under a clearly-optional dev/
(or tools/) subdir and have the README state plainly: standard build is make; the Docker
path is a convenience for reproducing the toolchain and firmware.

2.5 Relocate samples/ to examples/uefi/ (P2)

The canonical location for example code is top-level examples/
(https://github.com/micropython/micropython/tree/master/examples). Move samples/ ->
examples/uefi/. (Caveat: ports/nrf keeps its own examples/ dir, so this is a soft
convention - but top-level is the default.) Independently, 18 sample scripts is a lot of
surface; trim to the ones that earn their place.

2.6 Remove TODO.md (P2)

No other port carries one; deferred work lives in the tracker / upstreaming PR. It also
duplicates the README "Limitations" section. Delete, move contents to the PR description.


3. Test infrastructure

3.1 run_uefi_tests.py reinvents tests/run-tests.py (P2)

22 KB of bespoke runner that itself documents wrapping pyboard's exec: transport
(run_uefi_tests.py:5) and re-imports upstream test_utils. The upstream convention: tests
live in tests/ports/uefi/ (they correctly do), and the port supplies a thin pyboard-style
device driver so standard run-tests.py --target uefi drives it. Refactor toward the standard
runner; keep only the QEMU-launch glue that genuinely cannot live there.

3.2 tests/harness.py is brittle terminal choreography (P2)

21 KB of pexpect send / expect_exact driving the live REPL with 18 raw escape-sequence
literals - arrow keys (\x1b[A), cursor edits (\x08, \x7f), tab/BEL/NUL echo
(\t, \a, \x00) - asserting on cursor movement and byte-level echo (harness.py:189,
:223, :282). Any change to readline or the TerminalDxe layer breaks it, and the failure
is opaque. If line-editing coverage is worth keeping, narrow it to the smallest set of
assertions that pin behaviour (history recalls the line; Ctrl-C interrupts) rather than
exact terminal byte sequences, and lean on the standard .py.exp mechanism where possible.

3.3 Fix the doc/header inversion between the two test files (P3)

harness.py carries a full license header but no module docstring; run_uefi_tests.py
carries a README's worth of inlined prose but no license header (the only file in the port
missing one). Give both a one-line SPDX header (see 5) and move run_uefi_tests.py's
explanatory essay into the README or a short module docstring. (Moot for run_uefi_tests.py
if it is folded into a standard runner per 3.1.)


4. .gitignore

4.1 De-duplicate and tighten (P3)

The current file is verbose and overlapping (build/, build-*/, plus per-extension
*.o / *.obj / *.efi that the build dirs already contain; multiple firmware/log
globs). Model it on a surgical port ignore such as
https://github.com/micropython/micropython/blob/a5bac1b75ad4ba69d30f73ee3ce7bc358665069c/ports/esp32/.gitignore

  • ignore build output directories, not every artifact extension individually. Note it
    currently also ignores CLAUDE.md and .claude/, which ties to 6.3.

5. License headers & boilerplate ratio

Attribution consistency is good: all 63 source files carry an identical
Copyright (c) 2026 Nicko van Someren with no drift. The problem is volume - the full
25-line MIT block is applied uniformly regardless of file size:

File Total lines License Actual code
qstrdefsport.h 28 28 0
include/alloca.h 33 33 0
include/winsock2.h, ws2tcpip.h 32 32 0
include/unistd.h 33 32 1
uefi_stubs.c 46 39 7
modtime_uefi.c 47 38 9
mphalport.h 55 46 9

This diverges from upstream in two demonstrable ways: upstream's own extmod/asyncio/*.py
carry no per-file MIT block (pure-Python modules rely on top-level LICENSE), and
upstream has begun adopting SPDX short-form (extmod/mbedtls/mbedtls_alt.c).

5.1 Adopt SPDX one-liners port-wide (P2)

Replace the 25-line block with SPDX-License-Identifier: MIT + a single copyright line.
Keeps attribution and license unambiguous, matches upstream's direction, and removes
~1,400 lines of boilerplate across the port.

5.2 Don't header trivial files at all (P2)

Trivial files should not carry license bloat - see
https://github.com/micropython/micropython/blob/master/ports/rp2/boards/manifest.py
(a manifest.py with no header). Apply the same to this port's manifest.py and the
one-line include/ shims.

5.3 Delete qstrdefsport.h if it defines no qstrs (P3)

It is currently 100% header + a "none yet" comment and zero code. If the Makefile's
QSTR_DEFS needs a target it can be satisfied without a committed all-boilerplate file.

5.4 Consolidate the include/ shims (P3)

Thirteen separately-headered files, several empty or one #define, is more surface than the
problem needs. Merge the zero/one-line shims where sensible and give each a terse one-line
"why this shim exists" note instead of the full block (see also 6.2).


6. Documentation & orientation

6.1 Add a file-by-file map (P1 - highest-value single change)

The README "Layout" section is one dense paragraph; the directory presents ~40 top-level
files with no index. Add a table: each C file -> one-line responsibility (uefi_event.c =
TPL/ISR-to-scheduler bridge + serial REPL; uefi_vfs.c = VFS over EFI_SIMPLE_FILE_SYSTEM;
main.c = entry / heap / stack / argv; etc.). This is what lets someone assess the port
without knowing UEFI.

6.2 Document the include/ shim surface in one place (P2)

The *-unknown-windows clang triple is deeply non-obvious and is why there is a
windows.h / winsock2.h / ws2tcpip.h shim. Add one paragraph - "we target a Windows PE
triple, so the toolchain expects these libc/Win headers; here is the whole shim list and
why" - near the -Iinclude line in the Makefile or an include/README. Tie
uefi_stubs.c's __chkstk / _fltused to the same triple story.

6.3 De-agent the README and fix the dangling reference (P1)

README.md:7 points readers to CLAUDE.md as "the agent operating manual", but CLAUDE.md
is .gitignored - upstream readers get a dead reference. Phrases like "the ABI landmine,
what-not-to-touch" read as internal tooling notes. Remove the CLAUDE.md reference and fold
any genuinely necessary build guidance into the README / Makefile comments.

6.4 Keep limitations DRY (P3)

README "Limitations" and TODO.md overlap. After 2.6 removes TODO.md, ensure the README
states current capability once.


Suggested execution order

  1. Subtractions first (fast, high signal): delete 2.1 debugging rigs, 2.6 TODO.md,
    5.3 qstrdefsport.h; fix 6.3 README / CLAUDE.md.
  2. Namespace + naming: 1.1 collapse efi/uefi, 1.2 rename mod*_uefi.c.
  3. Relocations: 2.4 quarantine Docker/firmware into dev/, 2.5 samples ->
    examples/uefi/, 2.2/2.3 tidy scripts/ and docker/.
  4. License sweep: 5.1 SPDX one-liners, 5.2 drop headers on trivial files.
  5. Test infra: 3.1 move toward standard runner, 3.2 narrow harness.py.
  6. Orientation docs: 6.1 file map, 6.2 shim index.
  7. Polish: 4.1 .gitignore, remaining P3s.

Uh, me again, the TLDR is that the more you delete/factor out, and the more you adhere to MicroPython idioms the easier this becomes to review. Right now the superficial quality of the Python code (duplicate modules, bytewise copies in lieu of slices, manual byte unpacking in lieu of struct, copy-pasted functions littered over the codebase, searches over globals() for guids, no const() use) is quite confusing; why put MicroPython in UEFI if you don't want to write MicroPython??

@nickovs

nickovs commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@Gadgetoid Many thanks for the feedback. I will work through these finding (by hand) and address your (and Claude's) suggestions.

nickovs added 2 commits July 13, 2026 01:55
The changes to the license text removed just over 2,100 lines of
boilerplate and touched 90 files, so they are being commited separately
to avoid obscuring more subtle changes
addressing the other points.

Signed-off-by: Nicko van Someren <[email protected]>
The gzip.py file has been removed. I was not quite unused, since
it was getting frozen and included in each build, but it was not
needed.

The ssl.py file replicated the functionality of the ssl.py
in micropython-lib, wrapping the modern TLS support for
backward compatibility. We now use the version on micropython-lib.

The use of a 64 bit value in status.py if both deliberate and
necessary, since this is the size of the return code from UEFI
and bit 63 is meaningful. This has been left as it was.

The hangover from when byte block slicing didn't work has been
cleaned up.

GUID packing/unpacking has been cleaned up (some of the packing
wasn't even needed). I also revamped the whole registry system
so that we build the canonical registry map and then fold it into
the globals rather than trying to extract the map from the
globals.

UTF-16 support has been refactored into its own file and a single version
is used throughout.

The `efi` module has been dropped and the `efi.Timer` class has been
relocated.

The module file naming has been made both more internally consistent
and more consistent with the naming conventions used in other ports.

The README.md file now includes a structured map of the file layout.

Much scaffolding, including all the bring-up network test scripts,
have been removed.

Signed-off-by: Nicko van Someren <[email protected]>
@nickovs
nickovs force-pushed the port-uefi branch 2 times, most recently from f4c1e52 to 2d9ef05 Compare July 14, 2026 00:26
Testing the UEFI target now has run-test.py calling a target-specific
harness, not the other way around. This required changes to
tests/test_utils.py since the process of starting QEMU took longer than
the previous hard-wired timeout.

The Makefile targets for running tests have all been updated to use the
new test mechanism.

Signed-off-by: Nicko van Someren <[email protected]>
nickovs added 2 commits July 19, 2026 08:14
The Makefile builds are now more robust in the face of outdated content.

The harness.py code properly ensures that the UEFI boot parameters
are correctly set before tests are run on QEMU.

The firmware builder scripts have been consolidated into one,
parameterised script.

All builder support scripts have been tidied into the port's tools
directory.

Signed-off-by: Nicko van Someren <[email protected]>
Documentation and Makefile have been updated to point to the correct
example code location.

Signed-off-by: Nicko van Someren <[email protected]>
@Gadgetoid Gadgetoid mentioned this pull request Jul 22, 2026
5 of 8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ports Relates to multiple ports, or a new/proposed port

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants