diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2021-09-19 17:46:26 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2021-09-19 19:07:13 +0300 |
| commit | 4dffc92abf8f6a6e9b503c9809caaa99795d7a00 (patch) | |
| tree | 65fdb7c09f0b9a0ce2551fe8b51e637309322ed5 | |
| parent | 5979b0e7ba9064ae4033dbbe650bea86c2afb440 (diff) | |
| download | kmi-4dffc92abf8f6a6e9b503c9809caaa99795d7a00.tar.gz kmi-4dffc92abf8f6a6e9b503c9809caaa99795d7a00.zip | |
Added basic awareness of kernel size/bounds
| -rw-r--r-- | Makefile | 21 | ||||
| -rw-r--r-- | TODO.txt | 1 | ||||
| -rw-r--r-- | arch/riscv/conf/init-link.S | 21 | ||||
| -rw-r--r-- | arch/riscv/conf/kernel-link.S | 16 | ||||
| -rw-r--r-- | arch/riscv/init/init.c | 66 | ||||
| -rw-r--r-- | include/libfdt.h | 3 | ||||
| -rwxr-xr-x | scripts/gen-deps | 17 |
7 files changed, 103 insertions, 42 deletions
@@ -15,7 +15,7 @@ CC := gcc AR := ar CPP := cpp OBJCOPY ?= objcopy -OBJCOPY_FLAGS ?= -Obinary +OBJCOPY_FLAGS ?= -Obinary --set-section-flags .bss=alloc,load,contents COMMON_SOURCES != echo common/*.c KERNEL_SOURCES != echo kernel/*.c $(COMMON_SOURCES) @@ -36,29 +36,34 @@ GENELF = $(CROSS_COMPILE)$(CC) $(DEBUGFLAGS)\ GENLINK = $(CROSS_COMPILE)$(CPP) $(DEPFLAGS) $(INCLUDE_FLAGS) STRIPLINK = sed -n '/^[^\#]/p' +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 --kern "$(KERNEL_SOURCES)" INIT_OBJECTS != ./scripts/gen-deps --init "$(INIT_SOURCES)" -KERNEL_LD != ./scripts/gen-deps --link "$(KERNEL_LINK).S" -INIT_LD != ./scripts/gen-deps --link "$(INIT_LINK).S" +KERNEL_LD != ./scripts/gen-deps --kern-link "$(KERNEL_LINK).S" +INIT_LD != ./scripts/gen-deps --init-link "$(INIT_LINK).S" include deps.mk -apos.bin: kernel.elf init.elf - $(CROSS_COMPILE)$(OBJCOPY) $(OBJCOPY_FLAGS) kernel.elf kernel.bin - $(CROSS_COMPILE)$(OBJCOPY) $(OBJCOPY_FLAGS) init.elf init.bin - ./scripts/gen-padding 4096 init.bin +apos.bin: kernel.bin init.bin cat init.bin kernel.bin > $@ kernel.elf: $(KERNEL_OBJECTS) $(KERNEL_LD) $(GENELF) -T $(KERNEL_LD) $(KERNEL_OBJECTS) -o $@ -init.elf: $(INIT_OBJECTS) $(INIT_LD) +init.elf: kernel.bin $(INIT_OBJECTS) $(INIT_LD) $(GENELF) -T $(INIT_LD) $(INIT_OBJECTS) -o $@ +kernel.bin: kernel.elf + $(CROSS_COMPILE)$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@ + +init.bin: init.elf + $(CROSS_COMPILE)$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@ + clean: $(RM) -r $(CLEANUP) @@ -10,3 +10,4 @@ + Jump to vmem + Mark fdt, reserved mem, kernel, init and initrd in vmem. Remember to remove init from vmem when jumping to vmem ++ Figure out best way to tell the init how large out kernel is diff --git a/arch/riscv/conf/init-link.S b/arch/riscv/conf/init-link.S index 2bb904b..86e692e 100644 --- a/arch/riscv/conf/init-link.S +++ b/arch/riscv/conf/init-link.S @@ -5,8 +5,29 @@ ENTRY(_start) 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) + } + + __kernel_size = <KERNEL_SIZE>; + __init_end = . ; } diff --git a/arch/riscv/conf/kernel-link.S b/arch/riscv/conf/kernel-link.S index 4592086..1ccdc77 100644 --- a/arch/riscv/conf/kernel-link.S +++ b/arch/riscv/conf/kernel-link.S @@ -5,8 +5,24 @@ ENTRY(main) SECTIONS { . = ABSOLUTE(VM_KERN); + __kernel_start = .; + .text ALIGN(4K) : AT(0) { *(.kernel.start); *(.text*); } + + .rodata : { + *(.rodata*) + } + + .data : { + *(.data*) + } + + .bss : { + *(.bss*) *(COMMON) + } + + __kernel_end = .; } diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c index 1ec19a4..ee4a130 100644 --- a/arch/riscv/init/init.c +++ b/arch/riscv/init/init.c @@ -10,7 +10,7 @@ #include <csr.h> #include <vmap.h> -struct mem_layout { +struct pmem_layout { pm_t base; pm_t top; }; @@ -28,9 +28,10 @@ static struct cell_info get_cellinfo(void *fdt, int offset) }; return ret; + } -static struct mem_layout get_memlayout(void *fdt) +static struct pmem_layout get_memlayout(void *fdt) { struct cell_info ci = get_cellinfo(fdt, 0); @@ -38,24 +39,17 @@ static struct mem_layout get_memlayout(void *fdt) uint8_t *mem_reg = (uint8_t *) fdt_getprop(fdt, mem_offset, "reg", NULL); - pm_t base; /* if riscv128 comes around we will probably see addr_cells == 4, but * I'm not too concerned about it at the moment */ - if (ci.addr_cells == 2) { - base = fdt64_to_cpu(*(fdt64_t *) mem_reg); - mem_reg += sizeof(fdt64_t); - } else { - base = fdt32_to_cpu(*(fdt32_t *) mem_reg); - mem_reg += sizeof(fdt32_t); - } + pm_t base = fdt_load_int_ptr(pm_t, ci.addr_cells, mem_reg); - pm_t top; - if (ci.size_cells == 2) - top = fdt64_to_cpu(*(fdt64_t *) mem_reg) + base; + if(ci.addr_cells == 2) + mem_reg += sizeof(fdt64_t); else - top = fdt32_to_cpu(*(fdt32_t *) mem_reg) + base; + mem_reg += sizeof(fdt32_t); - struct mem_layout ret = { base, top }; + pm_t top = fdt_load_int_ptr(pm_t, ci.size_cells, mem_reg) + base; + struct pmem_layout ret = { base, top }; return ret; } @@ -74,7 +68,8 @@ static enum serial_dev_t serial_dev_enum(const char *dev_name) static void init_debug(void *fdt) { int chosen_offset = fdt_path_offset(fdt, "/chosen"); - const char *stdout = fdt_getprop(fdt, chosen_offset, "stdout-path", 0); + const char *stdout = fdt_getprop(fdt, chosen_offset, + "stdout-path", NULL); int stdout_offset = fdt_path_offset(fdt, stdout); @@ -89,10 +84,7 @@ static void init_debug(void *fdt) void *reg_ptr = (void *)fdt_getprop(fdt, stdout_offset, "reg", NULL); void *uart_ptr = 0; - if (ci.addr_cells == 2) - uart_ptr = (void *)(pm_t)fdt64_to_cpu(*(fdt64_t *) reg_ptr); - else - uart_ptr = (void *)(pm_t)fdt32_to_cpu(*(fdt32_t *) reg_ptr); + uart_ptr = (void *)fdt_load_int_ptr(pm_t, ci.addr_cells, reg_ptr); dbg_init(uart_ptr, dev); } @@ -101,46 +93,56 @@ static void init_debug(void *fdt) #define init_debug(...) #endif -/* TODO: these */ -static pm_t get_kerneltop(void *fdt) +static pm_t get_kerneltop() { - return 0; + /* interesting, for some reason if I define these to be just char + * pointers I get some wacky values. Not sure why that would be, but + * this works. */ + extern char __init_end[], __kernel_size[]; + return (pm_t)__init_end + (pm_t)__kernel_size; } static pm_t get_initrdtop(void *fdt) { - return 0; + int chosen_offset = fdt_path_offset(fdt, "/chosen"); + struct cell_info ci = get_cellinfo(fdt, chosen_offset); + + void *initrd_end_ptr = (void *)fdt_getprop(fdt, chosen_offset, + "linux,initrd-end", NULL); + + return fdt_load_int_ptr(pm_t, ci.addr_cells, initrd_end_ptr); } static pm_t get_fdttop(void *fdt) { - return 0; + const char *b = (const char *)fdt; + return (pm_t)(b + fdt_totalsize(fdt)); } static void setup_pmem(void *fdt) { - struct mem_layout pmem = get_memlayout(fdt); + struct pmem_layout pmem = get_memlayout(fdt); - pm_t kernel_top = get_kerneltop(fdt); pm_t initrd_top = get_initrdtop(fdt); + pm_t kernel_top = get_kerneltop(); pm_t fdt_top = get_fdttop(fdt); pm_t top = MAX3(kernel_top, initrd_top, fdt_top); + dbg("initrd_top:\t%#lx\n", initrd_top); + dbg("kernel_top:\t%#lx\n", kernel_top); + dbg("fdt_top:\t%#lx\n", fdt_top); } -void __noreturn init(void *fdt) +void init(void *fdt) { init_debug(fdt); dbg_fdt(fdt); setup_pmem(fdt); - /* basic memory layout info */ - struct mem_layout pmem = get_memlayout(fdt); - /* TODO: find first contiguous region */ /* generate pagetable at contiguous region */ - populate_pmap(pmem.base, pmem.top - pmem.base, 0/* something */); + /* populate_pmap(pmem.base, pmem.top - pmem.base, something); */ /* TODO: mark all used pages */ update_pmap(0/* TODO: figure out where in virtual memory the page map should be mapped */); diff --git a/include/libfdt.h b/include/libfdt.h index d734715..7425aef 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -9,4 +9,7 @@ void __dbg_fdt(void *fdt, int node_offset, int depth); #define dbg_fdt(...) #endif +#define fdt_load_int_ptr(t, c, p)\ + ((c) == 2 ? (t)fdt64_to_cpu(*(fdt64_t *)(p)) : (t)fdt32_to_cpu(*(fdt32_t *)(p))) + #endif diff --git a/scripts/gen-deps b/scripts/gen-deps index 6ddd289..7a468d3 100755 --- a/scripts/gen-deps +++ b/scripts/gen-deps @@ -13,7 +13,14 @@ gencommon () { } genlink () { gencommon ".ld" - echo " \$(GENLINK) $< | \$(STRIPLINK) > \$@" >> deps.mk + if [ "${init}" = "0" ] ; then + echo " \$(GENLINK) $< | \$(STRIPLINK) > \$@"\ + >> deps.mk; + else + echo " \$(GENLINK) $< | \$(STRIPLINK) | \$(KERN_INFO) > \$@"\ + >> deps.mk; + fi + } genrule () { @@ -32,10 +39,16 @@ case "${1}" in defs=-DINIT func=genrule ;; - --link) + --init-link) suffix=.ld + init=1 func=genlink ;; + + --kern-link) + suffix=.ld + init=0 + func=genlink esac for s in ${2} |
