From 2014a72774a4c82427d14bf04c79c919b94c21c6 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Thu, 29 Jan 2026 08:58:19 +0200 Subject: [PATCH] bdk: ianos: restructure for future expansion --- bdk/ianos/elfload/elfload.c | 2 +- bdk/ianos/elfload/elfload.h | 5 +- bdk/ianos/ianos.c | 151 +++++++++++++++++++++++------------- bdk/ianos/ianos.h | 28 ++++--- bdk/mem/minerva.c | 9 +-- bdk/module.h | 16 ++-- 6 files changed, 131 insertions(+), 80 deletions(-) diff --git a/bdk/ianos/elfload/elfload.c b/bdk/ianos/elfload/elfload.c index daf561a4..d56e99b9 100644 --- a/bdk/ianos/elfload/elfload.c +++ b/bdk/ianos/elfload/elfload.c @@ -21,7 +21,7 @@ el_status el_pread(el_ctx *ctx, void *def, size_t nb, size_t offset) { - return ctx->pread(ctx, def, nb, offset) ? EL_OK : EL_EIO; + return ctx->pread(ctx, def, nb, offset); } #define EL_PHOFF(ctx, num) (((ctx)->ehdr.e_phoff + (num) *(ctx)->ehdr.e_phentsize)) diff --git a/bdk/ianos/elfload/elfload.h b/bdk/ianos/elfload/elfload.h index 0a73e052..63942791 100644 --- a/bdk/ianos/elfload/elfload.h +++ b/bdk/ianos/elfload/elfload.h @@ -53,7 +53,7 @@ typedef enum typedef struct el_ctx { - bool (*pread)(struct el_ctx *ctx, void *dest, size_t nb, size_t offset); + el_status (*pread)(struct el_ctx *ctx, void *dest, size_t nb, size_t offset); /* base_load_* -> address we are actually going to load at */ @@ -61,6 +61,9 @@ typedef struct el_ctx base_load_paddr, base_load_vaddr; + /* original memory of binary */ + Elf_Addr eaddr; + /* size in memory of binary */ Elf_Addr memsz; diff --git a/bdk/ianos/ianos.c b/bdk/ianos/ianos.c index 99a996df..606b46f9 100644 --- a/bdk/ianos/ianos.c +++ b/bdk/ianos/ianos.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 M4xw - * Copyright (c) 2018-2019 CTCaer + * Copyright (c) 2018-2026 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -27,97 +27,136 @@ #include -#define IRAM_LIB_ADDR 0x4002B000 -#define DRAM_LIB_ADDR 0xE0000000 - extern heap_t _heap; -void *elfBuf = NULL; -void *fileBuf = NULL; +static bdk_params_t _bdk_params = { + .gfx_con = (void *)&gfx_con, + .gfx_ctx = (void *)&gfx_ctxt, + .heap = &_heap, + .memcpy = (memcpy_t)&memcpy, + .memset = (memset_t)&memset, -static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig) -{ - bdkParams_t bdkParameters = (bdkParams_t)malloc(sizeof(struct _bdkParams_t)); - bdkParameters->gfxCon = (void *)&gfx_con; - bdkParameters->gfxCtx = (void *)&gfx_ctxt; - bdkParameters->memcpy = (memcpy_t)&memcpy; - bdkParameters->memset = (memset_t)&memset; - bdkParameters->sharedHeap = &_heap; - - // Extra functions. - bdkParameters->extension_magic = IANOS_EXT0; - bdkParameters->reg_voltage_set = (reg_voltage_set_t)&max7762x_regulator_set_voltage; - - entrypoint(moduleConfig, bdkParameters); -} + .extension_magic = 0 +}; static void *_ianos_alloc_cb(el_ctx *ctx, Elf_Addr phys, Elf_Addr virt, Elf_Addr size) { - (void)ctx; - (void)phys; - (void)size; return (void *)virt; } -static bool _ianos_read_cb(el_ctx *ctx, void *dest, size_t numberBytes, size_t offset) +static el_status _ianos_read_cb(el_ctx *ctx, void *dest, size_t nb, size_t offset) { - (void)ctx; + memcpy(dest, (void *)(ctx->eaddr + offset), nb); - memcpy(dest, fileBuf + offset, numberBytes); - - return true; + return EL_OK; } //TODO: Support shared libraries. -uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig) +int ianos_loader(ianos_lib_t *lib, char *path) { el_ctx ctx; - uintptr_t epaddr = 0; + lib->buf = NULL; + if (!lib->bdk) + lib->bdk = &_bdk_params; // Read library. - fileBuf = sd_file_read(path, NULL); - - if (!fileBuf) - goto out; + ctx.eaddr = (Elf_Addr)sd_file_read(path, NULL); + if (!ctx.eaddr) + goto error; ctx.pread = _ianos_read_cb; if (el_init(&ctx)) - goto out; + goto error; + + if (lib->type & IA_SHARED_LIB) + goto error; // No support for shared libs now. // Set our relocated library's buffer. - switch (type & 0xFFFF) + switch (lib->type & ~IA_SHARED_LIB) { - case EXEC_ELF: - case AR64_ELF: - elfBuf = (void *)DRAM_LIB_ADDR; + case IA_DRAM_LIB: + lib->buf = malloc(ctx.memsz); // Aligned to 0x10 by default. break; + + case IA_IRAM_LIB: + break; + + case IA_AUTO_LIB: // Default to DRAM for now. default: - elfBuf = malloc(ctx.memsz); // Aligned to 0x10 by default. + lib->buf = malloc(ctx.memsz); // Aligned to 0x10 by default. + break; } - if (!elfBuf) - goto out; + if (!lib->buf) + goto error; // Load and relocate library. - ctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuf; + ctx.base_load_vaddr = ctx.base_load_paddr = (Elf_Addr)lib->buf; if (el_load(&ctx, _ianos_alloc_cb)) - goto out_free; + goto error; if (el_relocate(&ctx)) - goto out_free; + goto error; + + free((void *)ctx.eaddr); // Launch. - epaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuf; - moduleEntrypoint_t ep = (moduleEntrypoint_t)epaddr; + Elf_Addr epaddr = ctx.ehdr.e_entry + (Elf_Addr)lib->buf; + moduleEntrypoint ep = (moduleEntrypoint)epaddr; + ep(lib->private, lib->bdk); - _ianos_call_ep(ep, moduleConfig); + return 0; -out_free: - free(fileBuf); - elfBuf = NULL; - fileBuf = NULL; +error: + free((void *)ctx.eaddr); + free(lib->buf); -out: - return epaddr; -} \ No newline at end of file + return 1; +} + +uintptr_t ianos_static_module(char *path, void *private) +{ + el_ctx ctx; + Elf_Addr buf = 0; + Elf_Addr epaddr = 0; + + // Read library. + ctx.eaddr = (Elf_Addr)sd_file_read(path, NULL); + if (!ctx.eaddr) + goto error; + + ctx.pread = _ianos_read_cb; + + // Initialize elfload context. + if (el_init(&ctx)) + goto error; + + // Set our relocated library's buffer. + buf = (Elf_Addr)malloc(ctx.memsz); // Aligned to 0x10 by default. + if (!buf) + goto error; + + // Load and relocate library. + ctx.base_load_vaddr = ctx.base_load_paddr = buf; + if (el_load(&ctx, _ianos_alloc_cb)) + goto error; + + if (el_relocate(&ctx)) + goto error; + + free((void *)ctx.eaddr); + + // Launch. + epaddr = ctx.ehdr.e_entry + buf; + moduleEntrypoint ep = (moduleEntrypoint)epaddr; + ep(private, &_bdk_params); + + return (uintptr_t)epaddr; + +error: + free((void *)ctx.eaddr); + free((void *)buf); + + return 0; +} diff --git a/bdk/ianos/ianos.h b/bdk/ianos/ianos.h index 5ebec641..79d26478 100644 --- a/bdk/ianos/ianos.h +++ b/bdk/ianos/ianos.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 M4xw - * Copyright (c) 2018 CTCaer + * Copyright (c) 2018-2026 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -19,16 +19,26 @@ #define IANOS_H #include +#include typedef enum { - DRAM_LIB = 0, // DRAM library. - EXEC_ELF = 1, // Executable elf that does not return. - DR64_LIB = 2, // AARCH64 DRAM library. - AR64_ELF = 3, // Executable elf that does not return. - KEEP_IN_RAM = (1 << 31) // Shared library mask. -} elfType_t; + IA_DRAM_LIB = 0, // DRAM library. + IA_IRAM_LIB = 1, // IRAM library. No support for now. + IA_AUTO_LIB = 2, // AUTO library. Defaults to DRAM for now. + IA_SHARED_LIB = BIT(7) // Shared library mask. No support for now. +} ianos_type_t; -uintptr_t ianos_loader(char *path, elfType_t type, void* config); +typedef struct _ianos_lib_t +{ + uintptr_t epaddr; + void *buf; + void *private; + ianos_type_t type; + bdk_params_t *bdk; +} ianos_lib_t; -#endif \ No newline at end of file +int ianos_loader(ianos_lib_t *lib, char *path); +uintptr_t ianos_static_module(char *path, void *private); // Session-lived DRAM lib. + +#endif diff --git a/bdk/mem/minerva.c b/bdk/mem/minerva.c index 583fc9b0..66071940 100644 --- a/bdk/mem/minerva.c +++ b/bdk/mem/minerva.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2025 CTCaer + * Copyright (c) 2019-2026 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -52,8 +52,7 @@ u32 minerva_init(minerva_str_t *mtc_str) { // Load library and do a periodic training if needed. mtc_cfg->train_mode = OP_PERIODIC_TRAIN; - u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg); - mtc_call = (void *)ep_addr; + mtc_call = (void *)ianos_static_module("bootloader/sys/libsys_minerva.bso", (void *)mtc_cfg); return !mtc_call ? 1 : 0; } @@ -67,7 +66,7 @@ u32 minerva_init(minerva_str_t *mtc_str) mtc_tmp.init_done = !no_table ? MTC_NEW_MAGIC : MTC_IRB_MAGIC; // Load library and get table. - u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)&mtc_tmp); + u32 ep_addr = ianos_static_module("bootloader/sys/libsys_minerva.bso", (void *)&mtc_tmp); // Ensure that Minerva is initialized. if (mtc_tmp.init_done == MTC_INIT_MAGIC) @@ -88,7 +87,7 @@ u32 minerva_init(minerva_str_t *mtc_str) mtc_cfg->sdram_id = fuse_read_dramid(false); mtc_cfg->init_done = !no_table ? MTC_NEW_MAGIC : MTC_IRB_MAGIC; - u32 ep_addr = ianos_loader("bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg); + u32 ep_addr = ianos_static_module("bootloader/sys/libsys_minerva.bso", (void *)mtc_cfg); // Ensure that Minerva is initialized. if (mtc_cfg->init_done == MTC_INIT_MAGIC) diff --git a/bdk/module.h b/bdk/module.h index acc048c3..59fbfa15 100644 --- a/bdk/module.h +++ b/bdk/module.h @@ -1,6 +1,7 @@ /* * Common Module Header * Copyright (c) 2018 M4xw + * Copyright (c) 2018-2026 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -21,7 +22,7 @@ #include #include -#define IANOS_EXT0 0x304E4149 +#define IANOS_EXT1 0x314E4149 // Module Callback typedef void (*cbMainModule_t)(const char *s); @@ -31,16 +32,15 @@ typedef int (*reg_voltage_set_t)(u32, u32); typedef struct _bdkParams_t { - void *gfxCon; - void *gfxCtx; - heap_t *sharedHeap; + void *gfx_con; + void *gfx_ctx; + heap_t *heap; memcpy_t memcpy; memset_t memset; u32 extension_magic; - reg_voltage_set_t reg_voltage_set; -} *bdkParams_t; +} bdk_params_t; -// Module Entrypoint -typedef void (*moduleEntrypoint_t)(void *, bdkParams_t); +// Module Caller. +typedef void (*moduleEntrypoint)(void *, bdk_params_t *); #endif