aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2021-09-19 17:46:26 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2021-09-19 19:07:13 +0300
commit4dffc92abf8f6a6e9b503c9809caaa99795d7a00 (patch)
tree65fdb7c09f0b9a0ce2551fe8b51e637309322ed5
parent5979b0e7ba9064ae4033dbbe650bea86c2afb440 (diff)
downloadkmi-4dffc92abf8f6a6e9b503c9809caaa99795d7a00.tar.gz
kmi-4dffc92abf8f6a6e9b503c9809caaa99795d7a00.zip
Added basic awareness of kernel size/bounds
-rw-r--r--Makefile21
-rw-r--r--TODO.txt1
-rw-r--r--arch/riscv/conf/init-link.S21
-rw-r--r--arch/riscv/conf/kernel-link.S16
-rw-r--r--arch/riscv/init/init.c66
-rw-r--r--include/libfdt.h3
-rwxr-xr-xscripts/gen-deps17
7 files changed, 103 insertions, 42 deletions
diff --git a/Makefile b/Makefile
index 339f63e..0771908 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/TODO.txt b/TODO.txt
index 7782709..1d84441 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -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}