151 lines
3.9 KiB
Plaintext
151 lines
3.9 KiB
Plaintext
include cards.i
|
|
include initrd.i
|
|
include syscalls.i
|
|
include elf.i
|
|
include memory.i
|
|
section .text,text
|
|
public main
|
|
main:
|
|
clrfo
|
|
main.elf_header: fo.b Elf32_Ehdr.sizeof
|
|
link a6, #__FO ; Create a stack frame
|
|
move.l #msg, a0
|
|
jsr syscall_println
|
|
jsr cards_init
|
|
jsr initrd_init
|
|
move.l #test_proc_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
|
|
hdr_read:
|
|
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
|
|
phdr_read:
|
|
; 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
|
|
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 #6, d1
|
|
jsr syscall_vmem_map_free
|
|
move.l a0, a3 ; Save the allocated address in a3
|
|
; Offset the allocated address by the page offset in the pheader's virtaddr field
|
|
move.l (Elf32_Phdr.p_vaddr,a2), d0
|
|
andi.l #$FFF, d0
|
|
adda.l d0, a3
|
|
move.l a3, a0
|
|
; Zero the segment's memory
|
|
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 a3, 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 above
|
|
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 a3, 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 syscall_vmem_set_flags
|
|
move.l a3, a0
|
|
; Get the memory size of the pheader into d0 and round it to the next multiple of 4096
|
|
; Same as above
|
|
move.l (Elf32_Phdr.p_memsz,a2), d0
|
|
andi.l #$FFF, d0
|
|
beq.b .6
|
|
move.l #$1000, d1
|
|
bra.b .7
|
|
.6:
|
|
move.l #0, d1
|
|
.7:
|
|
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 starting page of the allocated memory segment into a0
|
|
move.l a3, d1
|
|
andi.l #(~$FFF), d1
|
|
move.l d1, a0
|
|
move.l (Elf32_Phdr.p_vaddr,a2), a1
|
|
dbg:
|
|
jsr syscall_vmem_copy_to_secondary
|
|
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 (main.elf_header+Elf32_Ehdr.e_entry,a6), a0
|
|
jsr syscall_new_process
|
|
unlk a6
|
|
rts
|
|
|
|
section .data,data
|
|
msg: dc.b "Hello from init",0
|
|
test_proc_name: dc.b "test_proc",0
|
|
|
|
section .bss,bss
|
|
tmp_stack: ds.b 32
|
|
tmp_stack_top:
|