Skip to content
Haiku OSDeep Dive Published Updated 7 min readViews unavailable

Haiku on ARM: Porting Challenges Without Pretending It Is a Finished Product

An evidence-based guide to Haiku's separate ARM and ARM64 ports, their boot and driver work, build targets, and honest support claims.

Saying that an operating system “supports ARM” can conceal more than it explains. ARM names an instruction-set family used in many different system-on-chip designs, not a single standardized computer platform comparable to the conventional x86 PC. Haiku’s own internals documentation explicitly distinguishes a 32-bit ARM port from a 64-bit ARM port and notes that they do not share much code because the architectures differ substantially. A toolchain that emits ARM instructions is therefore only the opening requirement, not proof of a usable Haiku system.

The practical questions are narrower: Which architecture? Which board or virtual machine? Which firmware interface? Can it boot repeatedly, enumerate memory, route interrupts, keep time, access storage, and provide input and display output? Can it run enough userland to test real applications? A responsible port-status report names those conditions instead of converting one successful boot log into a broad compatibility promise.

Why ARM is not one hardware target

The official ARM-port overview identifies the lack of a PC-like platform standard as a central difficulty. On ARM systems, a timer, interrupt controller, serial port, boot sequence, and peripheral layout may differ from one machine to another. More recent standards and common firmware practices reduce some variation, but a kernel still needs an accurate description of the particular platform and drivers for the devices it will use.

Early boot code must establish enough execution state to enter the kernel safely. The kernel then needs a memory map, exception and interrupt handling, timing sources, and a route to diagnostic output. Device trees can describe hardware supplied by the bootloader, allowing some platform information to be data rather than compiled board assumptions. Haiku’s port notes nevertheless document board-specific history and unfinished work to separate ARM architecture code from system-on-chip details.

That distinction is vital. Architecture support covers matters such as registers, page tables, atomic operations, context switching, and exception entry. Platform support handles firmware handoff and board-level components. Device support adds storage controllers, USB hosts, network devices, graphics, audio, and other peripherals. A system can be correct at one layer and unusable because the next layer remains incomplete.

ARM and ARM64 are separate engineering efforts

The 32-bit and 64-bit ports use different target names in Haiku’s build tooling: arm and arm64. The official build guides provide separate procedures for creating their cross-compilers. That is not cosmetic naming. Pointer width, virtual-memory layout, exception models, calling conventions, and toolchain targets differ, so a fix for one port should not be advertised automatically as a fix for the other.

The 32-bit port documentation also records constraints around older ARM generations, atomics, floating-point variants, and compiler multilib behavior. Those details show why “ARM” cannot be treated as a lowest-common-denominator binary target without cost. Choosing an instruction baseline changes both the hardware that can execute the system and the kernel or compiler work required to provide operations the hardware lacks.

ARM64 removes some historical variation at the instruction-set level, but it does not make board enablement automatic. A 64-bit kernel still requires compatible firmware, interrupt and timer support, memory discovery, and device drivers. Conversely, a virtual ARM64 machine can offer standardized virtual devices that are much easier to support than the peripherals of an arbitrary consumer board. Success in virtualization proves the architecture and selected virtual platform path; it does not imply that every ARM64 laptop or single-board computer will boot.

What the official build procedure actually proves

Haiku’s current ARM and ARM64 build guides use an out-of-tree generated directory and the repository’s configure script. The documented toolchain steps are:

mkdir generated.arm
cd generated.arm
../configure -j2 --cross-tools-source ../../buildtools --build-cross-tools arm

and, separately:

mkdir generated.arm64
cd generated.arm64
../configure -j2 --cross-tools-source ../../buildtools --build-cross-tools arm64

The relative path to buildtools must match the developer’s actual checkout layout; the guides explicitly tell readers to adjust options for their environment. After the cross-tools exist, both guides document jam -j2 -q @minimum-mmc as a way to build a minimal MMC image for their respective configured target.

