summaryrefslogtreecommitdiff
path: root/include/boot.h
diff options
context:
space:
mode:
authorBradley Morgan <brads@mainlining.org>2026-10-03 18:57:38 +0000
committerBradley Morgan <brads@mainlining.org>2026-10-03 18:57:38 +0000
commit00fc82f17cff9295387d516384ecdc443acb1b22 (patch)
tree798bef0185878286028fe0eaf7594616a66903e4 /include/boot.h
parent7e8514efb64774b6a635b87ae945e519a7c38551 (diff)
tashaboot: arm64 bringup, semihosting payload loader
consoles on the pl011 the dtb points at, walks the memory node and chosen, loads an arm64 kernel Image over semihosting and jumps to it with the documented register state. string functions, printf and libfdt are vendored from lk (lk2nd) and u-boot so the libc surface is the one those projects already proved. built and booted on qemu virt, payload exits clean through semihosting.
Diffstat (limited to 'include/boot.h')
-rw-r--r--include/boot.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/include/boot.h b/include/boot.h
new file mode 100644
index 0000000..34bfa88
--- /dev/null
+++ b/include/boot.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __BOOT_H
+#define __BOOT_H
+
+#include <sys/types.h>
+#include <stdint.h>
+
+/*
+ * payload loading and the arm64 boot protocol. See Documentation/
+ * arch/arm64/booting.rst in the kernel tree for the register contract
+ * we honour when jumping.
+ */
+
+#define LINUX_ARM64_IMAGE_MAGIC 0x644d5241
+
+/* the 64 byte header every arm64 kernel Image starts with */
+struct Image_header {
+ uint32_t code0; /* Executable code */
+ uint32_t code1; /* Executable code */
+ uint64_t text_offset; /* Image load offset, LE */
+ uint64_t image_size; /* Effective Image size, LE */
+ uint64_t flags; /* Kernel flags, LE */
+ uint64_t res2; /* reserved */
+ uint64_t res3; /* reserved */
+ uint64_t res4; /* reserved */
+ uint32_t magic; /* Magic number */
+ uint32_t res5;
+};
+
+struct tb_image {
+ uintptr_t ep; /* entry point to jump to */
+ uint64_t size; /* image size in bytes */
+ uintptr_t load; /* address the image was placed at */
+};
+
+/*
+ * validate the header at image and work out where it wants to live.
+ * returns 0 and fills img on success, negative on a bad image.
+ */
+int tb_image_setup(uintptr_t image, uintptr_t mem_base, uint32 mem_size,
+ struct tb_image *img);
+
+/*
+ * load the payload from semihosting into mem_base. returns 0 and fills
+ * img, negative when there is no debugger or no file.
+ */
+int tb_load_semihosting(const char *fname, uintptr_t load_addr,
+ uintptr_t mem_base, uint32 mem_size,
+ struct tb_image *img);
+
+/*
+ * jump to the kernel: x0 = dtb, x1 = x2 = x3 = 0. never returns.
+ */
+void __NO_RETURN tb_boot_linux(uintptr_t ep, const void *dtb);
+
+#endif