diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2021-12-20 12:28:30 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2021-12-20 12:37:55 +0200 |
| commit | dc2e2cc9dc9d7790e23dd9a4ccc265d7bb6d76aa (patch) | |
| tree | ee12863bb4aab536810bbe13638bf21317b37658 | |
| parent | 98255910aa82c27d04ba79704086eca2310b3075 (diff) | |
| download | kmi-dc2e2cc9dc9d7790e23dd9a4ccc265d7bb6d76aa.tar.gz kmi-dc2e2cc9dc9d7790e23dd9a4ccc265d7bb6d76aa.zip | |
Added init back
| -rw-r--r-- | Makefile | 17 | ||||
| -rw-r--r-- | TODO.txt | 2 | ||||
| -rw-r--r-- | arch/riscv/conf/apos.its | 4 | ||||
| -rwxr-xr-x | arch/riscv/conf/init | bin | 0 -> 1032 bytes | |||
| -rw-r--r-- | arch/riscv/conf/init-link.S | 30 | ||||
| -rw-r--r-- | arch/riscv/conf/initrd | bin | 0 -> 1536 bytes | |||
| -rw-r--r-- | arch/riscv/conf/initrd.txt | 1 | ||||
| -rw-r--r-- | arch/riscv/conf/kernel-link.S | 4 | ||||
| -rw-r--r-- | arch/riscv/conf/s.S | 4 | ||||
| -rw-r--r-- | arch/riscv/include/csr.h | 9 | ||||
| -rw-r--r-- | arch/riscv/include/vmem.h | 8 | ||||
| -rw-r--r-- | arch/riscv/init/init.c | 29 | ||||
| -rw-r--r-- | arch/riscv/kernel/main.c | 10 | ||||
| -rw-r--r-- | arch/riscv/kernel/vmem.c | 5 | ||||
| -rw-r--r-- | arch/riscv/source.mk | 1 | ||||
| -rw-r--r-- | common/elf.c | 2 | ||||
| -rw-r--r-- | common/initrd.c | 2 | ||||
| -rw-r--r-- | common/vmem.c | 5 | ||||
| -rw-r--r-- | include/apos/vmem.h | 2 |
19 files changed, 111 insertions, 24 deletions
@@ -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) @@ -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 Binary files differnew file mode 100755 index 0000000..06e61e0 --- /dev/null +++ b/arch/riscv/conf/init 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 Binary files differnew file mode 100644 index 0000000..8dc931b --- /dev/null +++ b/arch/riscv/conf/initrd 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); |
