;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2020-2024. 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 pe efi entry main section '.text' code executable readable include '../../struct.inc' include '../../macros.inc' include '../../proc32.inc' include '../../const.inc' include 'uefi32.inc' MEMORY_MAP_SIZE = 0x4000 GOP_BUFFER_SIZE = 0x100 LIP_BUFFER_SIZE = 0x100 FILE_BUFFER_SIZE = 0x1000 MAX_FILE_SIZE = 0x10000000 CODE_32_SELECTOR = 8 DATA_32_SELECTOR = 16 ; 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 stdcall uses ebx esi edi, _root, _name, _buffer, _size, _fatal mov eax, [_root] ccall [eax+EFI_FILE_PROTOCOL.Open], eax, file_handle, [_name], \ EFI_FILE_MODE_READ, 0 test eax, eax jz @f xor eax, eax cmp [_fatal], 1 jnz .done mov ebx, [efi_table] mov ebx, [ebx+EFI_SYSTEM_TABLE.ConOut] ccall [ebx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], ebx, \ msg_error_open_file ccall [ebx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], ebx, \ [_name] jmp $ @@: mov eax, [file_handle] lea ecx, [_size] ccall [eax+EFI_FILE_PROTOCOL.Read], eax, ecx, [_buffer] mov eax, [file_handle] ccall [eax+EFI_FILE_PROTOCOL.Close], eax mov eax, [_size] .done: ret endp proc skip_whitespace .next_char: cmp byte[esi], 0 jz .done cmp byte[esi], 0x20 ; ' ' jz .whitespace cmp byte[esi], 9 ; '\t' jz .whitespace jmp .done .whitespace: inc esi jmp .next_char .done: ret endp proc skip_until_newline .next_char: cmp byte[esi], 0 jz .done cmp byte[esi], 0xd ; '\r' jz .done cmp byte[esi], 0xa ; '\n' jz .done inc esi jmp .next_char .done: ret endp proc skip_newline .next_char: cmp byte[esi], 0xd ; '\r' jz .newline cmp byte[esi], 0xa ; '\n' jz .newline jmp .done .newline: inc esi jmp .next_char .done: ret endp proc skip_line call skip_until_newline call skip_newline ret endp proc dec2bin xor edx, edx .next_char: movzx eax, byte[esi] test eax, eax jz .done sub eax, '0' jb .done cmp eax, 9 ja .done inc esi imul edx, 10 add edx, eax jmp .next_char .done: mov eax, edx ret endp proc parse_option mov ebx, config_options-3*4 .try_next_option: add ebx, 3*4 mov edi, esi mov edx, [ebx] ; option name test edx, edx jz .done .next_char: cmp byte[edx], 0 jnz @f cmp byte[edi], '=' jz .opt_name_ok @@: cmp byte[edi], 0 jz .done movzx eax, byte[edi] cmp [edx], al jnz .try_next_option inc edi inc edx jmp .next_char .opt_name_ok: inc edi mov esi, edi call dword[ebx+4] .done: ret endp proc parse_line .next_line: cmp byte[esi], 0 jz .done cmp byte[esi], 0xd ; '\r' jz .skip cmp byte[esi], 0xa ; '\n' jz .skip cmp byte[esi], '#' jz .skip call parse_option call skip_line jmp .next_line .skip: call skip_line jmp .next_line .done: ret endp proc cfg_opt_func_resolution call dec2bin xor edx, edx mov [edx+BOOT_LO.x_res], ax cmp byte[esi], 'x' jz @f cmp byte[esi], '*' jz @f jmp .done @@: inc esi call dec2bin xor edx, edx mov [edx+BOOT_LO.y_res], ax mov [cfg_opt_used_resolution], 1 .done: ret endp proc cfg_opt_func_acpi call dec2bin mov [cfg_opt_used_acpi], 1 mov [cfg_opt_value_acpi], al ret endp proc cfg_opt_func_debug_print call dec2bin mov [cfg_opt_used_debug_print], 1 mov [cfg_opt_value_debug_print], al ret endp proc cfg_opt_func_launcher_start call dec2bin mov [cfg_opt_used_launcher_start], 1 mov [cfg_opt_value_launcher_start], al ret endp proc cfg_opt_func_mtrr call dec2bin mov [cfg_opt_used_mtrr], 1 mov [cfg_opt_value_mtrr], al ret endp proc cfg_opt_func_ask_params call dec2bin mov [cfg_opt_used_ask_params], 1 mov [cfg_opt_value_ask_params], al ret endp proc cfg_opt_func_imgfrom call dec2bin mov [cfg_opt_used_imgfrom], 1 mov [cfg_opt_value_imgfrom], al ret endp proc cfg_opt_func_syspath mov edi, cfg_opt_value_syspath .next_char: movzx eax, byte[esi] cmp al, 0xd ; \r jz .done cmp al, 0xa ; \n jz .done inc esi stosb jmp .next_char .done: mov byte[edi], 0 ret endp proc parse_config stdcall uses ebx esi edi, _buffer ; mov esi, [_buffer] mov esi, KERNEL_BASE .next_line: call parse_line cmp byte[esi], 0 jnz .next_line ret endp proc read_options_from_config stdcall uses ebx esi edi mov ebx, [efi_table] mov ebx, [ebx+EFI_SYSTEM_TABLE.BootServices] ccall [ebx+EFI_BOOT_SERVICES.HandleProtocol], [efi_handle], \ lipuuid, lip_interface test eax, eax jnz .error mov eax, [lip_interface] mov ebx, [efi_table] mov ebx, [ebx+EFI_SYSTEM_TABLE.BootServices] ccall [ebx+EFI_BOOT_SERVICES.HandleProtocol], \ [eax+EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle], sfspguid, \ sfsp_interface test eax, eax jnz .error mov eax, [sfsp_interface] ccall [eax+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume], eax, esp_root test eax, eax jnz .error stdcall load_file, [esp_root], file_name, KERNEL_BASE, \ FILE_BUFFER_SIZE, 0 test eax, eax jz @f stdcall parse_config, KERNEL_BASE @@: .error: ret endp proc print_vmode uses eax ebx ecx esi edi, _gop_if mov ebx, [_gop_if] call clearbuf mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] mov edi, msg call num2dec mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] mov edi, msg+8*2 call num2dec mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat] mov edi, msg+16*2 call num2dec mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine] mov edi, msg+24*2 call num2dec mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg ret endp proc find_vmode_index_by_resolution uses ebx esi edi mov [cfg_opt_value_vmode], 0 .next_mode: ; mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ; ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ ; msg_query_vmode movzx ecx, [cfg_opt_value_vmode] mov eax, [gop_interface] ccall [eax+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], eax, ecx, \ gop_info_size, gop_info test eax, eax jz @f call clearbuf mov edi, msg call num2hex mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg jmp .skip_mode @@: mov ecx, [gop_info] stdcall print_vmode, ecx ; PixelBlueGreenRedReserved8BitPerColor cmp [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat], 1 jnz .skip_mode xor edx, edx mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] cmp ax, [edx+BOOT_LO.x_res] jnz .skip_mode mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] cmp ax, [edx+BOOT_LO.y_res] jnz .skip_mode jmp .done .skip_mode: inc [cfg_opt_value_vmode] movzx eax, [cfg_opt_value_vmode] mov ecx, [gop_interface] mov edx, [ecx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode] cmp eax, [edx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode] jnz .next_mode mov [cfg_opt_used_resolution], 0 mov [cfg_opt_value_ask_params], 1 mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_error_no_such_vmode mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg_error jmp $ .error: .done: mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_vmode_found ret endp proc ask_for_params mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_ask_for_params jmp $ .error: .done: ret endp main: mov esi, [esp+4] mov [efi_handle], esi mov esi, [esp+8] mov [efi_table], esi mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset], eax, 1 mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_u4k_loaded mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_read_options call read_options_from_config mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_load_kernel stdcall load_file, [esp_root], kernel_name, KERNEL_BASE, MAX_FILE_SIZE, 1 mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_load_ramdisk stdcall load_file, [esp_root], ramdisk_name, RAMDISK_BASE, MAX_FILE_SIZE, 1 mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_alloc_devicesdat mov eax, [esi+EFI_SYSTEM_TABLE.BootServices] ccall [eax+EFI_BOOT_SERVICES.AllocatePages], \ EFI_ALLOCATE_MAX_ADDRESS, EFI_RESERVED_MEMORY_TYPE, 1, \ devicesdat_data call halt_on_error mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_load_devicesdat ccall load_file, [esp_root], devicesdat_name, [devicesdat_data], \ [devicesdat_size], 0 mov [devicesdat_size], eax mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_locate_gop_handlers mov eax, [esi+EFI_SYSTEM_TABLE.BootServices] ccall [eax+EFI_BOOT_SERVICES.LocateHandle], \ EFI_LOCATE_SEARCH_TYPE.ByProtocol, gopuuid, 0, \ gop_buffer_size, gop_buffer mov [status], eax mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_gop_buffer_size call clearbuf mov eax, [gop_buffer_size] mov edi, msg call num2hex mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg mov eax, [status] call halt_on_error mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_look_for_gop_handler mov ebx, gop_buffer .next_gop_handle: mov eax, ebx sub eax, gop_buffer cmp eax, [gop_buffer_size] jb @f mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_error_out_of_handlers mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg_error jmp $ @@: mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_query_handler mov eax, [esi+EFI_SYSTEM_TABLE.BootServices] ccall [eax+EFI_BOOT_SERVICES.HandleProtocol], \ [ebx], gopuuid, gop_interface ;mov eax, 0x80000003 test eax, eax jz @f call clearbuf mov edi, msg call num2hex mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg add ebx, 4 jmp .next_gop_handle @@: call find_rsdp mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_acpi_tables_done cmp [cfg_opt_used_resolution], 0 jz .not_used_resolution mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_opt_resolution call clearbuf xor edx, edx movzx eax, [edx+BOOT_LO.x_res] mov edi, msg call num2dec xor edx, edx movzx eax, [edx+BOOT_LO.y_res] mov edi, msg+8*2 call num2dec mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg call 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 [edx+BOOT_LO.debug_print], al .not_used_debug_print: cmp [cfg_opt_value_ask_params], 0 jz @f call ask_for_params @@: movzx ecx, [cfg_opt_value_vmode] mov eax, [gop_interface] ccall [eax+EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode], eax, ecx call halt_on_error mov ecx, [gop_interface] mov edx, [ecx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode] mov edi, [edx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.FrameBufferBase.lo] mov [fb_base], edi mov ebx, [edx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.Mode] mov eax, [gop_interface] ccall [eax+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], eax, ebx, \ gop_info_size, gop_info test eax, eax jnz .error mov ecx, [gop_info] mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution] xor edx, edx mov [edx+BOOT_LO.x_res], ax mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution] mov [edx+BOOT_LO.y_res], ax mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine] shl eax, 2 mov [edx+BOOT_LO.pitch], ax mov [edx+BOOT_LO.pci_data.access_mechanism], 1 movzx eax, [pci_last_bus] mov [edx+BOOT_LO.pci_data.last_bus], al mov [edx+BOOT_LO.pci_data.version], 0x0300 ; PCI 3.0 mov [edx+BOOT_LO.pci_data.pm_entry], 0 ; kernel ; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \ ; 450000/0x1000, EFI_ALLOCATE_ADDRESS ; ramdisk ; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \ ; 2880*512/0x1000, EFI_ALLOCATE_ADDRESS call calc_memmap ; call dump_memmap mov eax, [efi_table] mov eax, [eax+EFI_SYSTEM_TABLE.BootServices] ccall [eax+EFI_BOOT_SERVICES.ExitBootServices], [efi_handle], \ [memory_map_key] call halt_on_error cli xor edx, edx xor esi, esi mov [esi+BOOT_LO.bpp], 32 mov [esi+BOOT_LO.vesa_mode], dx mov [esi+BOOT_LO.bank_switch], edx mov edi, [fb_base] mov [esi+BOOT_LO.lfb], edi movzx eax, [cfg_opt_value_mtrr] mov [esi+BOOT_LO.mtrr], al movzx eax, [cfg_opt_value_launcher_start] mov [esi+BOOT_LO.launcher_start], al movzx eax, [cfg_opt_value_debug_print] mov [esi+BOOT_LO.debug_print], al mov [esi+BOOT_LO.dma], dl ; mov qword[esi+BOOT_LO.pci_data], 0 mov [esi+BOOT_LO.apm_entry], edx mov [esi+BOOT_LO.apm_version], dx mov [esi+BOOT_LO.apm_flags], dx mov [esi+BOOT_LO.apm_code_32], dx mov [esi+BOOT_LO.apm_code_16], dx mov [esi+BOOT_LO.apm_data_16], dx mov [esi+BOOT_LO.bios_hd_cnt], dl movzx eax, [cfg_opt_value_imgfrom] mov [esi+BOOT_LO.rd_load_from], al mov eax, dword[devicesdat_size] mov [edx+BOOT_LO.devicesdat_size], eax mov eax, dword[devicesdat_data] mov [edx+BOOT_LO.devicesdat_data], eax mov esi, cfg_opt_value_syspath mov edi, BOOT_LO.syspath mov ecx, 0x17 rep movsb lgdt [cs:GDTR] mov ax, DATA_32_SELECTOR mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax push CODE_32_SELECTOR lea eax, [.next] push eax retf .next: mov eax, cr0 and eax, not CR0_PG mov cr0, eax mov eax, cr4 and eax, not CR4_PAE mov cr4, eax mov eax, KERNEL_BASE ; add the 32-bit entry point add eax, [eax+kernel_header.b32_offset] push eax retn .error: mov esi, [efi_table] mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_error jmp $ halt_on_error: test eax, eax jz @f call clearbuf mov edi, msg call num2hex mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_error mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg jmp $ @@: ret proc find_rsdp mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_look_for_rsdp mov edi, [esi+EFI_SYSTEM_TABLE.ConfigurationTable] mov ecx, [esi+EFI_SYSTEM_TABLE.NumberOfTableEntries] .next_table: dec ecx js .all_tables_done ; EFI_ACPI_TABLE_GUID cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0x0], 0x8868e871 jnz .not_acpi20 cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0x4], 0x11d3e4f1 jnz .not_acpi20 cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0x8], 0x800022bc jnz .not_acpi20 cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0xc], 0x81883cc7 jnz .not_acpi20 mov eax, [edi+EFI_CONFIGURATION_TABLE.VendorTable] mov edx, BOOT_LO.acpi_rsdp mov [edx], eax mov eax, [esi+EFI_SYSTEM_TABLE.ConOut] ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \ msg_rsdp_found jmp .all_tables_done .not_acpi20: add edi, sizeof.EFI_CONFIGURATION_TABLE jmp .next_table .all_tables_done: ret endp proc calc_memmap mov eax, [esi+EFI_SYSTEM_TABLE.BootServices] ccall [eax+EFI_BOOT_SERVICES.AllocatePages], EFI_ALLOCATE_ANY_PAGES, \ EFI_RESERVED_MEMORY_TYPE, MEMORY_MAP_SIZE/0x1000, memory_map call halt_on_error mov eax, [esi+EFI_SYSTEM_TABLE.BootServices] ccall [eax+EFI_BOOT_SERVICES.GetMemoryMap], memory_map_size, \ [memory_map], memory_map_key, descriptor_size, descriptor_ver call halt_on_error push esi mov edi, BOOT_LO.memmap_blocks mov dword[edi-4], 0 ; memmap_block_cnt mov esi, [memory_map] mov ebx, esi add ebx, [memory_map_size] .next_descr: call add_uefi_memmap add esi, [descriptor_size] cmp esi, ebx jb .next_descr pop esi ret endp ; linux/arch/x86/platform/efi/efi.c ; do_add_efi_memmap proc add_uefi_memmap cmp [BOOT_LO.memmap_block_cnt], MAX_MEMMAP_BLOCKS jz .done mov eax, [esi+EFI_MEMORY_DESCRIPTOR.PhysicalStart.lo] mov edx, [esi+EFI_MEMORY_DESCRIPTOR.PhysicalStart.hi] mov [edi+e820entry.addr.lo], eax mov [edi+e820entry.addr.hi], edx mov eax, [esi+EFI_MEMORY_DESCRIPTOR.NumberOfPages.lo] mov edx, [esi+EFI_MEMORY_DESCRIPTOR.NumberOfPages.hi] shld edx, eax, 12 shl eax, 12 mov [edi+e820entry.size.lo], eax mov [edi+e820entry.size.hi], edx mov ecx, [esi+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 [esi+EFI_MEMORY_DESCRIPTOR.Attribute.lo], EFI_MEMORY_WB mov eax, E820_RAM jnz .type_done .reserved: mov eax, E820_RESERVED .type_done: mov [edi+e820entry.type], eax cmp eax, E820_RAM jnz @f inc [BOOT_LO.memmap_block_cnt] add edi, sizeof.e820entry @@: .done: ret endp proc num2dec pushad xor ecx, ecx mov ebx, 10 .next_digit: xor edx, edx div ebx push edx inc ecx test eax, eax jnz .next_digit .next_char: pop eax add eax, '0' stosw loop .next_char popad ret endp proc num2hex pushad xchg edx, eax mov ecx, 8 .next_tetra: rol edx, 4 movzx eax, dl and eax, 0x0f movzx eax, byte[hex+eax] stosw loop .next_tetra popad ret endp hex db '0123456789ABCDEF' proc clearbuf pushad mov eax, 0x0020 mov ecx, 79 mov edi, msg rep stosw popad ret endp section '.rodata' data readable align 16 GDTR: dw 3*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 gopuuid db EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID lipuuid db EFI_LOADED_IMAGE_PROTOCOL_GUID sfspguid db EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID pcirbguid 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 dd 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 "uefi32kos loaded",13,10,0 msg_read_options du "Read options from 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_handlers du "Locate GOP handlers",13,10,0 msg_look_for_gop_handler du "Look for GOP 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_gop_buffer_size du "GOP buffer size",13,10,0 msg_opt_resolution du "option resolution: ",0 msg_error du "Error!",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 du 79 dup " ",13,10,0 section '.data' data readable writeable efi_handle dd 0 efi_table dd 0 fb_base dd 0 gop_buffer_size dd GOP_BUFFER_SIZE gop_handle dd 0 gop_interface dd 0 gop_info_size dd 0 gop_info dd 0 lip_buffer_size dd LIP_BUFFER_SIZE lip_handle dd 0 lip_interface dd 0 sfsp_interface dd 0 pci_last_bus db 254 esp_root dd ? file_handle dd ? file_buffer_size dd FILE_BUFFER_SIZE-1 ; leave the last byte for \0 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 dd 0 descriptor_size dd 0 descriptor_ver dd 0 memory_map_size dd MEMORY_MAP_SIZE efi_fs_info_id db EFI_FILE_SYSTEM_INFO_ID efi_fs_info_size dq sizeof.EFI_FILE_SYSTEM_INFO efi_fs_info EFI_FILE_SYSTEM_INFO memory_map dd ? gop_buffer rd GOP_BUFFER_SIZE/4 devicesdat_data dd 0xffffffff devicesdat_size dd 0x1000 status dd ? section '.reloc' fixups data discardable