Initial commit
This commit is contained in:
279
src/boot/x86/1_elf.asm
Normal file
279
src/boot/x86/1_elf.asm
Normal file
@@ -0,0 +1,279 @@
|
||||
struc ELFHeader
|
||||
.e_ident resb 16
|
||||
.e_type resw 1
|
||||
.e_machine resw 1
|
||||
.e_version resd 1
|
||||
.e_entry resd 1
|
||||
.e_phoff resd 1
|
||||
.e_shoff resd 1
|
||||
.e_flags resd 1
|
||||
.e_ehsize resw 1
|
||||
.e_phentsize resw 1
|
||||
.e_phnum resw 1
|
||||
.e_shentsize resw 1
|
||||
.e_shnum resw 1
|
||||
.e_shstrndx resw 1
|
||||
endstruc
|
||||
|
||||
struc ELFSection
|
||||
.sh_name resd 1
|
||||
.sh_type resd 1
|
||||
.sh_flags resd 1
|
||||
.sh_addr resd 1
|
||||
.sh_offset resd 1
|
||||
.sh_size resd 1
|
||||
.sh_link resd 1
|
||||
.sh_info resd 1
|
||||
.sh_addralign resd 1
|
||||
.sh_entsize resd 1
|
||||
endstruc
|
||||
|
||||
struc ELFProgram
|
||||
.p_type resd 1
|
||||
.p_offset resd 1
|
||||
.p_vaddr resd 1
|
||||
.p_paddr resd 1
|
||||
.p_filesz resd 1
|
||||
.p_memsz resd 1
|
||||
.p_flags resd 1
|
||||
.p_align resd 1
|
||||
endstruc
|
||||
|
||||
struc ELFSym
|
||||
.st_name resd 1
|
||||
.st_value resd 1
|
||||
.st_size resd 1
|
||||
.st_info resb 1
|
||||
.st_other resb 1
|
||||
.st_shndx resw 1
|
||||
endstruc
|
||||
|
||||
; in eax = kernel file inode
|
||||
load_kernel:
|
||||
pushad
|
||||
|
||||
mov edi, ext2_get_inode_data_SCRATCH
|
||||
call ext2_get_inode_data
|
||||
|
||||
mov esi, ext2_get_inode_data_SCRATCH
|
||||
mov eax, 0
|
||||
mov ecx, [ext2_get_inode_data_SCRATCH + 4] ; filesize
|
||||
mov edi, KERNEL_INITIAL_LOAD
|
||||
call ext2_read_inode_bytes
|
||||
|
||||
cmp dword [KERNEL_INITIAL_LOAD], 0x464C457F ;ELF signature
|
||||
je .pass_signature
|
||||
popad
|
||||
stc
|
||||
ret
|
||||
.pass_signature:
|
||||
|
||||
; follow the LOAD program header instructions
|
||||
|
||||
movzx ecx, word [KERNEL_INITIAL_LOAD + ELFHeader.e_phnum]
|
||||
movzx ebp, word [KERNEL_INITIAL_LOAD + ELFHeader.e_phentsize]
|
||||
mov eax, KERNEL_INITIAL_LOAD
|
||||
add eax, [eax + ELFHeader.e_phoff]
|
||||
|
||||
.lup0:
|
||||
cmp dword [eax + ELFProgram.p_type], 1 ; PT_LOAD
|
||||
jne .skip0
|
||||
pushad
|
||||
|
||||
mov esi, [eax + ELFProgram.p_offset]
|
||||
|
||||
mov ecx, [eax + ELFProgram.p_memsz]
|
||||
add ecx, esi
|
||||
add ecx, 4095
|
||||
and ecx, ~4095
|
||||
and esi, ~4095
|
||||
sub ecx, esi
|
||||
|
||||
add esi, KERNEL_INITIAL_LOAD
|
||||
|
||||
mov edi, [eax + ELFProgram.p_vaddr]
|
||||
and edi, ~4095
|
||||
add edi, KERNEL_BASE
|
||||
|
||||
test ecx, ecx
|
||||
jz .skipcopy
|
||||
rep movsb
|
||||
.skipcopy:
|
||||
|
||||
mov edi, [eax + ELFProgram.p_vaddr]
|
||||
add edi, KERNEL_BASE
|
||||
add edi, [eax + ELFProgram.p_filesz]
|
||||
|
||||
mov ecx, [eax + ELFProgram.p_memsz]
|
||||
sub ecx, [eax + ELFProgram.p_filesz]
|
||||
|
||||
test ecx, ecx
|
||||
jz .skipbss
|
||||
mov eax, 0
|
||||
rep stosb
|
||||
.skipbss:
|
||||
|
||||
cmp edi, [KERNEL_END]
|
||||
jbe .maxkernelend
|
||||
mov [KERNEL_END], edi
|
||||
.maxkernelend:
|
||||
|
||||
popad
|
||||
.skip0:
|
||||
add eax, ebp
|
||||
dec ecx
|
||||
jnz .lup0
|
||||
|
||||
; fix up the relocations
|
||||
|
||||
mov esi, KERNEL_INITIAL_LOAD
|
||||
mov eax, string_reldyn
|
||||
call elf_find_array_section_by_name
|
||||
.lup2:
|
||||
mov ebx, [eax]
|
||||
add dword [KERNEL_BASE + ebx], KERNEL_BASE
|
||||
add eax, ebp
|
||||
|
||||
dec ecx
|
||||
jnz .lup2
|
||||
|
||||
; Save .dynstr for elf_find_symbol to use
|
||||
|
||||
mov esi, KERNEL_INITIAL_LOAD
|
||||
mov eax, string_dynstr
|
||||
call elf_find_array_section_by_name
|
||||
mov [elf_DYNSTR_TABLE], eax
|
||||
|
||||
; Save .dynsym for elf_find_symbol to use
|
||||
|
||||
mov esi, KERNEL_INITIAL_LOAD
|
||||
mov eax, string_dynsym
|
||||
call elf_find_array_section_by_name
|
||||
mov [elf_DYNSYM_TABLE], eax
|
||||
mov [elf_DYNSYMS], ecx
|
||||
|
||||
popad
|
||||
clc
|
||||
ret
|
||||
|
||||
; in esi = ptr to elf file
|
||||
; in eax = section name ptr
|
||||
; out eax = ptr to section data (or 0)
|
||||
; out ebp = section entry size
|
||||
; out ecx = section entry count
|
||||
elf_find_array_section_by_name:
|
||||
push ebx
|
||||
push edx
|
||||
|
||||
; ebx = section name ptr
|
||||
mov ebx, eax
|
||||
|
||||
; ebp = section table entry size
|
||||
movzx ebp, word [esi + ELFHeader.e_shentsize]
|
||||
|
||||
movzx eax, word [esi + ELFHeader.e_shstrndx]
|
||||
mul ebp
|
||||
|
||||
; edx = section table
|
||||
mov edx, [esi + ELFHeader.e_shoff]
|
||||
add edx, esi
|
||||
|
||||
; eax = string table
|
||||
add eax, edx
|
||||
mov eax, [eax + ELFSection.sh_offset]
|
||||
add eax, esi
|
||||
|
||||
; ecx = section index counter
|
||||
mov ecx, 0
|
||||
.lup:
|
||||
push eax
|
||||
push ebx
|
||||
add eax, [edx + ELFSection.sh_name]
|
||||
call streq
|
||||
pop ebx
|
||||
pop eax
|
||||
je .found
|
||||
|
||||
add edx, ebp
|
||||
inc ecx
|
||||
cmp cx, word [esi + ELFHeader.e_shnum]
|
||||
jb .lup
|
||||
|
||||
mov eax, 0
|
||||
jmp .notfound
|
||||
.found:
|
||||
|
||||
; eax = section header
|
||||
mov eax, ecx
|
||||
mul ebp
|
||||
add eax, [esi + ELFHeader.e_shoff]
|
||||
add eax, esi
|
||||
|
||||
; ebp = section entry size
|
||||
mov ebp, [eax + ELFSection.sh_entsize]
|
||||
|
||||
; ecx = entry count
|
||||
mov ecx, 0
|
||||
|
||||
test ebp, ebp
|
||||
jz .zeroentitysize
|
||||
push eax
|
||||
mov eax, [eax + ELFSection.sh_size]
|
||||
mov edx, 0
|
||||
div ebp
|
||||
mov ecx, eax
|
||||
pop eax
|
||||
.zeroentitysize:
|
||||
|
||||
mov eax, [eax + ELFSection.sh_offset]
|
||||
add eax, esi
|
||||
|
||||
.notfound:
|
||||
pop edx
|
||||
pop ebx
|
||||
|
||||
ret
|
||||
|
||||
elf_find_symbol:
|
||||
cmp dword [elf_DYNSTR_TABLE], 0
|
||||
jnz .inited1
|
||||
; table not loaded
|
||||
ret
|
||||
.inited1:
|
||||
cmp dword [elf_DYNSYM_TABLE], 0
|
||||
jnz .inited2
|
||||
; table not loaded
|
||||
ret
|
||||
.inited2:
|
||||
|
||||
push edx
|
||||
push ecx
|
||||
push ebx
|
||||
|
||||
mov edx, [elf_DYNSYM_TABLE]
|
||||
mov ecx, 0
|
||||
|
||||
.lup:
|
||||
mov ebx, [elf_DYNSTR_TABLE]
|
||||
add ebx, [edx + ELFSym.st_name]
|
||||
push eax
|
||||
call streq
|
||||
pop eax
|
||||
je .found
|
||||
|
||||
add edx, 16 ; symbol size
|
||||
inc ecx
|
||||
cmp ecx, [elf_DYNSYMS]
|
||||
jne .lup
|
||||
|
||||
; symbol not found
|
||||
mov edx, 0
|
||||
|
||||
.found:
|
||||
mov eax, edx
|
||||
|
||||
pop ebx
|
||||
pop ecx
|
||||
pop edx
|
||||
|
||||
ret
|
||||
Reference in New Issue
Block a user