From 3d6216a6f396eedd39508fb2dba302d11d87410b Mon Sep 17 00:00:00 2001 From: Kostas Missos Date: Tue, 21 Aug 2018 04:12:03 +0300 Subject: [PATCH] Deploy ianos. Our elf/module loader. --- bootloader/ianos/ianos.c | 174 +++++++++++++++++++++++++++++++++++++++ bootloader/ianos/ianos.h | 34 ++++++++ bootloader/main.c | 115 +------------------------- 3 files changed, 209 insertions(+), 114 deletions(-) create mode 100644 bootloader/ianos/ianos.c create mode 100644 bootloader/ianos/ianos.h diff --git a/bootloader/ianos/ianos.c b/bootloader/ianos/ianos.c new file mode 100644 index 0000000..4adb738 --- /dev/null +++ b/bootloader/ianos/ianos.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2018 M4xw + * Copyright (c) 2018 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "ianos.h" +#include "../utils/types.h" +#include "../libs/elfload/elfload.h" +#include "../../common/common_module.h" +#include "../mem/heap.h" +#include "../gfx/gfx.h" + +#define IRAM_LIB_ADDR 0x4002B000 +#define DRAM_LIB_ADDR 0xE0000000 + +extern gfx_ctxt_t gfx_ctxt; +extern gfx_con_t gfx_con; +extern heap_t _heap; +extern sdmmc_t sd_sdmmc; +extern sdmmc_storage_t sd_storage; + +extern void *sd_file_read(char *path); +extern bool sd_mount(); +extern void sd_unmount(); + +void *elfBuf = NULL; +void *fileBuf = NULL; + +static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig) +{ + bdkParams_t bdkParameters = (bdkParams_t)malloc(sizeof(struct _bdkParams_t)); + bdkParameters->gfxCon = &gfx_con; + bdkParameters->gfxCtx = &gfx_ctxt; + bdkParameters->memcpy = (memcpy_t)&memcpy; + bdkParameters->memset = (memset_t)&memset; + bdkParameters->sharedHeap = &_heap; + bdkParameters->sdSdmmc = &sd_sdmmc; + bdkParameters->sdStorage = &sd_storage; + + entrypoint(moduleConfig, bdkParameters); +} + +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) +{ + (void)ctx; + + memcpy(dest, fileBuf + offset, numberBytes); + + return true; +} + +void ianos_print_error(int errorno) +{ + switch (errorno) + { + case 1: + gfx_printf(&gfx_con, "Can't find library!\n"); + break; + case 2: + gfx_printf(&gfx_con, "Cant init ELF context!\n"); + break; + case 3: + gfx_printf(&gfx_con, "Cant alloc memory!\n"); + break; + case 4: + gfx_printf(&gfx_con, "Error loading ELF!\n"); + break; + case 5: + gfx_printf(&gfx_con, "Error relcating ELF!\n"); + break; + } +} + +//TODO: Support shared libraries. +int ianos_loader(bool sdmount, char *path, elfType_t type, void *moduleConfig) +{ + int res = 0; + + if (sdmount) + if (!sd_mount()) + goto elfLoadFinalOut; + + fileBuf = sd_file_read(path); + + if (sdmount) + sd_unmount(); + + if (!fileBuf) + { + res = 1; + goto elfLoadFinalOut; + } + + + el_ctx ctx; + ctx.pread = _ianos_read_cb; + + if (el_init(&ctx)) + { + res = 2; + goto elfLoadFinalOut; + } + + // Set our relocated library's buffer. + switch (type & 0xFFFF) + { + case EXEC_ELF: + case AR64_ELF: + elfBuf = (void *)DRAM_LIB_ADDR; + sd_unmount(); + break; + default: + elfBuf = memalign(ctx.align, ctx.memsz); + } + + if (!elfBuf) + { + res = 3; + goto elfLoadFinalOut; + } + + // Load and relocate library. + ctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuf; + if (el_load(&ctx, _ianos_alloc_cb)) + { + res = 4; + goto elfFreeOut; + } + + if (el_relocate(&ctx)) + { + res = 5; + goto elfFreeOut; + } + + // Launch. + uintptr_t epaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuf; + moduleEntrypoint_t ep = (moduleEntrypoint_t)epaddr; + + _ianos_call_ep(ep, moduleConfig); + +elfFreeOut: + if ((u32)elfBuf >= 0x90000000 && (u32)elfBuf <= DRAM_LIB_ADDR) + free(elfBuf); + free(fileBuf); + elfBuf = NULL; + fileBuf = NULL; + +elfLoadFinalOut: + + return res; +} \ No newline at end of file diff --git a/bootloader/ianos/ianos.h b/bootloader/ianos/ianos.h new file mode 100644 index 0000000..2d651ba --- /dev/null +++ b/bootloader/ianos/ianos.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018 M4xw + * Copyright (c) 2018 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef IANOS_H +#define IANOS_H + +#include "../utils/types.h" + +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; + +int ianos_loader(bool sdmount, char *path, elfType_t type, void* config); + +#endif \ No newline at end of file diff --git a/bootloader/main.c b/bootloader/main.c index 14ab035..15ec5f4 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -4,7 +4,6 @@ * Copyright (c) 2018 Rajko Stojadinovic * Copyright (c) 2018 CTCaer * Copyright (c) 2018 Reisyukaku - * Copyright (c) 2018 M4xw * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -57,13 +56,8 @@ #include "power/max17050.h" #include "power/bq24193.h" #include "config/config.h" - +#include "ianos/ianos.h" #include "libs/elfload/elfload.h" -#include "../common/common_module.h" - -// TODO: Make it not suck -FIL globalElfFile; -void *elfBuff; //TODO: ugly. gfx_ctxt_t gfx_ctxt; @@ -1727,113 +1721,6 @@ out: btn_wait(); } -void mainApplicationCb(const char *test) -{ - gfx_printf(&gfx_con, "\n%s\n\n", test); - //btn_wait(); - - return; -} - -extern heap_t _heap; -static void call_elf_ep(moduleEntrypoint_t entrypoint) -{ - pmoduleConfiguration_t moduleConfig = (pmoduleConfiguration_t)malloc(sizeof(struct moduleConfiguration_t)); - moduleConfig->gfxCon = &gfx_con; - moduleConfig->gfxCtx = &gfx_ctxt; - moduleConfig->memcpy = (memcpy_t)&memcpy; - moduleConfig->memset = (memset_t)&memset; - moduleConfig->sharedHeap = &_heap; - - entrypoint(mainApplicationCb, moduleConfig); -} - -static void *elfAllocationCallback( - el_ctx *ctx, - Elf_Addr phys, - Elf_Addr virt, - Elf_Addr size) -{ - (void)ctx; - (void)phys; - (void)size; - return (void *)virt; -} - -void *buffteg = NULL; -static bool elfReadCallback(el_ctx *ctx, void *dest, size_t numberBytes, size_t offset) -{ - (void)ctx; - - memcpy(dest, buffteg + offset, numberBytes); - - return true; -} - -// TODO: ??? Add more modules! -void launch_elf() -{ - gfx_clear_grey(&gfx_ctxt, 0x1B); - gfx_con_setpos(&gfx_con, 0, 0); - - if (sd_mount()) - { - gfx_printf(&gfx_con, "Attempting to execute: %s\n", "module_sample.so"); - - buffteg = sd_file_read("module_sample.so"); - - sd_unmount(); - - el_ctx ctx; - ctx.pread = elfReadCallback; - - if (el_init(&ctx)) - { - gfx_printf(&gfx_con, "%s\n", "Cant init ELF context"); - goto elfLoadFinalOut; - } - - elfBuff = memalign(ctx.align, ctx.memsz); - if (!elfBuff) - { - gfx_printf(&gfx_con, "%s\n", "Cant alloc memory"); - goto elfLoadFinalOut; - } - - ctx.base_load_vaddr = ctx.base_load_paddr = (uintptr_t)elfBuff; - if (el_load(&ctx, elfAllocationCallback)) - { - gfx_printf(&gfx_con, "%s\n", "el_load"); - goto elfFreeOut; - } - - if (el_relocate(&ctx)) - { - gfx_printf(&gfx_con, "%s\n", "el_relocate"); - goto elfFreeOut; - } - - uintptr_t epaddr = ctx.ehdr.e_entry + (uintptr_t)elfBuff; - moduleEntrypoint_t ep = (moduleEntrypoint_t)epaddr; - - call_elf_ep(ep); - - elfFreeOut: - free(elfBuff); - elfBuff = NULL; - } - else - { - gfx_printf(&gfx_con, "%s\n", "Cant mount SD"); - goto elfLoadFinalOut; - } - -elfLoadFinalOut: - btn_wait(); - - return; -} - void launch_firmware() { u8 max_entries = 61;