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