diff options
Diffstat (limited to 'kernel/proc.rv')
| -rw-r--r-- | kernel/proc.rv | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/kernel/proc.rv b/kernel/proc.rv index 92d48f1..8d7827a 100644 --- a/kernel/proc.rv +++ b/kernel/proc.rv @@ -9,35 +9,45 @@ fn load_elf(base, arg) do puts("not an ELF\n") return :nil end + const entry = mem_read(base + 24, 8) const program_header_offset = mem_read(base + 32, 8) const program_header_count = mem_read(base + 56, 2) const program_header_size = mem_read(base + 54, 2) const space = as_create() + for index in 0..program_header_count do const header = base + program_header_offset + index * program_header_size + if mem_read(header, 4) == PT_LOAD do const file_offset = mem_read(header + 8, 8) const virtual_address = mem_read(header + 16, 8) const file_size = mem_read(header + 32, 8) const memory_size = mem_read(header + 40, 8) let segment_offset = 0 - while segment_offset < memory_size do + + while (segment_offset < memory_size) do const frame = frame_alloc() mem_zero(frame, 4096) + if segment_offset < file_size do const remaining = file_size - segment_offset - mem_copy(frame, base + file_offset + segment_offset, if remaining > 4096 4096 else remaining) + mem_copy(frame, base + file_offset + segment_offset, if (remaining > 4096) 4096 else remaining) end + as_map(space, virtual_address + segment_offset, frame, PAGE_FLAGS) segment_offset = segment_offset + 4096 end end end + const stack_top = 0x7fff0000 + for page in 0..4 do as_map(space, stack_top - (page + 1) * 4096, frame_alloc(), PAGE_FLAGS) end + let arg_ptr = 0 const arg_len = arg:len() + if arg_len > 0 do const arg_frame = frame_alloc() mem_zero(arg_frame, 4096) @@ -45,31 +55,50 @@ fn load_elf(base, arg) do as_map(space, ARG_VADDR, arg_frame, PAGE_FLAGS) arg_ptr = ARG_VADDR end + proc_run(space, entry, stack_top, arg_ptr, arg_len) end -# one reused contiguous buffer to stage an elf image read off the disk, since -# load_elf wants a flat base to mem_read from and a file lands in scattered frames -# its a weird arch but wtv +#* one reused contiguous buffer to stage an elf image read off the disk, since + load_elf wants a flat base to mem_read from and a file lands in scattered frames + its a weird arch but wtv *# global loader = { scratch = 0 } const SCRATCH_PAGES = 64 -fn load_file_elf(path, arg) do +fn load_file_elf(path, arg) -> bool do const size = fs:size(path) - if size < 0 do puts("#{path}: not found\n") return :false end - if size > SCRATCH_PAGES * 4096 do puts("#{path}: too big to load\n") return :false end - if loader.scratch == 0 do loader.scratch = alloc_contig(SCRATCH_PAGES) end - if loader.scratch == 0 do puts("no memory for elf load\n") return :false end + if size < 0 do + puts("#{path}: not found\n") + return :false + end + if size > SCRATCH_PAGES * 4096 do + puts("#{path}: too big to load\n") + return :false + end + + if loader.scratch == 0 do + loader.scratch = alloc_contig(SCRATCH_PAGES) + end + if loader.scratch == 0 do + puts("no memory for elf load\n") + return :false + end + blit_str(loader.scratch, fs:read_bytes(path, 0, size)) load_elf(loader.scratch, arg) + return :true end -fn run_prog(name, arg) do +fn run_prog(name, arg) -> bool do let bare_name = name - if bare_name:starts_with?("/usr/bin/") bare_name = bare_name[9..] + if (bare_name:starts_with?("/usr/bin/")) + bare_name = bare_name[9..] + const path = "/usr/bin/#{bare_name}" - if fs:size(path) < 0 return :false + if (fs:size(path) < 0) + return :false + return load_file_elf(path, arg) end |
