kernel/main.68k

147 lines
3.7 KiB
Plaintext
Raw Permalink Normal View History

2024-03-19 09:23:45 -05:00
include elf.i
include term.i
include traps.i
include vmem.i
include pmem.i
include initrd.i
include tasking.i
include start.i
include memory.i
section .text,text
public main
main:
move.l #inital_stack, a7 ; Load the initial stack pointer
jsr term_init
jsr traps_init
jsr vmem_init
jsr pmem_init
jsr initrd_init
jsr pmem_pop_frame
move.l #0, d2
move.l #$FEF000, a0
move.l #1, d1
move.l #$2, d3
move.l d0, -(a7)
jsr vmem_map_to
move.l (a7)+, d0
move.l #($FEF000+$1000), a7
clrfo
main.elf_header: fo.b Elf32_Ehdr.sizeof
link a6, #__FO ; Create a stack frame
move.l d0, a0
jsr tasking_init
; Activate the address space for init
move.l #init_addr_space, a0
jsr vmem_activate_addr_space
; Get the offset of init in the initrd
move.l #init_name, a0
jsr initrd_find_file
move.l d0, d5
; Read the ELF header
lea.l (main.elf_header,a6), a0
move.l #0, d1
move.l #Elf32_Ehdr.sizeof, d2
jsr initrd_read_bytes
; Allocate elf_header.e_phnum * 32 bytes to read the program headers into
clr.l d0
move.w (main.elf_header+Elf32_Ehdr.e_phnum,a6), d0
move.l d0, d4
lsl.l #5, d0
move.l d0, d2
jsr malloc
; Read the program headers
move.l (main.elf_header+Elf32_Ehdr.e_phoff,a6), d1
move.l a0, -(a7)
move.l d5, d0
jsr initrd_read_bytes
move.l (a7)+, a2
; Loop through the program headers
subi.l #1, d4
phead_loop:
; If the program header's type is not LOAD, skip it
move.l (Elf32_Phdr.p_type,a2), d0
cmpi.l #PT_LOAD, d0
bne.w skip_pheader
; Get the memory size of the pheader into d0 and round it to the next multiple of 4096
; round_size = p_memsz & 0xFFF > 0 ? p_memsz & ~(0xFFF) + 1 : p_memsz & ~(0xFF)
move.l (Elf32_Phdr.p_memsz,a2), d0
andi.l #$FFF, d0
beq.b .1
move.l #$1000, d1
bra.b .2
.1:
move.l #0, d1
.2:
move.l (Elf32_Phdr.p_memsz,a2), d0
andi.l #(~$FFF), d0
add.l d1, d0
; Shift the rounded size right by 12 to get the number of pages the pheader takes up
lsr.l #8, d0
lsr.l #4, d0
; Map the segment to free memory
move.l (Elf32_Phdr.p_vaddr,a2), a0
move.l #0, d1
move.l #6, d2
jsr vmem_map
; Zero the segment's memory
move.l (Elf32_Phdr.p_vaddr,a2), a0
move.l (Elf32_Phdr.p_memsz,a2), d0
subi.l #1, d0
.3:
move.b #0, (a0)+
dbra d0, .3
; Read the segment's data off disk
move.l d5, d0
move.l (Elf32_Phdr.p_offset,a2), d1
move.l (Elf32_Phdr.p_filesz,a2), d2
move.l (Elf32_Phdr.p_vaddr,a2), a0
jsr initrd_read_bytes
; Get the memory size of the pheader into d0 and round it to the next multiple of 4096
; Same as abobe
move.l (Elf32_Phdr.p_memsz,a2), d0
andi.l #$FFF, d0
beq.b .4
move.l #$1000, d1
bra.b .5
.4:
move.l #0, d1
.5:
move.l (Elf32_Phdr.p_memsz,a2), d0
andi.l #(~$FFF), d0
add.l d1, d0
; Shift the rounded size right by 12 to get the number of pages the pheader takes up
lsr.l #8, d0
lsr.l #4, d0
; Get the pheader's flags and make them into the page mapping flags, put the
; argumemts into the right registers, and set the flags for the pheader's memory
move.l d0, d1
move.l (Elf32_Phdr.p_vaddr,a2), a0
move.l (Elf32_Phdr.p_flags,a2), d0
andi.l #PF_W, d0
move.l (Elf32_Phdr.p_flags,a2), d2
andi.l #PF_X, d2
lsl.l #3, d2
or.l d2, d0
ori.l #$4, d0
move.l #$0, d2
jsr vmem_set_flags
skip_pheader:
; Advance to the next pheader and loop back if there are more
lea.l (Elf32_Phdr.sizeof,a2), a2
dbra d4, phead_loop
; Create the init process
move.l #init_addr_space, a0
move.l (main.elf_header+Elf32_Ehdr.e_entry,a6), a1
jsr tasking_new_process
unlk a6 ; Tear down the stack frame
jsr tasking_exit
section .bss,bss
ds.b 4096
inital_stack:
section .data,data
init_name: dc.b "init",0
align 1
init_addr_space: dc.l $0, $0, $0, kernel_map - $6000