My Haiku ARM (UEFI) port progress

I feel that working with bare virtual hardware is easier and productive than fightning with firmware.

I give an idea:

_start.S

.global _start
_start:
    ldr x5, =STACK_TOP
    mov sp,x5
    bl start
1:
    b 1b
.size _start, . - _start

start.c

#include <stdint.h>
#include <stddef.h>

#define UART0_BASE 0x09000000

void WriteChar(char ch)
{
	*(volatile uint32_t *)(UART0_BASE) = ch;
}

void WriteString(const char *str)
{
	for (const char *ch = str; *ch != '\0'; ch++)
		WriteChar(*ch);
}

void WriteLn()
{
	WriteChar('\n');
}

void WriteInt(int64_t val)
{
	if (val == -9223372036854775807LL - 1) WriteString("-9223372036854775808");
	else if (val < 0) {WriteString("-"); WriteInt(-val);}
	else {
		if (val > 9) WriteInt(val/10);
		WriteChar(val%10 + '0');
	}
}

void WriteHex(uint64_t val, int n)
{
	if (n > 1 || val > 0xf) WriteHex(val/0x10, n - 1);
	val = val%0x10;
	if (val <= 9) WriteChar(val + '0');
	else WriteChar(val - 10 + 'A');
}

void Recursion(int n)
{
	WriteString("+"); WriteInt(n); WriteLn();
	if (n > 0) Recursion(n - 1);
	WriteString("-"); WriteInt(n); WriteLn();
}

void start(void *fdt) {
	WriteString("This is a test\n");
	WriteString("123\n");

	WriteHex(0x12345678, 8); WriteLn();
	WriteHex(0x87654321, 8); WriteLn();
	WriteInt(-123456789); WriteLn();
	
	Recursion(4);

	WriteString("fdt: "); WriteHex((size_t)fdt, 8); WriteLn();
	WriteString("fdt[0]: "); WriteHex(*((uint32_t*)fdt + 0), 8); WriteLn();
	WriteString("fdt[1]: "); WriteHex(*((uint32_t*)fdt + 1), 8); WriteLn();

	for (;;) {}
}

linker.ld

ENTRY(_start)
 
SECTIONS {
   . = 0x40000000;
 
    /* Make sure our entry stub goes first */
    .stub   : { _start.o(.text) }
    .text   : { *(.text) }
    .rodata : { *(.rodata) }
    .data   : { *(.data) }
    .bss    : { *(.bss COMMON) }
 
    STACK_BASE = .;
    . += 0x10000;
    STACK_TOP = .;
}

Build with following commands:

clang --target=aarch64-linux-gnu -ffreestanding -fpic -c _start.S
clang --target=aarch64-linux-gnu -ffreestanding -fpic -c start.c
ld.lld -T linker.ld _start.o start.o -o start
llvm-objcopy -O binary start start.bin

Run with:

qemu-system-aarch64 -M virt -cpu cortex-a57 -kernel start.bin -nographic

Output:

This is a test
123
12345678
87654321
-123456789
+4
+3
+2
+1
+0
-0
-1
-2
-3
-4
fdt: 44000000
fdt[0]: EDFE0DD0
fdt[1]: 00001000

All operations can be done from Haiku.

10 Likes