aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2021-12-20 12:28:30 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2021-12-20 12:37:55 +0200
commitdc2e2cc9dc9d7790e23dd9a4ccc265d7bb6d76aa (patch)
treeee12863bb4aab536810bbe13638bf21317b37658
parent98255910aa82c27d04ba79704086eca2310b3075 (diff)
downloadkmi-dc2e2cc9dc9d7790e23dd9a4ccc265d7bb6d76aa.tar.gz
kmi-dc2e2cc9dc9d7790e23dd9a4ccc265d7bb6d76aa.zip
Added init back
-rw-r--r--Makefile17
-rw-r--r--TODO.txt2
-rw-r--r--arch/riscv/conf/apos.its4
-rwxr-xr-xarch/riscv/conf/initbin0 -> 1032 bytes
-rw-r--r--arch/riscv/conf/init-link.S30
-rw-r--r--arch/riscv/conf/initrdbin0 -> 1536 bytes
-rw-r--r--arch/riscv/conf/initrd.txt1
-rw-r--r--arch/riscv/conf/kernel-link.S4
-rw-r--r--arch/riscv/conf/s.S4
-rw-r--r--arch/riscv/include/csr.h9
-rw-r--r--arch/riscv/include/vmem.h8
-rw-r--r--arch/riscv/init/init.c29
-rw-r--r--arch/riscv/kernel/main.c10
-rw-r--r--arch/riscv/kernel/vmem.c5
-rw-r--r--arch/riscv/source.mk1
-rw-r--r--common/elf.c2
-rw-r--r--common/initrd.c2
-rw-r--r--common/vmem.c5
-rw-r--r--include/apos/vmem.h2
19 files changed, 111 insertions, 24 deletions
diff --git a/Makefile b/Makefile
index e0a2ec6..80fe0e5 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ DEBUGFLAGS != [ $(RELEASE) ] && echo "-flto -O2" || echo "-O0 -ggdb3 -DDEBUG"
CFLAGS = -fno-pie -ffreestanding -nostdlib -std=c17 -Wall -Wextra
DEPFLAGS = -MT $@ -MMD -MP -MF $@.d
-all: kernel.bin
+all: apos.bin
# default values, overwrite if/when needed
ARCH ?= riscv
@@ -21,8 +21,9 @@ OBJCOPY ?= objcopy
OBJCOPY_FLAGS ?= -Obinary --set-section-flags .bss=alloc,load,contents
KERNEL_SOURCES != echo common/*.c lib/*.c
-CLEANUP := build deps.mk kernel.* apos.bin
+CLEANUP := build deps.mk kernel.* init.* apos.bin
CLEANUP_CMD :=
+INIT_SOURCES :=
include arch/$(ARCH)/source.mk
@@ -41,20 +42,30 @@ KERN_SIZE = wc -c kernel.bin | cut -d ' ' -f 1
KERN_INFO = sed "s/<KERNEL_SIZE>/$$($(KERN_SIZE))/"
KERNEL_LINK := arch/$(ARCH)/conf/kernel-link
+INIT_LINK := arch/$(ARCH)/conf/init-link
KERNEL_OBJECTS != ./scripts/gen-deps --compile "$(KERNEL_SOURCES)"
+INIT_OBJECTS != ./scripts/gen-deps --compile "$(INIT_SOURCES)"
KERNEL_LD != ./scripts/gen-deps --link "$(KERNEL_LINK).S"
+INIT_LD != ./scripts/gen-deps --link "$(INIT_LINK).S"
include deps.mk
+init.elf: $(INIT_OBJECTS) $(INIT_LD)
+ $(GENELF) -T $(INIT_LD) $(INIT_OBJECTS) -o $@
+
kernel.elf: $(KERNEL_OBJECTS) $(KERNEL_LD)
$(GENELF) -T $(KERNEL_LD) $(KERNEL_OBJECTS) -o $@
-$(INIT_LD): kernel.bin
+init.bin: init.elf
+ $(CROSS_COMPILE)$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@
kernel.bin: kernel.elf
$(CROSS_COMPILE)$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@
+apos.bin: init.bin kernel.bin
+ cat init.bin kernel.bin > apos.bin
+
clean:
$(RM) -r $(CLEANUP)
diff --git a/TODO.txt b/TODO.txt
index bbe214d..77cdf70 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -6,3 +6,5 @@
+ Make sure vmap is in 4K increments or whatever
+ Remove/converge convnum and debugging __atoi
+ Create actual init program
+ + That will need some kind of linking info, say, `place .text etc above
+ 0xffffffadsadsad` or whatever. Should be doable, let's see.
diff --git a/arch/riscv/conf/apos.its b/arch/riscv/conf/apos.its
index 1581025..15db4a4 100644
--- a/arch/riscv/conf/apos.its
+++ b/arch/riscv/conf/apos.its
@@ -7,7 +7,7 @@
images {
kernel {
description = "Garbaggio";
- data = /incbin/("../../../kernel.bin");
+ data = /incbin/("../../../apos.bin");
type = "kernel";
arch = "riscv";
os = "apos";
@@ -21,7 +21,7 @@
initrd {
description = "Gargabbio initrd";
- data = /incbin/("initrd.txt");
+ data = /incbin/("initrd");
type = "ramdisk";
arch = "riscv";
os = "apos";
diff --git a/arch/riscv/conf/init b/arch/riscv/conf/init
new file mode 100755
index 0000000..06e61e0
--- /dev/null
+++ b/arch/riscv/conf/init
Binary files differ
diff --git a/arch/riscv/conf/init-link.S b/arch/riscv/conf/init-link.S
new file mode 100644
index 0000000..642e831
--- /dev/null
+++ b/arch/riscv/conf/init-link.S
@@ -0,0 +1,30 @@
+OUTPUT_ARCH(riscv)
+ENTRY(main)
+
+SECTIONS {
+ . = ABSOLUTE(PM_KERN);
+ __init_start = .;
+
+ /* objcopy only copies these three sections (as far as I'm aware) into the
+ produces binary, so __init_end should point to the correct location in the
+ final binary
+ */
+ .text ALIGN(4K) : AT(0) {
+ *(.init.start)
+ *(.text*);
+ }
+
+ .rodata : {
+ *(.rodata*)
+ }
+
+ .data : {
+ *(.data*)
+ }
+
+ .bss : {
+ *(.bss*) *(COMMON)
+ }
+
+ __init_end = . ;
+}
diff --git a/arch/riscv/conf/initrd b/arch/riscv/conf/initrd
new file mode 100644
index 0000000..8dc931b
--- /dev/null
+++ b/arch/riscv/conf/initrd
Binary files differ
diff --git a/arch/riscv/conf/initrd.txt b/arch/riscv/conf/initrd.txt
deleted file mode 100644
index e965047..0000000
--- a/arch/riscv/conf/initrd.txt
+++ /dev/null
@@ -1 +0,0 @@
-Hello
diff --git a/arch/riscv/conf/kernel-link.S b/arch/riscv/conf/kernel-link.S
index bf0ad28..d3b1223 100644
--- a/arch/riscv/conf/kernel-link.S
+++ b/arch/riscv/conf/kernel-link.S
@@ -2,10 +2,10 @@ OUTPUT_ARCH(riscv)
ENTRY(main)
SECTIONS {
- . = ABSOLUTE(PM_KERN);
+ . = ABSOLUTE(VM_KERN);
__kernel_start = .;
- .text : AT(0) {
+ .text ALIGN(4K) : AT(0) {
*(.kernel.start);
*(.text*);
}
diff --git a/arch/riscv/conf/s.S b/arch/riscv/conf/s.S
new file mode 100644
index 0000000..7b796ce
--- /dev/null
+++ b/arch/riscv/conf/s.S
@@ -0,0 +1,4 @@
+.text
+.global _start
+_start:
+loop: j loop
diff --git a/arch/riscv/include/csr.h b/arch/riscv/include/csr.h
index 70e60bb..bd02b04 100644
--- a/arch/riscv/include/csr.h
+++ b/arch/riscv/include/csr.h
@@ -37,6 +37,9 @@
#define EXC_LOAD_PAGE_FAULT 13
#define EXC_STORE_PAGE_FAULT 15
+/* status CSR bits */
+#define SSTATUS_SUM (1 << 18)
+
/* directly lifted from Linux:/arch/riscv/include/asm/asm.h:9-13 */
#ifdef __ASSEMBLY__
#define __ASM_STR(x) x
@@ -50,4 +53,10 @@
#define csr_write(csr, val)\
__asm__ ("csrw " __ASM_STR(csr) ", %0" : : "rK" (val) : "memory")
+#define csr_set(csr, val)\
+ __asm__ ("csrs " __ASM_STR(csr) ", %0" : : "rK" (val) : "memory")
+
+#define csr_clear(csr, val)\
+ __asm__ ("csrc " __ASM_STR(csr) ", %0" : : "rK" (val) : "memory")
+
#endif /* APOS_CSR_H */
diff --git a/arch/riscv/include/vmem.h b/arch/riscv/include/vmem.h
index 2cd3ac7..d17aaf1 100644
--- a/arch/riscv/include/vmem.h
+++ b/arch/riscv/include/vmem.h
@@ -3,7 +3,6 @@
#include <apos/types.h>
#include <apos/attrs.h>
-#include <apos/pmem.h>
#define VM_V (1 << 0)
#define VM_R (1 << 1)
@@ -25,11 +24,4 @@ struct __packed vm_branch_t {
struct vm_branch_t *leaf[512];
};
-
-void map_vmem(struct vm_branch_t *b,
- pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order_t order);
-
-void unmap_vmem(struct vm_branch_t *b,
- vm_t vaddr, enum mm_order_t order);
-
#endif /* APOS_RISCV_VMAP_H */
diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c
new file mode 100644
index 0000000..d9b32a0
--- /dev/null
+++ b/arch/riscv/init/init.c
@@ -0,0 +1,29 @@
+#include <apos/types.h>
+#include <apos/attrs.h>
+#include <vmem.h>
+#include <csr.h>
+
+/* assume 64 bit for now */
+struct __packed init_vmem {
+ int *leaf[512];
+};
+
+struct init_vmem root_branch;
+
+/* assume Sv48 for now */
+void init_lowmem()
+{
+ size_t flags = VM_V | VM_X | VM_R | VM_W;
+ for(size_t i = 0; i < 512; ++i)
+ root_branch.leaf[i] = (int *)((1UL << 37) * i | flags);
+
+ csr_write(CSR_SATP, SATP_MODE_Sv48 | ((size_t)&root_branch >> 12));
+}
+
+void __section(".init.start") main(void *fdt)
+{
+ extern char *__init_end;
+ void (*kernel_main)(void *fdt) = (void (*)(void *))(VM_KERN + (size_t)&__init_end);
+ init_lowmem();
+ kernel_main(fdt);
+}
diff --git a/arch/riscv/kernel/main.c b/arch/riscv/kernel/main.c
index 40f0eb6..6c504f8 100644
--- a/arch/riscv/kernel/main.c
+++ b/arch/riscv/kernel/main.c
@@ -259,15 +259,17 @@ static void init_proc(void *fdt, struct vm_branch_t *b)
t->pid = 0;
t->tid = 0;
threads_insert(t);
- sp_mem_init(&t->sp_r, uvmem_size());
+ sp_mem_init(&t->sp_r, -uvmem_size(), uvmem_size() - 1);
/* binary itself */
size_t sz = align_up(get_init_size(fdt), BASE_PAGE_SIZE);
- t->bin = alloc_uvmem(t, sz, VM_V | VM_X);
+ t->bin = alloc_uvmem(t, sz, VM_V | VM_X | VM_R | VM_W | VM_U);
/* stack */
- t->stack = alloc_uvmem(t, SZ_2M, VM_V | VM_R | VM_W);
+ t->stack = alloc_uvmem(t, SZ_2M, VM_V | VM_R | VM_W | VM_U);
/* if it needs heap, it'll ask for it */
+ __asm__ ("sfence.vma" : : : "memory");
+
move_init(fdt, (void *)t->bin);
jump_to_userspace(t, 0, 0);
}
@@ -277,6 +279,8 @@ void __main main(void *fdt)
init_dbg(fdt);
dbg_fdt(fdt);
+ /* allow supervisor code to touch user data */
+ csr_set(CSR_SSTATUS, SSTATUS_SUM);
struct vm_branch_t *b = init_vmem(fdt);
init_mem_blocks();
init_irq(fdt);
diff --git a/arch/riscv/kernel/vmem.c b/arch/riscv/kernel/vmem.c
index ffe8731..4cb84a6 100644
--- a/arch/riscv/kernel/vmem.c
+++ b/arch/riscv/kernel/vmem.c
@@ -11,6 +11,11 @@
#define pte_addr(pte) (pnum_to_paddr(pte_ppn(pte)))
#define vm_to_index(a, o) (pm_to_index(a, o))
+void mod_vmem(struct vm_branch_t *branch, vm_t vaddr, uint8_t flags, enum mm_order_t order)
+{
+ /* todo */
+}
+
void map_vmem(struct vm_branch_t *branch,
pm_t paddr, vm_t vaddr, uint8_t flags, enum mm_order_t order)
{
diff --git a/arch/riscv/source.mk b/arch/riscv/source.mk
index ecc22bd..0e9a5c3 100644
--- a/arch/riscv/source.mk
+++ b/arch/riscv/source.mk
@@ -1,5 +1,6 @@
KERNEL_LOCAL != echo arch/riscv/kernel/*.[cS]
KERNEL_SOURCES += $(KERNEL_LOCAL)
+INIT_SOURCES += arch/riscv/init/init.c
CLEANUP_CMD := ./arch/riscv/conf/rmimage.sh
diff --git a/common/elf.c b/common/elf.c
index 7531bd1..83411e9 100644
--- a/common/elf.c
+++ b/common/elf.c
@@ -5,5 +5,5 @@ vm_t bin_entry(vm_t bin)
{
struct elf_header *e = (struct elf_header *)bin;
/* TODO: check that address points to a valid ELF executable */
- return (vm_t)e->e_entry;
+ return ((vm_t)e->e_entry) + bin;
}
diff --git a/common/initrd.c b/common/initrd.c
index f625209..6dd698d 100644
--- a/common/initrd.c
+++ b/common/initrd.c
@@ -75,7 +75,7 @@ pm_t get_initrdbase(void *fdt)
}
static char init_n[] = "init";
-static size_t init_nlen = ARRAY_SIZE(init_n);
+static size_t init_nlen = ARRAY_SIZE(init_n) - 1; /* ignore trailing NULL */
size_t get_init_size(void *fdt)
{
diff --git a/common/vmem.c b/common/vmem.c
index 25a8617..6d2b7dc 100644
--- a/common/vmem.c
+++ b/common/vmem.c
@@ -101,10 +101,11 @@ static struct sp_mem *sp_used_insert_region(struct sp_reg_root *r, struct sp_mem
return m;
}
-int sp_mem_init(struct sp_reg_root *r, size_t arena_size)
+int sp_mem_init(struct sp_reg_root *r, vm_t start, size_t arena_size)
{
struct sp_mem *m = get_mem_node();
- m->end = arena_size;
+ m->start = start;
+ m->end = start + arena_size;
sp_free_insert_region(r, m);
return 0;
diff --git a/include/apos/vmem.h b/include/apos/vmem.h
index fe2a76f..daa9d10 100644
--- a/include/apos/vmem.h
+++ b/include/apos/vmem.h
@@ -39,7 +39,7 @@ struct sp_mem {
*/
/* defined by arch */
-int sp_mem_init(struct sp_reg_root *r, size_t nums);
+int sp_mem_init(struct sp_reg_root *r, vm_t start, size_t nums);
vm_t alloc_uvmem(struct tcb *r, size_t s, uint8_t flags);
void free_uvmem(struct tcb *r, vm_t a);