diff options
| -rw-r--r-- | Makefile | 12 | ||||
| -rw-r--r-- | include/early/bump.h | 9 | ||||
| -rw-r--r-- | include/early/dtb.h | 1 | ||||
| -rw-r--r-- | include/sys/mem.h | 1 | ||||
| -rw-r--r-- | include/sys/stddef.h | 5 | ||||
| -rw-r--r-- | kernel/common/bump.c | 54 | ||||
| -rw-r--r-- | kernel/common/dtb.c | 24 | ||||
| -rw-r--r-- | kernel/common/mem.c | 18 | ||||
| -rw-r--r-- | kernel/riscv/kernel.c | 81 |
9 files changed, 116 insertions, 89 deletions
@@ -1,10 +1,15 @@ +VERSION = 0.1.0-alpha + CC = clang LD = ld.lld OBJCOPY = llvm-objcopy +COMPILER = $(shell $(CC) --version | head -n 1) +LINKER = $(shell $(LD) --version | head -n 1) + ARCH_FLAG = \ --target=riscv32-unknown-elf \ - -march=rv32im \ + -march=rv32g \ -mabi=ilp32 \ -D__SYS_LITTLE_ENDIAN__ @@ -20,6 +25,9 @@ COMMON_FLAGS = \ -nostdlib \ -nostdinc \ -nodefaultlibs \ + -DVERSION='"$(VERSION)"' \ + -DCOMPILER_NAME='"$(COMPILER)"' \ + -DLINKER_NAME='"$(LINKER)"' \ KERNEL_FLAG = $(COMMON_FLAGS) -static MODULE_FLAG = $(COMMON_FLAGS) -fPIC -fpie @@ -101,7 +109,7 @@ GENERATED = \ $(foreach m,$(MODULES),$($(m)_OBJS)) .PHONY: all kernel clean modules $(MODULES) -.SILENT: +$(V).SILENT: all: kernel modules kernel: $(KERNEL_BIN) modules: $(MODULES) diff --git a/include/early/bump.h b/include/early/bump.h deleted file mode 100644 index bf3e6f9..0000000 --- a/include/early/bump.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include <sys/stddef.h> -#include <early/dtb.h> -#define EHEAP_SIZE (512 * 1024) - - -void* kemalloc(size_t size); -struct mem_info *km_find_memory(struct dt_node *head); - diff --git a/include/early/dtb.h b/include/early/dtb.h index 41a7bcc..f0cd5ce 100644 --- a/include/early/dtb.h +++ b/include/early/dtb.h @@ -38,6 +38,7 @@ struct fdt_header { }; struct dt_node *dt_parse(void *fdt); +struct dt_node *dt_find_device(struct dt_node *head, const char *name); void *dt_get_prop(struct dt_node *node, char *name, size_t *len); uint32_t dt_read_u32(struct dt_node *node, char *name, uint32_t *out); diff --git a/include/sys/mem.h b/include/sys/mem.h index 769a162..e5637f6 100644 --- a/include/sys/mem.h +++ b/include/sys/mem.h @@ -23,6 +23,7 @@ struct mmio_device_meta { }; void* kmalloc(size_t size); +void* kemalloc(size_t size); void* kzalloc(size_t size); void kfree(void* ptr); diff --git a/include/sys/stddef.h b/include/sys/stddef.h index 27aea74..0232107 100644 --- a/include/sys/stddef.h +++ b/include/sys/stddef.h @@ -1,7 +1,7 @@ #pragma once #define NULL (void*)0 -#define uintptr_t __wk_size_t +#define uintptr_t __wk_uintptr_t #define size_t __wk_size_t #define uint8_t __wk_uint8_t #define uint16_t __wk_uint16_t @@ -32,7 +32,8 @@ #define htobi(x) x #endif -typedef __UINTPTR_TYPE__ __wk_size_t; +typedef __UINTPTR_TYPE__ __wk_uintptr_t; +typedef __SIZE_TYPE__ __wk_size_t; typedef __UINT8_TYPE__ __wk_uint8_t; typedef __UINT16_TYPE__ __wk_uint16_t; typedef __UINT32_TYPE__ __wk_uint32_t; diff --git a/kernel/common/bump.c b/kernel/common/bump.c deleted file mode 100644 index 1e07837..0000000 --- a/kernel/common/bump.c +++ /dev/null @@ -1,54 +0,0 @@ -#include <early/bump.h> -#include <sys/log.h> -#include <sys/mem.h> - -static char eheap[EHEAP_SIZE] = {0}; -static size_t eheap_off = 0; - -struct mem_info *km_find_memory(struct dt_node *head) { - struct dt_node *child = head->children; - while (child) { - struct mem_info *location = km_find_memory(child); - if (location) { - return location; - } else { - child = child->next; - } - } - - if (strlen(head->name) != 0) { - struct dt_prop *prop_head = head->props; - while (prop_head) { - if (strcmp(prop_head->name, "device_type") == 0 - && strcmp(prop_head->value, "memory") == 0) { - size_t len = 0; - uint32_t *reg = (uint32_t *)dt_get_prop(head, "reg", &len); - if (reg && len >= 8) { - uint32_t base = btohi(reg[0]); - uint32_t size = btohi(reg[1]); - struct mem_info *ret = kemalloc(sizeof(struct mem_info)); - ret->start = (void*)base; - ret->size = (size_t)size; - - return ret; - } - } - prop_head = prop_head->next; - } - } - return NULL; -} - - -void* kemalloc(size_t size) { - size = (size + 7) & ~7; - - if (eheap_off + size > EHEAP_SIZE) { - return NULL; - } - - void *ptr = &eheap[eheap_off]; - eheap_off += size; - return ptr; -} - diff --git a/kernel/common/dtb.c b/kernel/common/dtb.c index b345db0..482359b 100644 --- a/kernel/common/dtb.c +++ b/kernel/common/dtb.c @@ -1,5 +1,5 @@ #include <early/dtb.h> -#include <early/bump.h> +#include <sys/mem.h> struct dt_node *dt_parse(void *fdt) { struct fdt_header *hdr = fdt; @@ -52,6 +52,28 @@ struct dt_node *dt_parse(void *fdt) { } } +struct dt_node *dt_find_device(struct dt_node *head, const char *name) { + struct dt_node *child = head->children; + while (child) { + struct dt_node *result = dt_find_device(child, name); + if (result) { + return result; + } else { + child = child->next; + } + } + + struct dt_prop *props = head->props; + while (props) { + if (strcmp(props->name, "device_type") == 0 && + strcmp(props->value, name) == 0) { + return head; + } + } + + return NULL; +} + void *dt_get_prop(struct dt_node *node, char *name, size_t *len) { for (struct dt_prop *p = node->props; p; p = p->next) { if (strcmp(p->name, name) == 0) { diff --git a/kernel/common/mem.c b/kernel/common/mem.c index fee0761..f03d0a8 100644 --- a/kernel/common/mem.c +++ b/kernel/common/mem.c @@ -1,8 +1,12 @@ #include <sys/mem.h> #include <early/dtb.h> +#define EHEAP_SIZE (512 * 1024) static struct page *free_list; +static char eheap[EHEAP_SIZE] = {0}; +static size_t eheap_off = 0; + static void merge_freelist() { struct page *list = free_list; @@ -16,6 +20,20 @@ static void merge_freelist() { } } + +void* kemalloc(size_t size) { + size = (size + 7) & ~7; + + if (eheap_off + size > EHEAP_SIZE) { + return NULL; + } + + void *ptr = &eheap[eheap_off]; + eheap_off += size; + return ptr; +} + + void* kmalloc(size_t size) { struct page *page = free_list; struct page *last = NULL; diff --git a/kernel/riscv/kernel.c b/kernel/riscv/kernel.c index 4e72e2a..d34437f 100644 --- a/kernel/riscv/kernel.c +++ b/kernel/riscv/kernel.c @@ -1,42 +1,81 @@ #include <sys/log.h> +#include <sys/log.h> #include <sys/mem.h> #include <sys/cpio.h> -#include <early/bump.h> +#include <early/dtb.h> + +struct kernel_info { + struct dt_node *head; + void *mem_start; + size_t mem_size; + + void *initrd_start; + size_t initrd_size; +}; -#define KERNEL_SIZE 3 * 1024 * 1024 uint32_t user_regs[31]; -void kernel_main(size_t hart, void *fdt) { - printk("Doing kernel init with hard ID %d\n", hart); +struct kernel_info *discover_arch(void *fdt) { + struct kernel_info *kernel_info = kemalloc(sizeof(struct kernel_info)); struct dt_node *head = dt_parse(fdt); - struct mem_info *info = km_find_memory(head); + if (head == NULL) { + printk("[E;F] Failed to parse device tree!"); + return NULL; + } + kernel_info->head = head; - if (!info) { - printk("failed to find memory info!\n"); - return; + + struct dt_node *memory = dt_find_device(head, "memory"); + if (memory == NULL) { + printk("[E;F] Failed to fidn the memory device!"); + return NULL; } - info->start = (void *)((uint8_t *)info->start + KERNEL_SIZE); - info->size -= KERNEL_SIZE; + size_t len = 0; - km_init(info); + uint8_t *memory_reg = dt_get_prop(head, "reg", &len); - printk("memory blocks initialized\n"); + if (!memory_reg || len < sizeof(uintptr_t) + sizeof(size_t)) { + printk("[E;F] reg property for memory in provided device tree is nonexistent or invalid!"); + return NULL; + } - size_t len = 0; - uint32_t *initrd = dt_get_prop(head, "initrd", &len); - if (!initrd || len < 8) { - printk("failed to find initrd!\n"); + uintptr_t base = btohi(*memory_reg); + size_t size = btohi(*(memory_reg + sizeof(uintptr_t))); + + kernel_info->mem_start = (void *)base; + kernel_info->mem_size = size; + + + uint8_t *initrd_reg = dt_get_prop(head, "initrd", &len); + if (!initrd_reg || len < sizeof(uintptr_t) + sizeof(size_t)) { + printk("[E;F] initrd property for head of provided device tree is nonexistent or invalid!"); + return NULL; + } + + base = btohi(*initrd_reg); + size = btohi(*(initrd_reg + sizeof(uintptr_t))); + + kernel_info->initrd_start = (void *)base; + kernel_info->initrd_size = size; + + + return kernel_info; +} + +void kernel_main(size_t hart, void *fdt) { + printk("wkern version %s (Compiler %s, Linker %s)%s\n", VERSION, COMPILER_NAME, LINKER_NAME); + if (hart != 0) + return; + + struct kernel_info *kernel_info = discover_arch(fdt); + + if (!kernel_info) { return; } - uint32_t base = btohi(initrd[0]); - uint32_t size = btohi(initrd[1]); - - char *file = cpio_get_file((void*)base, (size_t)size, "/sbin/init"); - (void)file; } void kernel_trap() { |
