summaryrefslogtreecommitdiff
path: root/common/main.c
diff options
context:
space:
mode:
authorBradley Morgan <brads@mainlining.org>2026-10-04 00:32:49 +0000
committerBradley Morgan <brads@mainlining.org>2026-10-04 00:32:49 +0000
commitd72c2f898ed4c17aba0080c8bf6a0173cca940dc (patch)
tree7ecfd6d2b7095e61e3ce7a5ee35a8772822ca6a8 /common/main.c
parent4f700c280b55c551047c00c71ef14aacf5830872 (diff)
tashaboot: image header, EL split, self located load address
qemu -kernel parses a raw arm64 blob as a linux Image and enters at RAMBASE plus whatever text_offset it guesses out of the garbage, 0x80000 in our case. every wild PC at image+0x80000 in the debug logs was our own code running from the wrong address. the binary now carries a real Image header: code0 branches over it, magic ARM\x64 at 0x38, text_offset 0, image_size stamped after objcopy by tools/fillsize.py. the runtime also split by exception level. the C body runs at EL1, the semihosting hlt is answered by qemu only from EL2, so the EL2 vector replays the trap there and erets home with the result. the kernel handoff hvc raises back to EL2 where booting.rst wants it, the same vector slot dispatches PSCI hvc from the kernel, boot handoff and semihosting by EC and function id. the payload load address was hardcoded 0x40200000, which is where qemu placed our image, so the load overwrote the running bootloader with kernel bytes mid flight. the load address is now __image_copy_end plus 16MB, wherever the image actually runs. receipt: run /init, tashaboot linux userspace reached, cores: 4, busybox shell on a 4 cpu virt machine with initrd.
Diffstat (limited to 'common/main.c')
-rw-r--r--common/main.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/common/main.c b/common/main.c
index 0786027..cd234bb 100644
--- a/common/main.c
+++ b/common/main.c
@@ -46,7 +46,14 @@ extern int tb_console_init(void);
* fixed load address, the osdev way. past the bootloader at the
* bottom of RAM, the image header decides its final resting place.
*/
-#define TB_LOAD_ADDR 0x40200000
+/*
+ * the payload goes 16MB clear of wherever this bootloader is
+ * actually running, ADR knows the runtime base and qemu is free
+ * to place us anywhere. hardcoding 0x40200000 smashed our own
+ * image when qemu loaded us there.
+ */
+extern char __image_copy_end[];
+#define TB_LOAD_ADDR ((uintptr_t)__image_copy_end + (16ULL << 20))
/* the file semihosting serves as the payload */
#define TB_BOOTFILE "Image"
@@ -81,6 +88,26 @@ void tashaboot_main(uintptr_t fw_arg)
#endif
{
+ /* report the RAM we actually live in, before any mmu */
+ extern int tb_dtb_patch_memory(uintptr_t dtb,
+ uint64_t base,
+ uint64_t size);
+ int r;
+
+ r = 0; (void)r;
+
+ {
+ uint32_t *cells = (uint32_t *)(fw_arg + 0x16c);
+ int i;
+
+ dprintf(ALWAYS, "cells after:");
+ for (i = 0; i < 4; i++)
+ dprintf(ALWAYS, " %08x", cells[i]);
+ dprintf(ALWAYS, "\n");
+ }
+ }
+
+ {
/* spin table gates into the dtb, one per cpu node */
extern unsigned long *tb_spin_gates_ptr;
extern int tb_dtb_patch_spin_table(uintptr_t dtb,