My Haiku ARM (UEFI) port progress

I have compared the arm linker script with x86/x86_64, they look almost the same, but much different with riscv64. maybe we need different kernel linker scripts for efi and other platforms, u-boot, bios etc.

No. Kernel loading code is the same for all platforms. In my RISC-V port the same kernel file and OS image can be loaded by haiku_loader.riscv (bare metal firmware) and haiku_loader.efi (for UEFI-compatible firmware). x86_64 Haiku can be also loaded by both BIOS and UEFI.

Linker script depends on architecture, but not platform.

OK, so The problem is only about the linker script segments defines and compiler configs :wink:

I managed to get some serial output for kernel on ARM32:

Calling ExitBootServices. So long, EFI!
VirtioNetExitBoot: Context=0x4DECB110
VirtioBlkExitBoot: Context=0x4EF74190
VirtioBlkExitBoot: Context=0x4EF7D710
SetUefiImageMemoryAttributes - 0x000000004F928000 - 0x0000000000006000 (0x0000000000000000)
SetUefiImageMemoryAttributes - 0x000000004F922000 - 0x0000000000006000 (0x0000000000000000)
SetUefiImageMemoryAttributes - 0x000000004F91C000 - 0x0000000000006000 (0x0000000000000000)
SetUefiImageMemoryAttributes - 0x000000004F915000 - 0x0000000000007000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000004F90C000 - 0x0000000000009000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000004F900000 - 0x000000000000C000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000004F8FA000 - 0x0000000000006000 (0x0000000000000000)
SetUefiImageMemoryAttributes - 0x000000004F8F4000 - 0x0000000000006000 (0x0000000000000000)
Kernel entry point
Welcome to kernel debugger output!
Haiku revision: hrev55144+82+dirty, debug level: 2
INIT: init CPU
INIT: init interrupts
INIT: init VM
PANIC: vm_allocate_early: could not allocate virtual address

Welcome to Kernel Debugging Land...
Running on CPU 0
Current thread pointer is 0x4c23c848, which is an address we can't read from.
frame            caller     <image>:function + offset
 0 4c1f15c4 (+   0) 00000021   

I enabled -fpic, -shared like in riscv64, used riscv64 linker script keeping ARM part at beginning, and identity mapping (set vaddr to addr in platform_allocate_region()).


:wink: great, I have got the same result, compiled with the same link script without header, and enable -fpic and -shared.

So we can just replace the link script contents with riscv64, but do we need some more thinking? :frowning:

I don’t know why, I know you script made it @X512 :wink:

1 Like

I think that riscv64 version will be fine until some issues will be found (random crashes in unrelated places etc.).

It will be nice to write page table setup code like this. It will allow to use existing ARM kernel VMTranslationMap code. Otherwise kernel-user address range swapping (declared here) and kernel page table code adjustments will be needed.

That will require ARM versions of LookupPte() and Map() functions. riscv64 version:

