First version of Minisel, a minimalist seL4 rootserver app for testing. Change-Id: I0dff1e7d2a74a16a748c60cc37a8c2d13b505892
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b5c73e8 --- /dev/null +++ b/Makefile
@@ -0,0 +1,23 @@ +SRC_LIBSEL4 ?= $(ROOTDIR)/kata/kernel/libsel4 +OUT_KATA ?= $(OUT)/kata/riscv32-unknown-elf/release +OUT_MINISEL ?= $(OUT)/tmp/minisel + +INCLUDES += -I$(SRC_LIBSEL4)/arch_include/riscv +INCLUDES += -I$(SRC_LIBSEL4)/include +INCLUDES += -I$(SRC_LIBSEL4)/mode_include/32 +INCLUDES += -I$(SRC_LIBSEL4)/sel4_arch_include/riscv32/ +INCLUDES += -I$(OUT_KATA)/kernel/gen_config +INCLUDES += -I$(OUT_KATA)/libsel4/autoconf +INCLUDES += -I$(OUT_KATA)/libsel4/gen_config/ +INCLUDES += -I$(OUT_KATA)/libsel4/include +INCLUDES += -I$(OUT_KATA)/libsel4/sel4_arch_include/riscv32 + +OPT=-O0 +DBG=-g + +all: $(OUT_MINISEL)/minisel.elf + +$(OUT_MINISEL)/minisel.elf: + mkdir -p $(OUT_MINISEL) + riscv32-unknown-elf-gcc $(DBG) $(OPT) $(INCLUDES) -march=rv32imac -mabi=ilp32 -std=gnu11 -c minisel.c -o $(OUT_MINISEL)/minisel.o + riscv32-unknown-elf-gcc $(DBG) -static -nostdlib $(OUT_MINISEL)/minisel.o -o $(OUT_MINISEL)/minisel.elf
diff --git a/minisel.c b/minisel.c new file mode 100644 index 0000000..3d92285 --- /dev/null +++ b/minisel.c
@@ -0,0 +1,85 @@ +// This file is a barebones, minimal-dependency rootserver (root app) for seL4 +// that uses no standard C libraries or startfiles. It prints bootinfo to the +// console using the seL4_DebugPutChar syscall and is intended as a starting +// point for low-level seL4 tests. + +#include <stdint.h> +#include <stdarg.h> + +#include <sel4/bootinfo.h> +#include <sel4/arch/syscalls.h> + +seL4_BootInfo *bootinfo; +__thread seL4_IPCBuffer *__sel4_ipc_buffer; + +char minisel_stack[16384] __attribute__((__aligned__(4096))); +char minisel_tls[4096] __attribute__((__aligned__(4096))); + +__attribute__((naked)) void _start() { + asm volatile( + ".option push \n" + ".option norelax \n" + "la gp, __global_pointer$ \n" + "la sp, minisel_stack + 4096 \n" + "la x4, minisel_tls \n" + "la t0, bootinfo \n" + "sw a0, 0(t0) \n" + ".option pop \n" + "j main \n" + ); +} + +// only prints 32-bit "%x" hex values +void minisel_printf(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + for (; *fmt; fmt++) { + if (*fmt == '%') { + fmt++; + if (*fmt == 'x') { + uint32_t arg = va_arg(args, uint32_t); + for (int i = 7; i >= 0; i--) { + int n = (arg >> (4 * i)) & 0xF; + seL4_DebugPutChar(n > 9 ? 'A' + n - 10 : '0' + n); + } + } + } else { + seL4_DebugPutChar(*fmt); + } + } + va_end(args); +} + +int main(void) { + minisel_printf("\n"); + minisel_printf("########################################\n"); + minisel_printf("Minisel startup, bootinfo @ %x\n", bootinfo); + minisel_printf("extraLen %x\n", bootinfo->extraLen); + minisel_printf("nodeID %x\n", bootinfo->nodeID); + minisel_printf("numNodes %x\n", bootinfo->numNodes); + minisel_printf("numIOPTLevels %x\n", bootinfo->numIOPTLevels); + minisel_printf("ipcBuffer %x\n", bootinfo->ipcBuffer); + minisel_printf("initThreadCNodeSizeBits %x\n", bootinfo->initThreadCNodeSizeBits); + minisel_printf("CONFIG_MAX_NUM_BOOTINFO_UNTYPED_CAPS %x\n", CONFIG_MAX_NUM_BOOTINFO_UNTYPED_CAPS); + minisel_printf("\n"); + + int slot_a = bootinfo->untyped.start; + int slot_b = bootinfo->untyped.end; + + minisel_printf("slot_a %x\n", slot_a); + minisel_printf("slot_b %x\n", slot_b); + minisel_printf("\n"); + + for (int i = 0; i < (slot_b - slot_a); i++) { + seL4_UntypedDesc u = bootinfo->untypedList[i]; + uint32_t paddr_a = u.paddr; + uint32_t paddr_b = paddr_a + (1 << u.sizeBits); + minisel_printf("paddr %x:%x isDevice %x\n", paddr_a, paddr_b, u.isDevice); + } + minisel_printf("\n"); + + minisel_printf("Done, sleeping in WFI loop\n"); + while(1) { + asm("wfi"); + } +}