# Bare-metal environments for the Raspberry Pi 5

Checked on 2026-10-21. Goal: run the NeXT emulator Previous (a large C/C++ program, today an SDL3 program on Raspberry Pi OS) with as few layers as possible between the emulator and the hardware. Raspberry Pi 5 first, Raspberry Pi 4 as a comparison.

Sources are cited as links, or as `file:line` inside a local clone with the commit hash of that clone:

| Clone | Commit | Date of the commit |
|-------|--------|--------------------|
| `rsta2/circle` | `7a81e1b` | 2026-09-25 |
| `smuehlst/circle-stdlib` | `4fbab62` | 2026-09-25 |
| `raspberrypi/documentation` | `ddea98e` | not recorded |
| `raspberrypi/rpi-eeprom` | `7ed1cc2` | not recorded |
| `ultibohub/Core` | `5fe351e` | 2026-05-12 |

Paths below are relative to the root of the named clone. Where a claim could not be checked, it is marked **open**.

## 1. The boot chain of the Pi 5

### What runs before the kernel image

1. The ROM (first stage) reads the SPI boot EEPROM and runs the second stage bootloader from it. Source: [EEPROM boot flow](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#bootflow-eeprom), `documentation/asciidoc/computers/raspberry-pi/bootflow-eeprom.adoc` (documentation `ddea98e`), sections "First stage bootloader" and "Second stage bootloader".
2. The second stage initializes clocks and SDRAM, reads the EEPROM configuration, walks `BOOT_ORDER` (SD card, USB mass storage, NVMe, network and others) and loads the firmware from the first device that has it. Same file.
3. On the Pi 5 the firmware is part of the EEPROM. Quote, `bootflow-eeprom.adoc`, section "Differences on Raspberry Pi 5": "Instead of loading `start.elf`, the firmware loads the Linux kernel. Effectively, the bootloader has an embedded version of `start.elf`." The same fact appears in `documentation/asciidoc/computers/config_txt/boot.adoc` (section `start_file`, `fixup_file`): "The Raspberry Pi 5, 500, 500+, and Compute Module 5 firmware is self-contained in the bootloader EEPROM."
4. The `raspberrypi/firmware` repository has no `start*.elf` for the Pi 5. Its `boot/` directory (checked through the GitHub API on 2026-10-21) holds `start.elf`, `start4.elf`, `start4cd.elf`, `start4db.elf`, `start4x.elf`, `start_cd.elf`, `start_db.elf`, `start_x.elf`, the kernels, `bcm2712*.dtb` files and `LICENCE.broadcom`, and no Pi 5 `.elf`.
5. The EEPROM images are pre-compiled binaries. Quote, [rpi-eeprom README](https://github.com/raspberrypi/rpi-eeprom/blob/master/README.md) (`7ed1cc2`), line 2: "This repository contains the scripts and pre-compiled binaries used to create the `rpi-eeprom` package". `LICENSE` in the same clone lists `firmware-2712/*` with the licence "custom" (Copyright 2024 Raspberry Pi (Trading) Ltd.). The source of the bootloader is therefore not in that repository.

### Image name and `config.txt`

- Image name: `boot.adoc` section `kernel`: "The Raspberry Pi 5, 500, 500+, and Compute Module 5 firmware defaults to loading `kernel_2712.img` ... If this file is not present, then the common 64-bit kernel (`kernel8.img`) will be loaded instead." The table in `documentation/asciidoc/computers/configuration/reference.adoc` lines 93 to 100 lists `kernel8.img` and `kernel_2712.img` for BCM2712.
- `arm_64bit`: `boot.adoc` section `arm_64bit`: "Flagship models since Raspberry Pi 5, Compute Modules since CM5, and Keyboard models since Raspberry Pi 500 _only_ support the 64-bit kernel. Models that only support a 64-bit kernel ignore this flag." The Pi 5 is not in the list of models that accept the flag.
- An explicit `kernel=` line in `config.txt` overrides the default name. `boot.adoc` section `kernel`. Circle's own `boot/config64.txt` (circle `7a81e1b`) uses `[pi5]` with `kernel=kernel_2712.img` at lines 39 and 40, together with `arm_64bit=1`, `kernel_address=0x80000` and `initial_turbo=0` at lines 12 to 14.
- Arm stub: `boot.adoc` section `armstub`: "The default Arm stub is stored in firmware and is selected automatically based on the Raspberry Pi model and various settings." Circle's memory map for the Pi 5 shows "ARM Trusted Firmware, BL31" in the first 32 KByte (`doc/memorymap.txt` line 245, circle `7a81e1b`). Circle starts secondary cores through a PSCI `CPU_ON` call with `smc #0` (`lib/multicore.cpp` lines 150 to 172), which means the bare-metal image runs below a resident secure monitor that it cannot replace from `config.txt`.
- Device tree: Circle needs `bcm2712-rpi-5-b.dtb` and `overlays/bcm2712d0.dtbo` on the SD card. Source: [Circle Pi 5 appendix](https://circle-rpi.readthedocs.io/en/latest/appendices/raspberry-pi-5.html), section "Installing", and `boot/README` ("The device tree overlay bcm2712d0.dtbo must be copied into the directory overlays/ on the SD card").

### What can never be removed

Based on the sources above:

- The ROM and the EEPROM second stage bootloader, including the firmware embedded in it.
- The firmware keeps serving the ARM side after the kernel starts. Circle depends on this: "Because Circle relies on this firmware support, there are limitations, when using HDMI displays" (Circle Pi 5 appendix, section "Display support"). How long the firmware's VideoCore code stays running is not stated in the documents read, so the exact extent is **open**.
- A resident BL31 / PSCI layer (Circle memory map, see above).
- A device tree file that the firmware reads (the `.dtb` and the overlay).

## 2. Circle and circle-stdlib

### Licences

- Circle: `LICENSE` in the root is the "GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007" (circle `7a81e1b`). The add-ons carry third-party code with their own terms (FatFs by ChaN, LVGL, the Plan 9 WLAN driver and others, listed in `addon/README`). Their individual licences were not examined and are **open**.
- circle-stdlib: `README.md` line 169 to 170: "This project is licensed under the GNU GENERAL PUBLIC LICENSE Version 3" (circle-stdlib `4fbab62`). Newlib, libc++ and mbed TLS come in as submodules with their own licences. The submodules were not fetched in the clone, so those licences are **open**.
- **Open and important for Previous:** Circle and circle-stdlib are GPLv3. Whether the licence of Previous can be combined with GPLv3 code was not examined here.

### Release history for the Pi 5

From `CHANGELOG.md` in circle `7a81e1b`. A "Step" is a Circle release.

| Step | Date | Pi 5 content | Line |
|------|------|--------------|------|
| 46 | 2024-02-28 | "With this release Circle initially **supports the Raspberry Pi 5**. There are many features, which are not available yet, but important features like USB and networking are supported." | 273 to 278 |
| 47 | 2024-07-09 | SPI master, I2S sound, PWM sound, PWM output (4 channels), GPIO clocks, real-time clock, power button, power-off, 8-channel I2S output, better GPIO timing through RIO | 232 to 260 |
| 48 | 2024-11-08 | "HDMI sound for the Raspberry Pi 5", BCM2712 stepping D0, fix that only 4 GB of RAM were usable on the 8 GB model | 198 to 230 |
| 49 | 2025-03-18 | External PCIe bus of the Pi 5 through `CBcmPCIeHostBridge`, XPT2046 touch driver, new display management with `CTerminalDevice` | 156 to 193 |
| 50 | 2025-08-15 | New DTB files required for the Pi 5, WLAN firmware update, HDMI sound fix | 117 to 143 |
| 50.1 | 2026-02-01 | NVMe v1.4 SSD driver (experimental), I2S RX/TX on the Pi 5, multi-core programs in QEMU | 76 to 108 |
| 51 | not read | New TCP/IP stack, libc++ related options, toolchain GCC 15.2.Rel1 | 38 to 74 |
| 51.1 | not read | Official 5" and 7" touchscreens (v1 and v2) with DSI on the Pi 5, `LogTrace`, USB mouse with generic HID interface | 11 to 36 |

### Support per item, Raspberry Pi 5

The authoritative table is "Features" in `README.md` (circle `7a81e1b`, lines 91 to 173). Its heading says "Only the features with a "x" or other info are currently supported on the Raspberry Pi 5."

| Item | Pi 5 status | Source and quote | Since |
|------|-------------|------------------|-------|
| AArch64 build | Yes, AArch64 only | README line 97: "AArch32 and AArch64 support \| AArch64 only". README line 214: "Circle does not support 32-bit applications on the Raspberry Pi 5." [Appendix](https://circle-rpi.readthedocs.io/en/latest/appendices/raspberry-pi-5.html): "The Cortex-A76 CPU of the Raspberry Pi 5 supports only AArch64 in the mode, which is used by Circle (EL1)". `RASPPI = 5` selects the target `kernel_2712` (`Rules.mk` line 118). | Step 46 |
| Multicore, four cores | Yes | README line 101: "Multi-core support (Raspberry Pi 2, 3 and 4) \| x". `lib/multicore.cpp` lines 139 to 205 has a separate Pi 5 path that starts cores 1 to 3 with PSCI `CPU_ON` and waits for them. `doc/multicore.txt`: all peripheral IRQs and their callbacks run on core 0, and the cooperative scheduler "cannot be used on more than one core at a time and should always run on core 0". Sample `17-fractal` and `43-multiwindow` are marked as working on the Pi 5. | Step not stated in `CHANGELOG.md`, **open** |
| MMU and caches | Yes | README line 99: "Enables all CPU caches using the MMU \| x" | Step not stated, **open** |
| FPU and NEON | Not stated in the README or the doc files read | **Open.** The README table has no row for it. The compile flags in `Rules.mk` were not examined. | open |
| HDMI framebuffer | Limited | README line 116: "Frame buffer (screen driver with escape sequences) \| limited". [Appendix](https://circle-rpi.readthedocs.io/en/latest/appendices/raspberry-pi-5.html), "Display support": "The firmware support for frame buffer device(s) is not as comfortable on the Raspberry Pi 5 as on earlier models. Because Circle relies on this firmware support, there are limitations, when using HDMI displays (e.g. no configuration in config.txt, cannot set display resolution from application)." | Step 46 |
| Resolution | Chosen by the firmware, not by the application | Same quote. `boot/config64.txt` lines 41 and 42 have `#framebuffer_depth=32` and `#framebuffer_ignore_alpha=1` for `[pi5]`, commented out. | |
| Double buffering and vsync | **Open** | `include/circle/bcmframebuffer.h` declares `SetVirtualOffset` (line 71) and `WaitForVerticalSync` (line 73). `sample/README` line 42 marks `41-screenanimations` ("2D graphical shapes demo on screen without flickering") as working on the Pi 5. Whether these two calls work on the Pi 5 firmware was not measured. | open |
| VideoCore mailbox | Used for the frame buffer | `lib/usb/xhcidevice.cpp` line 26 includes `circle/bcmpropertytags.h`. The Pi 5 appendix says Circle relies on firmware support for the frame buffer. The documents do not use the word "mailbox" for the Pi 5, so the exact interface is **open**. | |
| OpenGL ES, EGL, OpenVG | No | README lines 167 and 168: row "OpenGL ES 1.1 and 2.0, OpenVG 1.1, EGL 1.4" has nothing in the Pi 5 column. `addon/README`: `vc4` has no `[5]`. | |
| USB host through RP1 xHCI | Yes | README line 142: "Host controller interface (HCI) drivers \| x". `lib/usb/xhcidevice.cpp` lines 31 to 39 takes the interrupts `RP1_IRQ_USBHOST0_0` and `RP1_IRQ_USBHOST1_0` for the Pi 5 (any model other than 4). `doc/memorymap.txt` line 244 to 277 puts the "RP1 peripherals" at `10F0000000` on "PCI Bus 0000:01". The [RP1 datasheet](https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf), chapter 5, describes two xHCI controllers (Synopsys dwc_usb3). Hub driver: README line 143, "Standard hub driver (USB 2.0 only)". | Step 46 |
| USB HID keyboard and mouse | Yes | README line 144: "HID class device drivers (keyboard, mouse, gamepad) \| x". `sample/README` line 10: `08-usbkeyboard [PnP,5]`. `10-usbmouse` is marked `[PnP]` without `5`. Step 49 fixes an LVGL mouse cursor on the Pi 5. Step 51.1 adds "USB mice with generic HID interface (3-0-0)". | Step 46 |
| USB mass storage | Yes | README line 148: "Driver for USB mass storage devices (bulk only) \| x". `sample/README`: `07-usbstorage [5]`, `15-files [5]`. | Step 46 |
| SD card with FAT | Yes | README lines 121, 159 and 160: "EMMC SD card interface driver \| x", "Internal FAT driver (limited function) \| x", "FatFs driver (full function, by ChaN) \| x". The SDHOST driver is for the Pi 1 to 3 only (README line 122). `addon/README`: `SDCard [5]`, `fatfs [5]`. | Step 46 |
| Ethernet through RP1 | Yes | README line 137: "MACB / GEM Gigabit Ethernet NIC of Raspberry Pi 5 \| x". The RP1 datasheet chapter 7 describes the "Cadence Gigabit Ethernet MAC (GEM_GXL 1p09)". `sample/README`: `06-ethernet [5]`. | Step 46 |
| Wi-Fi | Yes, with a caveat | README line 138: "Wireless LAN access \| x". `doc/issues.txt`: "The WLAN connection is delicate on the Raspberry Pi 5, when a HDMI display is used at the same time." | Step not stated |
| Sound | HDMI audio, I2S and PWM work; no headphone jack | README lines 130 and 131: "I2S sound output and input \| x", "HDMI sound output (without VCHIQ) \| x"; line 124: "PWM sound output (on headphone jack) \| with adapter" (Step 47: "requires external circuit on GPIO12/13 or GPIO18/19"). HDMI sound for the Pi 5 came in Step 48. README line 150 lists "Driver for USB audio streaming devices (RPi 4 only)" with an `x` in the Pi 5 column, which contradicts itself, so USB audio on the Pi 5 is **open**. | I2S and PWM: Step 47. HDMI: Step 48. |
| Timers and interrupts | System timer yes, IRQ only | README line 100: "Interrupt support (IRQ and FIQ) \| IRQ only". Line 118: "System timer (with kernel timers) \| x". | Step 46 |
| Platform DMA | RP1 DMA and DMA40 | README lines 119 and 120 | Step 46 |
| NVMe | Experimental | Step 50.1, README line 140 | Step 50.1 |
| Bluetooth | No | README line 173: "Not supported \| Bluetooth" | |
| C and C++ standard library | Through circle-stdlib | See below | |

### circle-stdlib

- Build option: `configure` accepts `-r <number>, --raspberrypi <number>   Circle Raspberry Pi model number (1, 2, 3, 4, 5, default: 1)` (`README.md`, circle-stdlib `4fbab62`). The sample 64-bit toolchain is `aarch64-none-elf` (`--aarch64`, GCC 15.2.Rel1 or LLVM 22.1.4).
- C library: [Newlib](https://sourceware.org/newlib/) through the fork `circle-newlib` (`README.md`, "Overview"). The submodule was not fetched, so the exact syscall coverage is **open**.
- C++ library: libstdc++ from the toolchain without platform parts, or libc++ with `--libcxx` (since v20, "currently experimental and optional"). With libc++ the README lists `std::thread`, `std::mutex`, `std::condition_variable`, `std::filesystem`, `thread_local` and `std::random_device`.
- **Threads are not POSIX threads.** `libs/libcxx-threading/src/thread.cpp` lines 90 to 215 builds each `std::thread` as a `CTask` of Circle's scheduler. `doc/multicore.txt` says that scheduler is cooperative, runs on one core and "should always run on core 0". A grep of circle-stdlib for `pthread` finds only mbed TLS configuration and a constant name in `thread.cpp`. No `pthread_*` API is implemented in the repository. For an emulator that wants its CPU, audio and video threads on separate cores, this is a hard limit. `std::thread` objects would all share core 0, unless the program starts work on other cores through `CMultiCoreSupport`.
- The `v21` entry in `CHANGELOG.md` says: "Synced with Circle Step 51.1.1".
- `doc/stdlib-support.txt` in Circle: "`STDLIB_SUPPORT=2` to build with C standard library too", "`STDLIB_SUPPORT=3` to build with C++ standard library too", "`STDLIB_SUPPORT=4` to build with external C++ standard library", with circle-stdlib as the project that provides options 2 to 4.

### Pi 4 comparison

Circle lists the Raspberry Pi 4 Model B, Pi 400 and CM4 as "Tested" (`README.md` lines 196 to 197 and 204). Differences that matter here:

- Interrupts: the Pi 4 supports FIQ, with a Circle-specific ARM stub (`armstub8-rpi4.bin`, `boot/README`). The Pi 5 supports IRQ only.
- Frame buffer: the Pi 4 has no listed restriction in the README. The 4K case needs `hdmi_enable_4kp60=1` (`doc/issues.txt`). The Pi 5 is "limited".
- USB: the Pi 4 xHCI controller sits behind a PCIe root complex of the SoC (`xhcidevice.cpp` lines 49 to 51, `m_PCIeHostBridge`), the Pi 5 one is inside RP1.
- Multicore and the `kernel8-rpi4.img` name come from `Rules.mk` lines 110 to 118: `kernel8` for the Pi 3 (64-bit), `kernel8-rpi4` for the Pi 4, `kernel_2712` for the Pi 5.

## 3. An SDL port for Circle

**Result: no maintained SDL port for Circle was found.**

What was checked (2026-10-21):

- `rsta2/circle` `7a81e1b` and `smuehlst/circle-stdlib` `4fbab62`: a recursive case-insensitive search for "sdl" finds only unrelated hits (`smimaster`, `ws2812oversmi`, `addon/lvgl/lv_conf.h`, a `package-lock.json`). The LVGL hit was not examined.
- GitHub repository search with several phrasings ("SDL circle raspberry bare metal", "circle-sdl", "SDL2 Circle bare metal", "SDL3 bare metal"). Nothing relevant came back.
- Issues in `rsta2/circle` matching "SDL": [#308 "multiple pthread definitions"](https://github.com/rsta2/circle/issues/308), [#359](https://github.com/rsta2/circle/issues/359) and [#145](https://github.com/rsta2/circle/issues/145). Only #308 is about SDL. The author writes: "I'm just a hobbyist programmer but am trying to port SDL2 to circle-stdlib." A comment dated 2022-08-08 says: "So far, I've commented out the references to pthreads in newlib in favor of the circle/addon/linux provided versions. At least I got minimal SDL to compile." The attempt builds on SDL's `src/video/raspberry` driver (Dispmanx, `vc4`), which does not exist on the Pi 5. No repository with the result was linked. Its state is **open**.
- The Circle discussion titles (list fetched through the GitHub GraphQL API, first 100) contain no SDL entry. The search covered titles only.
- Current SDL (`libsdl-org/SDL` `d0183f0`, directory `src/video`) has these backends: android, cocoa, directx, dos, dummy, emscripten, gdk, haiku, khronos, kmsdrm, n3ds, ngage, offscreen, openharmony, openvr, ps2, psp, qnx, raspberry, riscos, uikit, vita, vivante, wayland, windows, x11. `kmsdrm` needs the Linux DRM stack. The `dummy` and `offscreen` backends have no display output. A Circle backend would have to be written, which is a direct output to Circle's frame buffer plus input, audio and thread layers.

## 4. Other environments for the Pi 5

| Environment | Pi 5 status | Source |
|-------------|-------------|--------|
| **Ultibo** | No Pi 5 support found | `README.md` of `ultibohub/Core` (`5fe351e`, 2026-05-12) lists "Raspberry Pi (A/B/A+/B+/2B/3B/3B+/4B/400/Zero/ZeroW/Zero2W) plus QEMU ARM emulation". The platform units are `bcm2708`, `bcm2709`, `bcm2710`, `bcm2711` (`source/.../bcm27*.pas`). [Supported Hardware](https://ultibo.org/wiki/Supported_Hardware) lists the Pi A/B, Pi 2/3, Pi 4/400/CM4 and QEMU, nothing newer. A search of the Ultibo forum for "Raspberry Pi 5" returned 0 matches. A case-insensitive search of the clone for `2712`, `BCM2712` and "Raspberry Pi 5" found no code, only font data. Ultibo also lists "Standard C library support including BSD sockets and POSIX threads" and pre-emptive threading, so it is the better match for Previous on a Pi 4. Licence: LGPL v2.1 with a linking exception (`LICENSE`, [wiki](https://ultibo.org/wiki/Main_Page)). |
| **Zephyr** | Board `rpi_5` exists, minimal | [Board page](https://docs.zephyrproject.org/latest/boards/raspberrypi/rpi_5/doc/index.html) and `boards/raspberrypi/rpi_5/` (checked through the GitHub API). Blinky instructions: put `zephyr.bin` and `bcm2712-rpi-5-b.dtb` on the SD card with `kernel=zephyr.bin`. `rpi_5_bcm2712.dts` enables `uart10`, a GPIO LED, the GPIO controllers, a PCIe controller node and an entropy source. No USB, Ethernet or display node was seen in the file's `status` entries. Zephyr is an RTOS for microcontroller class work. |
| **RTEMS** | A BSP exists | The RTEMS source tree has `bsps/aarch64/raspberrypi5/` with `console/console.c`, `start/bspstarthooks.c`, `start/bspstartmmu.c`, `start/bspsmp-arm-psci-targetcpu.c` and `spec/build/bsps/aarch64/raspberrypi5/` with console, clock and SMP build items (GitHub tree listing, `RTEMS/rtems` `5c7281c`). That is UART, timer, MMU and SMP through PSCI. No USB or display driver is in that tree. |
| **seL4** | Kernel port exists | `src/plat/bcm2712/config.cmake` (`seL4/seL4` `d97d707`) declares platform `rpi5` with Cortex-A76. The [hardware list](https://docs.sel4.systems/Hardware/) names "Raspberry Pi 5B, BCM2712, Cortex-A76, AARCH64". seL4 is a microkernel, so every driver would be user-level code that does not exist for RP1 USB or HDMI as far as the sources read show. |
| **NetBSD** | Runs, with limits | [NetBSD/evbarm on Raspberry Pi](https://wiki.netbsd.org/ports/evbarm/raspberry_pi/): "NetBSD 10 supports the RPI 4 and RPI 5." and, for NetBSD 10 and current, "RPI5 general support (UEFI firmware required). Ethernet not working." A full OS with a kernel and a libc, not a bare-metal library. |
| **FreeBSD** | Not listed for the Pi 5 | The [FreeBSD 15.0 hardware notes](https://www.freebsd.org/releases/15.0R/hardware/) list the Raspberry Pi Zero 2 W, 3 and 4 (and the 14.3 notes list the 3 and 4). The Pi 5 does not appear. The FreeBSD source tree carries `bcm2712*.dts` files under `sys/contrib/device-tree/src/arm64/broadcom`, which says nothing about driver support. |
| **UEFI for the Pi 5** | Archived | [worproject/rpi5-uefi](https://github.com/worproject/rpi5-uefi) README: "This repository is no longer maintained and has been archived." Only tested on early BCM2712C1 boards. NetBSD needs a UEFI firmware, so this matters for that route. |
| **Hobby bare-metal projects** | Exist, no maturity claim | Found by GitHub search: [gaolaowai/tiny-os](https://github.com/gaolaowai/tiny-os) (Rust RTOS, "Raspberry Pi 5 (BCM2712 / Cortex-A76)"), [rishi-vinod/pi5-bare-metal-gpio](https://github.com/rishi-vinod/pi5-bare-metal-gpio) (C and assembly, controls "RP1 silicon registers directly") and [jlaportebot/lobster-os](https://github.com/jlaportebot/lobster-os) (Rust OS with "SMP, networking, display, USB, filesystem, and window manager"). Their READMEs were not read, and their claims are unverified. |
| **Unikraft and other unikernels** | **Open** | Unikraft's `plat/` directory (`unikraft/unikraft`) has `kvm`, `native` and `xen`, with no Raspberry Pi entry. No other unikernel with a Pi 5 target was found. Absence in a search is not proof of absence. |
| **Raspberry Pi bare-metal tutorials** | **Open** | No tutorial series for the Pi 5 with a primary source was found in the searches above. |

## 5. What is hard on the Pi 5 for bare metal

1. **RP1 sits behind PCIe.** The [RP1 datasheet](https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf) (build 2023-11-07, `rp1.pdf` text, chapter 1): "RP1 is a peripheral controller ... It connects to an application processor (AP) via a PCIe 2.0 x4 bus". Section 2.3.1: "The AP accesses Peripherals and Shared SRAM over PCIe as offsets from the assigned base addresses in BAR1 and BAR2 respectively." So every USB, Ethernet and GPIO register access goes through a PCIe window that someone has to configure. Circle's appendix says: "The RP1 peripherals are accessible automatically on entry into main() in Circle applications. No specific action is necessary for this purpose." That means the firmware has done the PCIe bring-up before the kernel starts, and a bare-metal image can use it. Who else has to do it, and what a different environment would need to program, is **open**.
2. **RP1 documentation is public but limited.** The RP1 peripherals datasheet is a Creative Commons Attribution-NoDerivatives document with a legal notice that permits use "solely in conjunction with the Raspberry Pi products". It covers system description, low speed peripherals, SDIO, USB (xHCI, "Synopsys IP dwc_usb3, v3.30b"), the PCIe endpoint, Ethernet ("Cadence Gigabit Ethernet MAC (GEM_GXL 1p09)") and DSI/CSI hosts, and DMA. The Ethernet chapter points to a Cadence user guide that is not part of the datasheet. RP1 has two Cortex-M3 processors ([Raspberry Pi documentation](https://www.raspberrypi.com/documentation/computers/io-controllers.html), `io-controllers/rp1.adoc`), which the datasheet text read here does not describe as programmable by the user (**open**).
3. **No public BCM2712 datasheet found.** The [product brief](https://datasheets.raspberrypi.com/rpi5/raspberry-pi-5-product-brief.pdf) gives the feature list. The documentation index at datasheets.raspberrypi.com did not list a BCM2712 peripheral datasheet in the search done here. Circle works against the firmware and its device tree for the parts of the SoC that are not documented. This is **open** and could be wrong, since the index page was searched only for keywords.
4. **VideoCore VII is not documented publicly.** [Mesa V3D documentation](https://docs.mesa3d.org/drivers/v3d.html): "Broadcom never released a public specification for the V3D 3.x or 4.x series." and "Developers with NDA access with Broadcom or Raspberry Pi can get access to the V3D architecture specification". Mesa's V3D 7.1 driver (Pi 5) is open source, but it talks to a Linux DRM kernel driver ("The V3D Mesa drivers communicate directly with the V3D kernel DRM driver for scheduling GPU commands"), so a bare-metal use of the GPU would mean porting the kernel side too. Circle has no 3D support on the Pi 5 (see the table in section 2).
5. **The display path is owned by the firmware.** Circle appendix: no `config.txt` display configuration and no resolution selection from the application. The Pi 5 firmware is also embedded in the EEPROM, which Previous cannot change.
6. **Wi-Fi next to HDMI** is "delicate" on the Pi 5 (`doc/issues.txt`).
7. **FIQ is not available** on the Pi 5 (README line 100).
8. **Hardware revision steps.** Circle needs a specific DTB and `bcm2712d0.dtbo` for the D0 stepping and says the README tests "With BCM2712 C1 and D0 steppings" (line 198).

## Raspberry Pi 5 support per peripheral

Entries are "Yes", "Limited", "No" or "Open" (not verified in the sources read), with the source in the sections above. Zephyr, RTEMS and seL4 are listed from the board files and directory listings only, so "No" there means "no driver seen in the files listed", not "impossible".

| Peripheral | Circle (with circle-stdlib) | Ultibo | Zephyr `rpi_5` | RTEMS `raspberrypi5` | seL4 `rpi5` | NetBSD 10 / current |
|------------|-----------------------------|--------|----------------|----------------------|-------------|---------------------|
| Pi 5 supported at all | Yes (Step 46 on) | No | Yes (minimal) | Yes (minimal) | Yes (kernel only) | Yes (UEFI required) |
| AArch64 | Yes (only mode) | No | Yes | Yes | Yes | Yes |
| Four cores | Yes (PSCI, `multicore.cpp`) | No | Open | Yes (PSCI file present) | Open | Open |
| MMU and caches | Yes | No | Open | Yes (`bspstartmmu.c`) | Yes | Yes |
| FPU and NEON | Open | No | Open | Open | Open | Open |
| HDMI frame buffer | Limited (resolution set by firmware) | No | No | No | No | Open |
| Frame buffer double buffering, vsync | Open | No | No | No | No | Open |
| 3D (OpenGL ES, Vulkan) | No | No | No | No | No | Open |
| USB host (RP1 xHCI) | Yes | No | No | No | No | Open |
| USB keyboard and mouse | Yes | No | No | No | No | Open |
| USB mass storage | Yes | No | No | No | No | Open |
| SD card with FAT | Yes (FatFs) | No | Open | No | No | Open |
| Ethernet (RP1 GEM) | Yes | No | No | No | No | No ("Ethernet not working") |
| Wi-Fi | Yes (with HDMI caveat) | No | No | No | No | Open |
| HDMI audio | Yes (Step 48) | No | No | No | No | Open |
| I2S audio | Yes (Step 47) | No | No | No | No | Open |
| PWM audio | With an external circuit | No | No | No | No | Open |
| Timers and interrupts | Yes (IRQ only, no FIQ) | No | Open | Yes | Yes (GIC v2) | Yes |
| UART | Yes | No | Yes (`uart10`) | Yes (`console.c`) | Open | Open |
| NVMe over PCIe | Experimental | No | PCIe controller node only | No | No | Open |
| C and C++ standard library | Newlib, libstdc++ or libc++ through circle-stdlib | Own RTL, C library and C++ library (Pi 4 and older only) | Zephyr's own libc | Newlib | Out of scope | Full libc |
| POSIX threads | No (`std::thread` over cooperative scheduler on one core) | Yes on Pi 4 and older, not Pi 5 | Open | Open | Out of scope | Yes |
| SDL | No port found | No port found | No | No | No | Open (would use the full OS) |
| Licence | GPLv3 | LGPL v2.1 with linking exception | Open (not verified in this paper) | Open (not verified in this paper) | GPLv2 for the kernel (header of `config.cmake`: `GPL-2.0-only`) | Open (not verified in this paper) |

## Open points to settle next

- Whether double buffering with `SetVirtualOffset` and `WaitForVerticalSync` works on a Pi 5 and which resolutions the firmware offers without `config.txt` display options.
- Whether the licence of Previous is compatible with GPLv3 code from Circle.
- FPU and NEON state in Circle on the Pi 5.
- Whether a core other than core 0 can run a `CTask` scheduler of its own, since the documented rule is "should always run on core 0".
- Source and licence of the Newlib fork used by circle-stdlib.
