aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-07-05 19:38:11 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-07-05 19:38:11 +0300
commite09edb5d54e39bd9509a1dc450df5ab320759f97 (patch)
tree78e050b0db87df3a3ddfbb6570d44513ac34e02a /src/main.c
parent98f21e694a6b0964d6d08196cb6bfbc1c2ae2ff4 (diff)
downloadkmi-e09edb5d54e39bd9509a1dc450df5ab320759f97.tar.gz
kmi-e09edb5d54e39bd9509a1dc450df5ab320759f97.zip
allow booting with Qemu's -kernel flag directly
+ Took some fairly significant changes, for one the kernel is no longer relocated at the start of a boot, instead it sits wherever the user decides the kernel should sit. Similarly, the initial kernel stack and page table are stored within the binary, slightly bloating the size but making it much safer to boot since there's really no chance of us overwriting the fdt or initrd in memory.
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c92
1 files changed, 69 insertions, 23 deletions
diff --git a/src/main.c b/src/main.c
index 4647fed..19d52a2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -19,6 +19,54 @@
#include <arch/smp.h>
#include <libfdt.h>
+static pm_t __fdt_ram_base(void *fdt)
+{
+ int mem_offset = fdt_path_offset(fdt, "/memory");
+ const void *mem_reg = fdt_getprop(fdt, mem_offset, "reg", NULL);
+
+ struct cell_info ci = get_cellinfo(fdt, mem_offset);
+ return (pm_t)fdt_load_reg_addr(ci, mem_reg, 0);
+}
+
+static pm_t __fdt_ram_size(void *fdt)
+{
+ int mem_offset = fdt_path_offset(fdt, "/memory");
+ const void *mem_reg = fdt_getprop(fdt, mem_offset, "reg", NULL);
+
+ /* here we actually want the root offset because /memory itself doesn't
+ * have children, I guess? */
+ struct cell_info ci = get_cellinfo(fdt, fdt_path_offset(fdt, "/"));
+ return (pm_t)fdt_load_reg_size(ci, mem_reg, 0);
+}
+
+void kernel(void *fdt, uintptr_t load_addr, struct vmem *d)
+{
+ fdt = __va(fdt);
+
+ /* dbg uses direct mapping at this point */
+ init_dbg(fdt);
+ /* start up debugging in kernel IO */
+ setup_io_dbg(d);
+
+ dbg_fdt(fdt);
+
+ setup_arch(fdt);
+
+ init_pmem(fdt, load_addr);
+
+ init_irq(fdt);
+ init_timer(fdt);
+
+ vm_t proc_fdt = 0, proc_initrd = 0;
+ init_proc(fdt, &proc_fdt, &proc_initrd);
+
+ /* try to bring up other cores on system */
+ smp_bringup(d, fdt);
+
+ /* start running init program */
+ run_init(cur_tcb(), proc_fdt, proc_initrd);
+}
+
/**
* Boot entry of kernel actual.
*
@@ -29,35 +77,33 @@
* @param ram_base RAM base.
* @return Should not.
*/
-void __main main(void *fdt, uintptr_t ram_base)
+void main(unsigned long hart, void *fdt, uintptr_t load_addr)
{
- set_ram_base(ram_base);
+ /* we have our own ways to get the current hart when we need it, but we
+ * have to get the function signature right */
+ (void)hart;
- /* convert physical address to virtual address */
- fdt = __va(fdt);
-
- /* dbg uses direct mapping at this point */
- init_dbg(fdt);
- setup_dmap_dbg();
- dbg_fdt(fdt);
+ pm_t ram_base = __fdt_ram_base(fdt);
+ pm_t ram_size = __fdt_ram_size(fdt);
+ set_ram_base(ram_base);
+ set_ram_size(ram_size);
- setup_arch(fdt);
+ init_mem(fdt);
- init_pmem(fdt);
- /* setup temporary virtual memory */
- struct vmem *b = init_vmem(fdt);
+ struct vmem *d = direct_mapping();
- /* start up debugging in kernel IO */
- setup_io_dbg(b);
+ to_kernelspace(fdt, load_addr, d, ram_base, VM_DMAP);
+ unreachable();
+}
- init_irq(fdt);
- init_timer(fdt);
- init_proc(fdt);
+#if GENERIC_UBOOT
+void main_go(size_t argc, char *argv[], uintptr_t load_addr)
+{
+ if (argc != 2)
+ return;
- /* try to bring up other cores on system */
- smp_bringup(b, fdt);
+ void *fdt = (void *)strtouintptr(argv[1]);
- /* start running init program */
- void *initrd = (void *)get_initrdbase(fdt);
- run_init(cur_tcb(), fdt, initrd);
+ main(0, fdt, load_addr);
}
+#endif