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.