These commands prove useful but limited facts. A successful cross-toolchain build confirms that host tools and target compiler components were produced. A successful image target confirms that Jam assembled the selected target and its dependencies into an image. Neither result establishes that firmware can load the image, the kernel can initialize the platform, or the resulting userland can access a given board’s storage and peripherals.

The guides also present QEMU examples using virtual hardware and TianoCore firmware. QEMU is valuable because it makes the emulated machine definition repeatable and provides a serial console for early diagnostics. It is a controlled reference environment, not a substitute for board testing. Exact QEMU arguments, firmware paths, and generated image names should be taken from the guide corresponding to the configured architecture because the ARM and ARM64 examples are not interchangeable.

Milestones from first instruction to useful desktop

A port should be described through observable milestones. The first is toolchain viability: target objects link with the intended ABI and the boot components have the executable format expected by firmware. Next comes controlled early output, often over a serial console, so failures before graphics initialization are visible.

Kernel entry is only the beginning. Physical and virtual memory management must survive allocation pressure. Interrupts and a timer must work well enough for scheduling and timeouts. Context switching must preserve all required architectural state. The kernel debugger is particularly valuable at this stage because ordinary user-space diagnostics may not exist yet.

After that comes a usable device path. The system needs a boot medium or virtual disk, a filesystem, and enough driver support to start userland. USB input, networking, and graphics are later independent milestones. Reaching a shell demonstrates far more than printing a boot banner, but it still does not demonstrate a complete graphical desktop or broad hardware compatibility. Starting the desktop on a particular virtual machine is stronger again, yet reliability, power management, installation, package updates, and real-board devices remain separate tests.

Recording these stages prevents regressions from being hidden by vague labels. A matrix can state, for each exact target, whether firmware handoff, serial output, kernel debugger, SMP, storage, USB, network, framebuffer, acceleration, audio, and installation are working, partial, or untested. “Experimental” then becomes a useful summary backed by evidence rather than a disclaimer with no detail.

Board support depends on firmware and drivers

The official overview links notes for several hardware families accumulated during the port’s history, including multiple Raspberry Pi generations, BeagleBone Black, and Allwinner-based hardware. The presence of notes is not a release guarantee. Documentation may capture experiments, required boot files, serial configuration, or historical limitations without claiming that a current Haiku release offers complete support.

Firmware is part of the compatibility statement. A board may boot through U-Boot, UEFI/TianoCore, or a vendor-specific sequence; it may supply a flattened device tree or expect platform code to know fixed addresses. Even boards sold under one family name can revise their system-on-chip or peripheral controllers. An image tested on one board revision and firmware version should be reported with those identifiers.

Drivers are equally specific. The kernel can schedule ARM64 code correctly and still lack the SD controller needed to find its packages. A framebuffer can display a desktop without any accelerated graphics support. A USB controller driver may work while an attached Wi-Fi device has no compatible network driver. These partial successes are worth reporting accurately, but combining them into “the board is supported” removes the information users and developers need.

How to report progress without overstating it

Start every report with the architecture and target, for example “ARM64 under QEMU virt” rather than “Haiku ARM.” Record the Haiku revision, buildtools revision, configure options, image target, firmware build, emulator version or board revision, and the exact working devices. Preserve the serial log for failures and describe whether the result is reproducible from a clean generated directory.

Separate build status from runtime status. “The @minimum-mmc target completed” is a build result. “TianoCore loaded the image and the kernel reached the debugger” is a boot result. “The desktop started with keyboard, storage, and network under QEMU” is a platform result. None should silently become a general release-support claim.

Finally, use Haiku’s current port and build documentation rather than copying an old command from a forum post. Porting pages can contain explicit TODOs and historical notes; those are valuable evidence of open work, not embarrassment to be edited out of the story. The honest conclusion is that Haiku has real ARM and ARM64 engineering, build infrastructure, and documented experimental paths, while usefulness remains dependent on a named platform and its implemented subsystems.

Related:

Sources:

Comments