;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2020-2021. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; Version 2, or (at your option) any later version. ;; ;; ;; ;; Written by Ivan Baravy ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; format pe64 efi entry main section '.text' code executable readable include '../../struct.inc' include '../../macros.inc' include '../../kglobals.inc' fastcall fix fstcall include 'proc64.inc' include '../../const.inc' purge DQ include 'uefi64.inc' MEMORY_MAP_SIZE = 0x10000 PROTOCOL_HANDLERS_BUFFER_SIZE = 0x100 FILE_BUFFER_SIZE = 0x1000 KERNEL_TRAMPOLINE = 0x8f80 ; just before BOOT_LO KERNEL_BASE = 0x10000 RAMDISK_BASE = 0x100000 MAX_FILE_SIZE = 0x10000000 CODE_32_SELECTOR = 8 DATA_32_SELECTOR = 16 CODE_64_SELECTOR = 24 ; linux/arch/x86/include/uapi/asm/e820.h E820_RAM = 1 E820_RESERVED = 2 E820_ACPI = 3 E820_NVS = 4 E820_UNUSABLE = 5 E820_PMEM = 7 proc load_file _root, _name, _buffer, _size, _fatal mov [_root], rcx mov [_name], rdx mov [_buffer], r8 mov [_size], r9 mov r10, [_root] mov r11, [_name] fstcall [r10+EFI_FILE_PROTOCOL.Open], r10, file_handle, \ r11, EFI_FILE_MODE_READ, 0 test eax, eax jz @f mov [_size], 0 cmp [_fatal], 1 jnz .done mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error_open_file mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] mov rdx, [_name] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, [_name] jmp $ @@: lea rdx, [_size] mov r8, [_buffer] mov r10, [file_handle] fstcall [r10+EFI_FILE_PROTOCOL.Read], [file_handle], rdx, r8 mov r10, [file_handle] fstcall [r10+EFI_FILE_PROTOCOL.Close], [file_handle] .done: call clearbuf mov rax, [_size] mov rdi, msg call num2dec mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_file_size mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg mov rax, [_size] ret endp skip_whitespace: .next_char: cmp byte[rsi], 0 jz .done cmp byte[rsi], 0x20 ; ' ' jz .whitespace cmp byte[rsi], 9 ; '\t' jz .whitespace jmp .done .whitespace: inc rsi jmp .next_char .done: ret skip_until_newline: .next_char: cmp byte[rsi], 0 jz .done cmp byte[rsi], 0xd ; '\r' jz .done cmp byte[rsi], 0xa ; '\n' jz .done inc rsi jmp .next_char .done: ret skip_newline: .next_char: cmp byte[rsi], 0xd ; '\r' jz .newline cmp byte[rsi], 0xa ; '\n' jz .newline jmp .done .newline: inc rsi jmp .next_char .done: ret skip_line: call skip_until_newline call skip_newline ret dec2bin: mov edx, 0 .next_char: movzx eax, byte[rsi] test eax, eax jz .done sub eax, '0' jb .done cmp eax, 9 ja .done inc rsi imul edx, 10 add edx, eax jmp .next_char .done: mov eax, edx ret parse_option: mov rbx, config_options-3*8 .try_next_option: add rbx, 3*8 mov rdi, rsi mov rdx, [rbx] ; option name test rdx, rdx jz .done .next_char: cmp byte[rdx], 0 jnz @f cmp byte[rdi], '=' jz .opt_name_ok @@: cmp byte[rdi], 0 jz .done movzx eax, byte[rdi] cmp [rdx], al jnz .try_next_option inc rdi inc rdx jmp .next_char .opt_name_ok: inc rdi mov rsi, rdi call qword[rbx+8] .done: ret parse_line: .next_line: cmp byte[rsi], 0 jz .done cmp byte[rsi], 0xd ; '\r' jz .skip cmp byte[rsi], 0xa ; '\n' jz .skip cmp byte[rsi], '#' jz .skip call parse_option call skip_line jmp .next_line .skip: call skip_line jmp .next_line .done: ret cfg_opt_func_resolution: call dec2bin xor edx, edx mov [rdx+BOOT_LO.x_res], ax cmp byte[rsi], 'x' jz @f cmp byte[rsi], '*' jz @f jmp .done @@: inc rsi call dec2bin xor edx, edx mov [rdx+BOOT_LO.y_res], ax mov [cfg_opt_used_resolution], 1 .done: ret cfg_opt_func_acpi: call dec2bin mov [cfg_opt_used_acpi], 1 mov [cfg_opt_value_acpi], al ret cfg_opt_func_debug_print: call dec2bin mov [cfg_opt_used_debug_print], 1 mov [cfg_opt_value_debug_print], al ret cfg_opt_func_launcher_start: call dec2bin mov [cfg_opt_used_launcher_start], 1 mov [cfg_opt_value_launcher_start], al ret cfg_opt_func_mtrr: call dec2bin mov [cfg_opt_used_mtrr], 1 mov [cfg_opt_value_mtrr], al ret cfg_opt_func_ask_params: call dec2bin mov [cfg_opt_used_ask_params], 1 mov [cfg_opt_value_ask_params], al ret cfg_opt_func_imgfrom: call dec2bin mov [cfg_opt_used_imgfrom], 1 mov [cfg_opt_value_imgfrom], al ret cfg_opt_func_syspath: mov rdi, cfg_opt_value_syspath .next_char: movzx eax, byte[rsi] cmp al, 0xd ; \r jz .done cmp al, 0xa ; \n jz .done inc rsi stosb jmp .next_char .done: mov byte[rdi], 0 ret proc parse_config uses rbx rsi rdi, _buffer mov rsi, rcx mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_parsing_config .next_line: call parse_line cmp byte[rsi], 0 jnz .next_line ret endp proc read_options_from_config mov r10, [rbx+EFI_SYSTEM_TABLE.BootServices] fstcall [r10+EFI_BOOT_SERVICES.HandleProtocol], [efi_handle], \ lip_guid, lip_interface test eax, eax jz @f mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error_efi_lip_handle jmp $ @@: mov r11, [lip_interface] mov r10, [rbx+EFI_SYSTEM_TABLE.BootServices] fstcall [r10+EFI_BOOT_SERVICES.HandleProtocol], \ [r11+EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle], sfsp_guid, \ sfsp_interface test eax, eax jz @f mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error_lip_dev_sfsp jmp $ @@: mov r10, [sfsp_interface] fstcall [r10+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume], \ [sfsp_interface], esp_root test eax, eax jz @f mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error_sfsp_openvolume jmp $ @@: fstcall load_file, [esp_root], file_name, KERNEL_BASE, \ FILE_BUFFER_SIZE, 0 ; not fatal test eax, eax jz @f fstcall parse_config, KERNEL_BASE @@: .error: ret endp proc print_vmode uses rax rbx rcx rdx rsi rdi mov r10, rcx call clearbuf mov eax, [r10+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] mov rdi, msg call num2dec mov eax, [r10+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] mov rdi, msg+8*2 call num2dec mov eax, [r10+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat] mov rdi, msg+16*2 call num2dec mov eax, [r10+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine] mov rdi, msg+24*2 call num2dec mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg ret endp proc find_vmode_index_by_resolution mov [cfg_opt_used_resolution], 1 mov [cfg_opt_value_vmode], 0 .next_mode: movzx edx, [cfg_opt_value_vmode] mov r10, [gop_interface] fstcall [r10+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], [gop_interface], \ rdx, gop_info_size, gop_info cmp rax, EFI_SUCCESS jnz .error mov rcx, [gop_info] fstcall print_vmode ; PixelBlueGreenRedReserved8BitPerColor cmp [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat], 1 jnz .skip_mode xor edx, edx mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] cmp ax, [rdx+BOOT_LO.x_res] jnz .skip_mode mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] cmp ax, [rdx+BOOT_LO.y_res] jnz .skip_mode jmp .done .skip_mode: inc [cfg_opt_value_vmode] movzx eax, [cfg_opt_value_vmode] mov rcx, [gop_interface] mov rdx, [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode] cmp eax, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode] jnz .next_mode mov [cfg_opt_used_resolution], 0 mov [cfg_opt_value_ask_params], 1 mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error_no_such_vmode mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error jmp $ .error: .done: ret endp ask_for_params: jmp $ proc detect_pci_config fstcall get_protocol_interface, pcirbiop_guid mov [pcirbiop_interface], rax mov r10, rax fstcall [r10+EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Configuration], r10, \ pcirbiop_resources ; fstcall dump_pci_resources fstcall get_last_pci_bus call clearbuf movzx eax, [pci_last_bus] mov rdi, msg call num2hex mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_pci_last_bus mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg ret endp proc get_last_pci_bus mov rsi, [pcirbiop_resources] .next_resource: cmp [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Type], \ EFI_RESOURCE_DESCRIPTOR_TYPE.END_TAG jz .not_found mov rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.RangeMaximum] cmp [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.ResourceType], \ EFI_RESOURCE_TYPE.BUS jz .found movzx eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Length] lea rsi, [rsi+rax+3] jmp .next_resource .found: mov [pci_last_bus], al .not_found: ret endp proc main _efi_handle, _efi_table mov [efi_handle], rcx mov [efi_table], rdx mov rbx, rdx mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset], rcx, 1 test eax, eax jnz $ ; what can I do here? mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_u4k_loaded mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_detect_pci_config fstcall detect_pci_config mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_read_options fstcall read_options_from_config ; read kernel file mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_load_kernel fstcall load_file, [esp_root], kernel_name, KERNEL_BASE, \ MAX_FILE_SIZE, 1 ; fatal ; read ramdisk image mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_load_ramdisk fstcall load_file, [esp_root], ramdisk_name, RAMDISK_BASE, \ MAX_FILE_SIZE, 1 ; fatal ; alloc buffer for devices.dat mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_alloc_devicesdat mov r10, [rbx+EFI_SYSTEM_TABLE.BootServices] fstcall [r10+EFI_BOOT_SERVICES.AllocatePages], \ EFI_ALLOCATE_MAX_ADDRESS, EFI_RESERVED_MEMORY_TYPE, 1, \ devicesdat_data cmp eax, EFI_SUCCESS jnz .error ; read devices.dat mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_load_devicesdat fstcall load_file, [esp_root], devicesdat_name, [devicesdat_data], \ [devicesdat_size], 0 ; not fatal mov [devicesdat_size], rax mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_locate_gop_interface fstcall get_protocol_interface, gop_guid mov [gop_interface], rax fstcall find_rsdp mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_acpi_tables_done cmp [cfg_opt_used_resolution], 0 jz .not_used_resolution mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_opt_resolution call clearbuf xor edx, edx movzx eax, [rdx+BOOT_LO.x_res] mov rdi, msg call num2dec xor edx, edx movzx eax, [rdx+BOOT_LO.y_res] mov rdi, msg+8*2 call num2dec mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg fstcall find_vmode_index_by_resolution .not_used_resolution: cmp [cfg_opt_used_debug_print], 0 jz .not_used_debug_print movzx eax, [cfg_opt_value_debug_print] xor edx, edx mov [rdx+BOOT_LO.debug_print], al .not_used_debug_print: cmp [cfg_opt_value_ask_params], 0 jz @f call ask_for_params @@: movzx edx, [cfg_opt_value_vmode] mov r10, [gop_interface] fstcall [r10+EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode], [gop_interface], rdx test eax, eax jz @f call clearbuf mov rdi, msg call num2hex mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error jmp $ @@: mov rcx, [gop_interface] mov rdx, [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode] mov rdi, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.FrameBufferBase] mov [fb_base], rdi mov edx, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.Mode] mov r10, [gop_interface] fstcall [r10+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], [gop_interface], \ rdx, gop_info_size, gop_info test eax, eax jz @f jmp .error @@: mov rcx, [gop_info] mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] xor rdx, rdx mov [rdx+BOOT_LO.x_res], ax mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] mov [rdx+BOOT_LO.y_res], ax mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine] shl eax, 2 mov [rdx+BOOT_LO.pitch], ax mov [rdx+BOOT_LO.pci_data.access_mechanism], 1 movzx eax, [pci_last_bus] mov [rdx+BOOT_LO.pci_data.last_bus], al mov [rdx+BOOT_LO.pci_data.version], 0x0300 ; PCI 3.0 mov [rdx+BOOT_LO.pci_data.pm_entry], 0 ; kernel ; fstcall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \ ; 450000/0x1000, EFI_ALLOCATE_ADDRESS ; ramdisk ; fstcall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \ ; 2880*512/0x1000, EFI_ALLOCATE_ADDRESS fstcall calc_memmap ; fstcall dump_memmap mov r10, [rbx+EFI_SYSTEM_TABLE.BootServices] fstcall [r10+EFI_BOOT_SERVICES.ExitBootServices], [efi_handle], \ [memory_map_key] fstcall halt_on_error cli xor edx, edx xor esi, esi mov [rsi+BOOT_LO.bpp], 32 mov [rsi+BOOT_LO.vesa_mode], dx mov [rsi+BOOT_LO.bank_switch], edx mov rdi, [fb_base] mov [rsi+BOOT_LO.lfb], edi movzx eax, [cfg_opt_value_mtrr] mov [rsi+BOOT_LO.mtrr], al movzx eax, [cfg_opt_value_launcher_start] mov [rsi+BOOT_LO.launcher_start], al movzx eax, [cfg_opt_value_debug_print] mov [rsi+BOOT_LO.debug_print], al mov [rsi+BOOT_LO.dma], dl mov [rsi+BOOT_LO.apm_entry], edx mov [rsi+BOOT_LO.apm_version], dx mov [rsi+BOOT_LO.apm_flags], dx mov [rsi+BOOT_LO.apm_code_32], dx mov [rsi+BOOT_LO.apm_code_16], dx mov [rsi+BOOT_LO.apm_data_16], dx mov [rsi+BOOT_LO.bios_hd_cnt], dl movzx eax, [cfg_opt_value_imgfrom] mov [rsi+BOOT_LO.rd_load_from], al mov eax, dword[devicesdat_size] mov [rdx+BOOT_LO.devicesdat_size], eax mov eax, dword[devicesdat_data] mov [rdx+BOOT_LO.devicesdat_data], eax mov rsi, cfg_opt_value_syspath mov rdi, BOOT_LO.syspath mov ecx, 0x17 rep movsb ; kernel trampoline mov rsi, kernel_trampoline mov rdi, KERNEL_TRAMPOLINE mov ecx, kernel_trampoline.size rep movsb mov rax, GDTR lgdt [cs:rax] mov ax, DATA_32_SELECTOR mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax push CODE_32_SELECTOR mov rax, KERNEL_TRAMPOLINE push rax retf .error: mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error jmp $ endp proc halt_on_error test eax, eax jz @f call clearbuf mov rdi, msg call num2hex mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg jmp $ @@: ret endp proc get_protocol_interface uses rsi rdi, _guid locals .status dq ? endl mov [_guid], rcx mov [prot_handlers_buffer_size], PROTOCOL_HANDLERS_BUFFER_SIZE mov r10, [rbx+EFI_SYSTEM_TABLE.BootServices] fstcall [r10+EFI_BOOT_SERVICES.LocateHandle], \ EFI_LOCATE_SEARCH_TYPE.ByProtocol, [_guid], 0, \ prot_handlers_buffer_size, prot_handlers_buffer mov [.status], rax mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_protocol_buffer_size call clearbuf mov rax, [prot_handlers_buffer_size] mov rdi, msg call num2hex mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg mov rax, [.status] test eax, eax jz @f call clearbuf mov rdi, msg call num2hex mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg jmp $ @@: mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_look_for_handler mov rsi, prot_handlers_buffer .try_next_handle: mov rax, rsi mov rcx, prot_handlers_buffer sub rax, rcx cmp rax, [prot_handlers_buffer_size] jb @f mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error_out_of_handlers mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_error jmp $ @@: mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_query_handler mov r10, [rbx+EFI_SYSTEM_TABLE.BootServices] fstcall [r10+EFI_BOOT_SERVICES.HandleProtocol], qword[rsi], [_guid], \ prot_interface ;mov rax, 0x8000_0000_0000_0003 test eax, eax jz @f call clearbuf mov rdi, msg call num2hex mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg add rsi, 8 jmp .try_next_handle @@: mov rax, [prot_interface] ret endp proc find_rsdp uses rsi rdi mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_look_for_rsdp mov rdi, [rbx+EFI_SYSTEM_TABLE.ConfigurationTable] mov rcx, [rbx+EFI_SYSTEM_TABLE.NumberOfTableEntries] mov rax, 0x11d3e4f18868e871 mov rdx, 0x81883cc7800022bc .next_table: dec ecx js .all_tables_done cmp [rdi+0], rax jnz .not_acpi20 cmp [rdi+8], rdx jnz .not_acpi20 mov rax, [rdi+16] mov rdx, BOOT_LO.acpi_rsdp mov [rdx], eax jmp .all_tables_done .not_acpi20: add rdi, 24 jmp .next_table .all_tables_done: ret endp proc dump_pci_resources uses rsi rdi xor eax, eax mov rsi, [pcirbiop_resources] mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_dump_pci_resources .next_resource: call clearbuf movzx eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Type] cmp eax, EFI_RESOURCE_DESCRIPTOR_TYPE.END_TAG jz .done mov rdi, msg call num2hex mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg call clearbuf movzx eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.ResourceType] mov rdi, msg call num2dec mov rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.RangeMinimum] mov rdi, msg+2*2 call num2hex mov rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.RangeMaximum] mov rdi, msg+19*2 call num2hex mov rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.TranslationOffset] mov rdi, msg+36*2 call num2hex mov rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.AddressLength] mov rdi, msg+53*2 call num2hex mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg movzx eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Length] add eax, 3 add rsi, rax jmp .next_resource .done: ret endp proc calc_memmap uses rsi rdi mov r10, [rbx+EFI_SYSTEM_TABLE.BootServices] fstcall [r10+EFI_BOOT_SERVICES.AllocatePages], EFI_ALLOCATE_ANY_PAGES, \ EFI_RESERVED_MEMORY_TYPE, MEMORY_MAP_SIZE/0x1000, memory_map call halt_on_error mov r10, [rbx+EFI_SYSTEM_TABLE.BootServices] fstcall [r10+EFI_BOOT_SERVICES.GetMemoryMap], memory_map_size, \ [memory_map], memory_map_key, descriptor_size, descriptor_ver call halt_on_error mov rdi, BOOT_LO.memmap_blocks mov dword[rdi-4], 0 ; memmap_block_cnt mov rsi, [memory_map] mov r10, rsi add r10, [memory_map_size] .next_descr: fstcall add_uefi_memmap add rsi, [descriptor_size] cmp rsi, r10 jb .next_descr ret endp proc dump_memmap uses rsi rdi xor eax, eax mov rsi, BOOT_LO.memmap_blocks mov r12, [rax+BOOT_LO.memmap_block_cnt] call clearbuf mov eax, ebx mov rdi, msg call num2dec mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, \ msg_memmap mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg call clearbuf .next_mapping: dec r12d js .done mov rax, rsi mov rcx, BOOT_LO.memmap_blocks sub rax, rcx mov ecx, sizeof.e820entry xor edx, edx div ecx mov rdi, msg call num2dec mov rax, [rsi+e820entry.addr] mov rdi, msg+4*2 call num2hex mov rax, [rsi+e820entry.size] mov rdi, msg+24*2 call num2hex mov rcx, [rbx+EFI_SYSTEM_TABLE.ConOut] fstcall [rcx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rcx, msg add rsi, sizeof.e820entry jmp .next_mapping .done: ret endp ; linux/arch/x86/platform/efi/efi.c ; do_add_efi_memmap proc add_uefi_memmap xor eax, eax cmp [rax+BOOT_LO.memmap_block_cnt], MAX_MEMMAP_BLOCKS jz .done mov rax, [rsi+EFI_MEMORY_DESCRIPTOR.PhysicalStart] mov [rdi+e820entry.addr], rax mov rax, [rsi+EFI_MEMORY_DESCRIPTOR.NumberOfPages] shl rax, 12 mov [rdi+e820entry.size], rax mov ecx, [rsi+EFI_MEMORY_DESCRIPTOR.Type] cmp ecx, EFI_LOADER_CODE jz .mem_ram_if_wb cmp ecx, EFI_LOADER_DATA jz .mem_ram_if_wb cmp ecx, EFI_BOOT_SERVICES_CODE jz .mem_ram_if_wb cmp ecx, EFI_BOOT_SERVICES_DATA jz .mem_ram_if_wb cmp ecx, EFI_CONVENTIONAL_MEMORY jz .mem_ram_if_wb cmp ecx, EFI_ACPI_RECLAIM_MEMORY mov eax, E820_ACPI jz .type_done cmp ecx, EFI_ACPI_MEMORY_NVS mov eax, E820_NVS jz .type_done cmp ecx, EFI_UNUSABLE_MEMORY mov eax, E820_UNUSABLE jz .type_done cmp ecx, EFI_PERSISTENT_MEMORY mov eax, E820_PMEM jz .type_done jmp .reserved .mem_ram_if_wb: test [rsi+EFI_MEMORY_DESCRIPTOR.Attribute], dword EFI_MEMORY_WB mov eax, E820_RAM jnz .type_done .reserved: mov eax, E820_RESERVED .type_done: mov [rdi+e820entry.type], eax cmp eax, E820_RAM jnz @f xor eax, eax inc [rax+BOOT_LO.memmap_block_cnt] add rdi, sizeof.e820entry @@: .done: ret endp num2dec: push rbx rcx rdx rdi xor ecx, ecx mov ebx, 10 .next_digit: xor edx, edx div ebx push rdx inc ecx test eax, eax jnz .next_digit .next_char: pop rax add eax, '0' stosw loop .next_char pop rdi rdx rcx rbx ret num2hex: push rbx rcx rdx rdi xchg rdx, rax mov ecx, 16 .next_tetra: rol rdx, 4 movzx eax, dl and eax, 0x0f movzx eax, byte[hex_abc+eax] stosw loop .next_tetra pop rdi rdx rcx rbx ret clearbuf: push rcx rdi mov eax, ' ' mov ecx, 79 mov rdi, msg rep stosw pop rdi rcx ret use32 kernel_trampoline: org KERNEL_TRAMPOLINE mov eax, cr0 and eax, not CR0_PG mov cr0, eax mov ecx, MSR_AMD_EFER rdmsr btr eax, 8 ; LME wrmsr mov eax, cr4 and eax, not CR4_PAE mov cr4, eax push KERNEL_BASE retn align 16 GDTR: dw 4*8-1 dq GDT align 16 GDT: dw 0, 0, 0, 0 dw 0FFFFh,0,9A00h,0CFh ; 32-bit code dw 0FFFFh,0,9200h,0CFh ; flat data dw 0FFFFh,0,9A00h,0AFh ; 64-bit code assert $ < BOOT_LO kernel_trampoline.size = $ - KERNEL_TRAMPOLINE section '.rodata' data readable gop_guid db EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID lip_guid db EFI_LOADED_IMAGE_PROTOCOL_GUID sfsp_guid db EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID pcirbiop_guid db EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID file_name du '\EFI\KOLIBRIOS\KOLIBRI.INI',0 kernel_name du '\EFI\KOLIBRIOS\KOLIBRI.KRN',0 ramdisk_name du '\EFI\KOLIBRIOS\KOLIBRI.IMG',0 devicesdat_name du '\EFI\KOLIBRIOS\DEVICES.DAT',0 config_options dq cfg_opt_name_resolution, cfg_opt_func_resolution, \ cfg_opt_cmnt_resolution, \ cfg_opt_name_acpi, cfg_opt_func_acpi, cfg_opt_cmnt_acpi, \ cfg_opt_name_debug_print, cfg_opt_func_debug_print, \ cfg_opt_cmnt_debug_print, \ cfg_opt_name_launcher_start, cfg_opt_func_launcher_start, \ cfg_opt_cmnt_launcher_start, \ cfg_opt_name_mtrr, cfg_opt_func_mtrr, cfg_opt_cmnt_mtrr, \ cfg_opt_name_ask_params, cfg_opt_func_ask_params, \ cfg_opt_cmnt_ask_params, \ cfg_opt_name_imgfrom, cfg_opt_func_imgfrom, \ cfg_opt_cmnt_imgfrom, \ cfg_opt_name_syspath, cfg_opt_func_syspath, \ cfg_opt_cmnt_syspath, \ 0 cfg_opt_name_resolution db "resolution",0 cfg_opt_name_acpi db "acpi",0 cfg_opt_name_debug_print db "debug_print",0 cfg_opt_name_launcher_start db "launcher_start",0 cfg_opt_name_mtrr db "mtrr",0 cfg_opt_name_ask_params db "ask_params",0 cfg_opt_name_imgfrom db "imgfrom",0 cfg_opt_name_syspath db "syspath",0 cfg_opt_cmnt_resolution db "# Graphic mode",0 cfg_opt_cmnt_acpi db "# ACPI settings",0xa, \ "# 0: don't use",0xa, \ "# 1: parse ACPI tables",0xa, \ "# 2: + call _PIC method",0xa, \ "# 3: + get APIC interrupts",0xa,0 cfg_opt_cmnt_debug_print db "# Duplicate debug output to the screen",0 cfg_opt_cmnt_launcher_start db "# Start LAUNCHER app after kernel is loaded",0 cfg_opt_cmnt_mtrr db "# Configure MTRR's",0 cfg_opt_cmnt_ask_params db "# Interrupt booting to ask the user for boot", \ " params",0 cfg_opt_cmnt_imgfrom db "# Where to load ramdisk image from",0 cfg_opt_cmnt_syspath db "# Path to /sys directory",0 msg_u4k_loaded du "uefi64kos loaded",13,10,0 msg_detect_pci_config du "Detect PCI configuration",13,10,0 msg_dump_pci_resources du "Dump PCI resources",13,10,0 msg_pci_last_bus du "Last PCI bus",13,10,0 msg_read_options du "Read options from config file",13,10,0 msg_file_size du "File size:",13,10,0 msg_parsing_config du "Parsing config file",13,10,0 msg_load_kernel du "Load kernel",13,10,0 msg_load_ramdisk du "Load ramdisk",13,10,0 msg_load_devicesdat du "Load DEVICES.DAT",13,10,0 msg_alloc_devicesdat du "Allocate memory for DEVICES.DAT",13,10,0 msg_locate_gop_interface du "Locate GOP interface",13,10,0 msg_look_for_handler du "Look for protocol handler",13,10,0 msg_query_handler du "Query handler",13,10,0 msg_query_vmode du "Query vmode",13,10,0 msg_vmode_found du "Video mode found",13,10,0 msg_look_for_rsdp du "Look for RSDP",13,10,0 msg_rsdp_found du "RSDP found",13,10,0 msg_acpi_tables_done du "ACPI tables done",13,10,0 msg_ask_for_params du "Ask for params",13,10,0 msg_set_graphic_mode du "Set graphic mode",13,10,0 msg_success du "Success!",13,10,0 msg_protocol_buffer_size du "Protocol buffer size",13,10,0 msg_opt_resolution du "Option resolution: ",0 msg_memmap du "Memmap",13,10,0 msg_error du "Error!",13,10,0 msg_error_efi_lip_handle du "efi_handle can't handle LIP",13,10,0 msg_error_lip_dev_sfsp du "LIP device handle can't handle SFSP",13,10,0 msg_error_sfsp_openvolume du "SFSP OpenVolume failed",13,10,0 msg_error_no_such_vmode du "No such vmode",13,10,0 msg_error_out_of_handlers du "Out of handlers",13,10,0 msg_error_open_file du "Error: can't open file ",0 msg_error_exit_boot_services du "Error: Exit boot services",13,10,0 msg du 79 dup " ",13,10,0 msg_debug du "Debug ",13,10,0 section '.data' data readable writeable efi_handle dq 0 efi_table dq 0 fb_base dq 0 gop_interface dq 0 gop_info_size dq 0 gop_info dq 0 lip_interface dq 0 sfsp_interface dq 0 pci_last_bus db 254 cfg_opt_used_resolution db 0 cfg_opt_used_acpi db 0 cfg_opt_used_debug_print db 0 cfg_opt_used_launcher_start db 0 cfg_opt_used_mtrr db 0 cfg_opt_used_ask_params db 0 cfg_opt_used_imgfrom db 0 cfg_opt_used_syspath db 0 cfg_opt_value_vmode db 0 cfg_opt_value_acpi db 0 cfg_opt_value_debug_print db 0 cfg_opt_value_launcher_start db 1 cfg_opt_value_mtrr db 0 cfg_opt_value_ask_params db 0 cfg_opt_value_imgfrom db RD_LOAD_FROM_MEMORY cfg_opt_value_syspath db "/RD/1",0 rb 20 memory_map_key dq 0 descriptor_size dq 0 descriptor_ver dq 0 memory_map_size dq MEMORY_MAP_SIZE efi_fs_info_id db EFI_FILE_SYSTEM_INFO_ID efi_fs_info_size dq sizeof.EFI_FILE_SYSTEM_INFO devicesdat_data dq 0xffffffff devicesdat_size dq 0x1000 hex_abc db '0123456789ABCDEF' section '.bss' data readable writeable discardable prot_handlers_buffer_size dq ? prot_interface dq ? esp_root dq ? file_handle dq ? pcirbiop_interface dq ? pcirbiop_resources dq ? efi_fs_info EFI_FILE_SYSTEM_INFO memory_map dq ? prot_handlers_buffer rq PROTOCOL_HANDLERS_BUFFER_SIZE/8 pcirbio_buffer rq PROTOCOL_HANDLERS_BUFFER_SIZE/8 section '.reloc' fixups data discardable