From 5ff54a875642962fc857cee00bde17f9a465f1fa Mon Sep 17 00:00:00 2001 From: Bradley Morgan Date: Sun, 4 Oct 2026 10:42:10 +0000 Subject: tashaboot: arm64 bootloader holy shit it's here, Tashaboot, based from arm arm, enjoy reading this masterpiece Signed-off-by: Bradley Morgan --- common/image.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 common/image.c (limited to 'common/image.c') diff --git a/common/image.c b/common/image.c new file mode 100644 index 0000000..640eab4 --- /dev/null +++ b/common/image.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * image.c - arm64 kernel Image validation and placement. + * + * The relocation rules are the ones from the kernel boot protocol, + * including the pre a2c1d73b94ed quirks, same math u-boot's + * booti_setup() runs. + * + * Copyright (C) 2026 Bradley Morgan + */ + +#include +#include +#include +#include + +#define LINUX_ARM64_IMAGE_MAGIC 0x644d5241 /* "ARM\x64" */ + +#define SZ_16M 0x01000000 +#define SZ_2M 0x00200000 + +/* the 64 byte header from Documentation/arch/arm64/booting.rst */ +struct Image_header { + uint32 code0; /* executable */ + uint32 code1; /* unused */ + uint64 text_offset; /* load offset, LE */ + uint64 image_size; /* size, LE */ + uint64 flags; /* bit 3: relocatable */ + uint64 res1; + uint64 res2; + uint64 res3; + uint32 magic; /* "ARM\x64" */ + uint32 res4; +}; + +int tb_image_setup(uintptr_t image, struct tb_image *img) +{ + const struct Image_header *ih = (const struct Image_header *)image; + uint64_t image_size, text_offset; + + if (le32_to_cpu(ih->magic) != LINUX_ARM64_IMAGE_MAGIC) + return -1; + + if (le64_to_cpu(ih->image_size) == 0) { + /* ancient image, no size field, assume the old defaults */ + image_size = SZ_16M; + text_offset = 0x80000; + } else { + image_size = le64_to_cpu(ih->image_size); + text_offset = le64_to_cpu(ih->text_offset); + } + + /* + * flag bit 3 says the image can live anywhere, honour where it + * already is. otherwise the base must be 2MB aligned, the + * physical offset from there is text_offset. + */ + if (le64_to_cpu(ih->flags) & (1ULL << 3)) { + uintptr_t base = image - text_offset; + + img->load = ((base + SZ_2M - 1) & ~(uintptr_t)(SZ_2M - 1)) + + text_offset; + } else { + /* + * no relocate flag: the image must sit text_offset from a + * 2MB aligned base. it is already staged at the fixed + * address, treat its own position as the answer. + */ + img->load = image; + } + + /* the whole image, header included, lives at load, entry is code0 */ + img->ep = img->load; + img->size = image_size; + + return 0; +} -- cgit v1.2.3