Initial commit

This commit is contained in:
mid
2026-05-01 12:43:49 +03:00
commit 08f9c590e3
14 changed files with 1338 additions and 0 deletions

279
src/boot/x86/1_elf.asm Normal file
View 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