Skip to content

aarch64 raspi bcm2711 boot - #971

Merged
Kalamatee merged 12 commits into
aros-development-team:masterfrom
bsek:bsek/aarch64-raspi-bcm2711-boot
Aug 9, 2026
Merged

aarch64 raspi bcm2711 boot#971
Kalamatee merged 12 commits into
aros-development-team:masterfrom
bsek:bsek/aarch64-raspi-bcm2711-boot

Conversation

@bsek

@bsek bsek commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

aarch64-raspi: boot on the Raspberry Pi 4

Brings up the BCM2711 far enough to boot: timer, memory map, bootstrap
memory primitives and the framebuffer.

Device tree instead of assumption. entropy.resource and usb2otg probed
hardware unconditionally, which on a BCM2711 means poking cores that are not
there.

Timer. The microhz tick comes from VBlank on BCM2711; the system timer
does not raise the interrupt the earlier SoCs deliver.

Memory. The bootstrap read only the first memory range the tree reports,
so a Pi 4 came up with a fraction of its RAM. It now reads them all, and the
system pool is no longer declared as chip memory. The pre-MMU bootstrap also
got alignment-safe mem* primitives — the compiler was emitting unaligned
accesses into memory that cannot take them yet.

Framebuffer. The VideoCore framebuffer is handed to the kernel by the
bootstrap. The HIDD that paints into it moves from the SoC directory to the
board and is renamed fbgfx, since it is a plain linear-framebuffer driver
with nothing VideoCore-specific left in it. It now also detaches the
bootstrap's console on takeover, instead of both drawing into the same pixels.

The fbgfx commit is dominated by file renames — the diff is larger than the
change.

bsek added 12 commits August 9, 2026 17:45
BCM2711 puts an RNG200 at the BCM2835 block's address, with different
registers, and a machine whose firmware disabled the node may not decode
it at all - the Pi 4 aborts on the first write. Check the node before
touching the hardware, and fall back to the software source.
On BCM2711 the OTG core serves the USB-C socket, which the firmware
leaves powered down - the USB-A ports hang off a PCIe xHCI controller
instead. Driving it there hangs the core during the ROM USB startup.
It kept the deepest node that did match and carried on, so asking for a
node the machine does not have returned an ancestor - which reads as
success and leaves the caller inspecting the wrong node. Return NULL
instead, as dt_find_node() in the kernel already does, and stop tracing
every lookup by default.
dt_find_node() printed the key, the root and every node it walked past
on every call, unconditionally, on both arm and aarch64.
Unit addresses in node names are bus addresses and move between SoC
generations: the Broadcom RNG is rng@7e104000 on a Pi 3 and rng@7d208000
on a Pi 5, and the OTG core's node is absent entirely on BCM2712. A
driver keyed on the path stops matching, and the usb2otg gate then read
that as "no description, probe anyway" - on hardware that has no such
core. Add OF_FindNodeByCompatible() and key both gates on the binding.
The system timer's compare match is not delivered on the Pi 4, so
handleMicroHZ() never ran and every Delay() and interrupt-driven DoIO()
hung. The kernel already causes INTB_VERTB from the ARM generic timer,
so drive the tick from there as well. Each tick derives its delta from
the free-running counter, so both sources firing is harmless.
The bootstrap already brings the mailbox framebuffer up, so pass its
geometry on in the boot taglist and expose it through KrnGetSystemAttr.
vcgfx wraps that surface and takes the display on BCM2711, where vc4gfx
now bows out: it drives the BCM283x HVS and pixel valves directly, and
BCM2711 rearranges all of it. One kickstart still serves both boards.

Based on work by John Knipper.

# Conflicts:
#	compiler/include/aros/kernel.h
A /memory node holds a list of (address, size) tuples, and the Pi 4
firmware describes anything past the first GB as its own entry, so a
board with more than 1GB lost everything above it. Walk the whole
property, map each range, and emit a KRN_MEMLower/KRN_MEMUpper pair per
range. The kernel keeps the first as its primary header - that is where
it was loaded - and gives each of the others one of their own.
It was flagged MEMF_CHIP as well as MEMF_FAST, so AvailMem() reported
the same RAM under both headings and Wanderer showed it twice. The
32-bit RasPi port describes the identical SoC without MEMF_CHIP, and
platform_init.c strips the flag from AllocMem() anyway.
…trap

With the MMU off every access is Device memory and must be aligned, but
the C library memset/memcpy use NEON stores that fault there. The
bootstrap now carries its own byte-safe versions; without them the Pi 4
took an alignment fault (ESR DFSC 0x21) before it reached query_memory.

Based on work by John Knipper.
It sat in arch/aarch64-native/hidd, the CPU tier, which by the layout the
arm port established holds CPU code: SoC drivers live under soc/, board
code under <cpu>-<board>/. The driver touches no VideoCore register - it
wraps whatever linear surface the kernel reports - so soc/broadcom would
be wrong too, and its only real dependency is the raspi bootstrap that
fills those attributes in. Hence the board tier, and a name describing
what it does rather than what it talks to.

# Conflicts:
#	arch/aarch64-raspi/boot/mmakefile.src
The bootstrap hands the kernel a putchar that draws into the framebuffer,
and krnPutC feeds every bug() to it as well as to the serial line - so
driver debug output kept painting over the screen Workbench was using.
Send 0x03, which drops that putchar, the way vc4gfx already does on the
BCM283x boards.
@Kalamatee
Kalamatee merged commit c4e3236 into aros-development-team:master Aug 9, 2026
2 of 3 checks passed
@bsek
bsek deleted the bsek/aarch64-raspi-bcm2711-boot branch August 9, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants