summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/common/bump.c54
-rw-r--r--kernel/common/dtb.c24
-rw-r--r--kernel/common/mem.c18
-rw-r--r--kernel/riscv/kernel.c81
4 files changed, 101 insertions, 76 deletions
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() {