hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/kernel/proc.rv
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-25 11:31:59 +0200
committerhachem <im@hachem.wtf>2026-09-25 11:31:59 +0200
commited285c9fc665e262ed21c7bf5734acb2b7a532db (patch)
treee51434e8069bc7219221cc1136515828d0293aca /kernel/proc.rv
parentd18d1da05a4d065d54787434d6bc46f3354626a5 (diff)
feat: load + run native ELF binaries
Diffstat (limited to 'kernel/proc.rv')
-rw-r--r--kernel/proc.rv40
1 files changed, 40 insertions, 0 deletions
diff --git a/kernel/proc.rv b/kernel/proc.rv
new file mode 100644
index 0000000..af6e8f7
--- /dev/null
+++ b/kernel/proc.rv
@@ -0,0 +1,40 @@
+# parse the embedded ELF (physical address from elf_phys()) and run it in ring 3
+
+const PT_LOAD = 1
+const PAGE_FLAGS = 6 # WRITE | USER
+
+fn cmd_run() do
+ const base = elf_phys()
+ if mem_read(base, 4) != 0x464c457f do
+ puts("run: not an ELF\n")
+ return :nil
+ end
+ const entry = mem_read(base + 24, 8)
+ const phoff = mem_read(base + 32, 8)
+ const phnum = mem_read(base + 56, 2)
+ const phentsize = mem_read(base + 54, 2)
+ const as = as_create()
+ for i in 0..phnum do
+ const ph = base + phoff + i * phentsize
+ if mem_read(ph, 4) == PT_LOAD do
+ const offset = mem_read(ph + 8, 8)
+ const vaddr = mem_read(ph + 16, 8)
+ const filesz = mem_read(ph + 32, 8)
+ const memsz = mem_read(ph + 40, 8)
+ let off = 0
+ while off < memsz do
+ const frame = frame_alloc()
+ mem_zero(frame, 4096)
+ if off < filesz do
+ const left = filesz - off
+ mem_copy(frame, base + offset + off, if left > 4096 4096 else left)
+ end
+ as_map(as, vaddr + off, frame, PAGE_FLAGS)
+ off = off + 4096
+ end
+ end
+ end
+ const stack_top = 0x7fff0000
+ as_map(as, stack_top - 4096, frame_alloc(), PAGE_FLAGS)
+ proc_run(as, entry, stack_top)
+end