static Pte*
LookupPte(addr_t virtAdr, bool alloc)
	Pte *pte = (Pte*)VirtFromPhys(sPageTable);
	for (int level = 2; level > 0; level --) {
		pte += PhysAdrPte(virtAdr, level);
		if (!((1 << pteValid) & pte->flags)) {
			if (!alloc)
				return NULL;
			pte->ppn = AllocPhysPage() / B_PAGE_SIZE;
			if (pte->ppn == 0)
				return NULL;
			memset((Pte*)VirtFromPhys(B_PAGE_SIZE * pte->ppn), 0, B_PAGE_SIZE);
			pte->flags |= (1 << pteValid);
		pte = (Pte*)VirtFromPhys(B_PAGE_SIZE * pte->ppn);
	pte += PhysAdrPte(virtAdr, 0);
	return pte;

static void
Map(addr_t virtAdr, phys_addr_t physAdr, uint64 flags)
	// dprintf("Map(0x%" B_PRIxADDR ", 0x%" B_PRIxADDR ")\n", virtAdr, physAdr);
	Pte* pte = LookupPte(virtAdr, true);
	if (pte == NULL)
		panic("can't allocate page table");

	pte->ppn = physAdr / B_PAGE_SIZE;
	pte->flags = (1 << pteValid) | flags;

Produced page table should be passed to arch_start_kernel() and applied there.

Some information about ARM32 page tables: ARM Paging - OSDev Wiki.


Good day,

I’lm interested on the progress of this port to ARM. Planning on getting a Pinebook Pro, which uses an ARM Hexa-Core Rockchip RK3399, 4GB RAM, and with option to add an NVMe drive, to do some tinkering.

It would be nice to test ARM Port on such device once it becomes available again.


I have a Pinebook Pro, myself. I’d also like to see Haiku on it. The only point of disagreement with me is that the NVMe adapter draws more power than the current model of PBP can source with its battery pack when used. I’d rather see a small FPGA board to accelerate legacy graphics cores like the AGA chipset from my Commodore Amiga 1200 via the MiniMig core. Building up something modern using an Intel Cyclone 10 series could start using drivers for that. Its core is fully reverse engineered already, though dated.

Actually, the Mali Bifrost driver is open source now also. A 3D booster might be better based on its design.

1 Like

Thanks for pointing out this issue. Then I rather stay away from it for this project.

I am interested to give a hand, if I can. Have very little hardware/bare metal experience, but I am ready to learn. Not sure where to start though.

Same here except my 64-bit ARM is a PineBook Pro, as mentioned, with a RockChip Rk3399. I have several ARM7 32 bit machines as well: ODroid XU4, Cubox i4p and Raspberry Pi 2.

First you need to reproduce existing result (getting kernel loaded and receive serial output).

You need to setup build environment:

git clone
git clone
cd haiku
mkdir generated.arm
cd generated.arm
../configure -j4 --build-cross-tools arm --cross-tools-source ../../buildtools --distro-compatibility official
jam -q -j4 @minimum.image-raw haiku-minimum.image esp.image

And then run:

qemu-system-arm -bios qemu-uefi-aarch32.bin -M virt -cpu cortex-a15 -m 1024 -hda esp.image -hdb haiku-minimum.image -device ramfb -usb -device qemu-xhci,id=xhci -device usb-mouse -device usb-kbd -serial stdio

Instruction may be inaccurate or incomplete, please ask if something is gone wrong.


i have a error in Jam

Build profile minimum.image-raw not defined.

How to define this thing

1 Like

I think the last command should be:

jam -q -j4 @minimum-raw haiku-minimum.image esp.image

I was able to compile for ARM! I ran qemu with qemu-system-arm -bios /usr/lib/u-boot/qemu_arm/u-boot.bin -M virt -cpu cortex-a15 -m 1024 -hda esp.image -hdb haiku-minimum.image -device ramfb -usb -device qemu-xhci,id=xhci -device usb-mouse -device usb-kbd -serial stdio and was able to see the Haiku boot menu in the console! It was a very exciting moment. However, it couldn’t find any boot volumes. Did I miss something?


What does it mean exactly? Boot loader may require selecting boot volume before “continue booting” become active.

It says:

Welcome to the
Haiku Boot Loader
Copyright 2004-2020 Haiku, Inc.

Select boot volume (Current: None)
Select safe mode options
Select debug options
Select video mode (Current: None)

Cannot continue booting (Boot volume is not valid)
1 Like

What happens if open this menu?

Select Boot Volume

<No boot volume found>

Rescan Volumes
Return to main menu

“Rescan Volumes” just goes back to the prior menu, it seems.

Can you replace “-hda esp.image -hdb haiku-minimum.image” with

	-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \
	-device virtio-blk-device,drive=x1,bus=virtio-mmio-bus.1 \
	-drive file="esp.image",if=none,format=raw,id=x0 \
	-drive file="haiku-minimum.image",if=none,format=raw,id=x1 \


1 Like