1250 lines
38 KiB
NASM
1250 lines
38 KiB
NASM
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;; ;;
|
||
|
;; Copyright (C) KolibriOS team 2020. All rights reserved. ;;
|
||
|
;; Distributed under terms of the GNU General Public License ;;
|
||
|
;; Version 2, or (at your option) any later version. ;;
|
||
|
;; ;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
|
||
|
format pe64 efi
|
||
|
entry main
|
||
|
|
||
|
section '.text' code executable readable
|
||
|
|
||
|
include '../../struct.inc'
|
||
|
include '../../macros.inc'
|
||
|
include '../../const.inc'
|
||
|
|
||
|
purge DQ
|
||
|
include 'uefi64.inc'
|
||
|
|
||
|
MEMORY_MAP_SIZE = 0x10000
|
||
|
GOP_BUFFER_SIZE = 0x100
|
||
|
LIP_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
|
||
|
|
||
|
load_file:
|
||
|
virtual at rsp+8
|
||
|
.root dq ?
|
||
|
.name dq ?
|
||
|
.buffer dq ?
|
||
|
.size dq ?
|
||
|
.fatal dq ?
|
||
|
end virtual
|
||
|
eficall [.root], EFI_FILE_PROTOCOL.Open, [.root], file_handle, \
|
||
|
[.name], EFI_FILE_MODE_READ, 0
|
||
|
test eax, eax
|
||
|
jz @f
|
||
|
xor eax, eax
|
||
|
cmp [.fatal], 1
|
||
|
jnz .done
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_error_open_file
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
[.name]
|
||
|
jmp $
|
||
|
@@:
|
||
|
|
||
|
lea rax, [.size]
|
||
|
eficall [file_handle], EFI_FILE_PROTOCOL.Read, [file_handle], rax, \
|
||
|
[.buffer]
|
||
|
eficall [file_handle], EFI_FILE_PROTOCOL.Close, [file_handle]
|
||
|
mov rax, [.size]
|
||
|
.done:
|
||
|
push rax
|
||
|
call clearbuf
|
||
|
mov rdi, msg
|
||
|
call num2dec
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_file_size
|
||
|
pop rbx
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
|
||
|
pop rbx
|
||
|
pop rax
|
||
|
ret 8*5
|
||
|
|
||
|
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
|
||
|
|
||
|
parse_config:
|
||
|
virtual at rsp+8
|
||
|
.buffer dq ?
|
||
|
end virtual
|
||
|
; mov rsi, [.buffer]
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_parsing_config
|
||
|
pop rbx
|
||
|
mov rsi, KERNEL_BASE
|
||
|
.next_line:
|
||
|
call parse_line
|
||
|
cmp byte[rsi], 0
|
||
|
jnz .next_line
|
||
|
ret 1*8
|
||
|
|
||
|
read_options_from_config:
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
|
||
|
eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, [efi_handle], lipuuid, \
|
||
|
lip_interface
|
||
|
test eax, eax
|
||
|
jz @f
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_error_efi_lip_handle
|
||
|
pop rbx
|
||
|
jmp $
|
||
|
@@:
|
||
|
mov rax, [lip_interface]
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
|
||
|
eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, \
|
||
|
[rax+EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle], sfspguid, \
|
||
|
sfsp_interface
|
||
|
test eax, eax
|
||
|
jz @f
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_error_lip_dev_sfsp
|
||
|
pop rbx
|
||
|
jmp $
|
||
|
@@:
|
||
|
eficall [sfsp_interface], EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume, \
|
||
|
[sfsp_interface], esp_root
|
||
|
test eax, eax
|
||
|
jz @f
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_error_sfsp_openvolume
|
||
|
pop rbx
|
||
|
jmp $
|
||
|
@@:
|
||
|
push 0 ; not fatal, i.e. it's ok to not find this file
|
||
|
push FILE_BUFFER_SIZE
|
||
|
push KERNEL_BASE
|
||
|
; push file_name
|
||
|
mov rax, file_name
|
||
|
push rax
|
||
|
push [esp_root]
|
||
|
call load_file
|
||
|
|
||
|
test eax, eax
|
||
|
jz @f
|
||
|
push KERNEL_BASE
|
||
|
call parse_config
|
||
|
@@:
|
||
|
|
||
|
.error:
|
||
|
ret
|
||
|
|
||
|
print_vmode:
|
||
|
push rax rbx rcx rdx rsi rdi
|
||
|
mov rbx, rcx
|
||
|
call clearbuf
|
||
|
mov eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
|
||
|
mov rdi, msg
|
||
|
call num2dec
|
||
|
mov eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
|
||
|
mov rdi, msg+8*2
|
||
|
call num2dec
|
||
|
|
||
|
mov eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat]
|
||
|
mov rdi, msg+16*2
|
||
|
call num2dec
|
||
|
|
||
|
mov eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine]
|
||
|
mov rdi, msg+24*2
|
||
|
call num2dec
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
|
||
|
pop rdi rsi rdx rcx rbx rax
|
||
|
ret
|
||
|
|
||
|
find_vmode_index_by_resolution:
|
||
|
mov [cfg_opt_used_resolution], 1
|
||
|
mov [cfg_opt_value_vmode], 0
|
||
|
.next_mode:
|
||
|
movzx eax, [cfg_opt_value_vmode]
|
||
|
eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode, \
|
||
|
[gop_interface], rax, gop_info_size, gop_info
|
||
|
cmp rax, EFI_SUCCESS
|
||
|
jnz .error
|
||
|
mov rcx, [gop_info]
|
||
|
call 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 rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_error_no_such_vmode
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_error
|
||
|
jmp $
|
||
|
.error:
|
||
|
.done:
|
||
|
ret
|
||
|
|
||
|
ask_for_params:
|
||
|
ret
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
|
||
|
eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, [rax], gopuuid, \
|
||
|
msg_ask_for_params
|
||
|
jmp $
|
||
|
|
||
|
xor ebx, ebx
|
||
|
.next_mode:
|
||
|
call clearbuf
|
||
|
mov eax, ebx
|
||
|
lea rdi, [msg]
|
||
|
call num2dec
|
||
|
|
||
|
push rbx
|
||
|
eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode, \
|
||
|
[gop_interface], rbx, gop_info_size, gop_info
|
||
|
cmp rax, EFI_SUCCESS
|
||
|
jnz .error
|
||
|
mov rcx, [gop_info]
|
||
|
; PixelBlueGreenRedReserved8BitPerColor
|
||
|
cmp [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat], 1
|
||
|
jnz .skip
|
||
|
mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
|
||
|
lea rdi, [msg+4*2]
|
||
|
call num2dec
|
||
|
mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
|
||
|
lea rdi, [msg+9*2]
|
||
|
call num2dec
|
||
|
; mov eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine]
|
||
|
; lea rdi, [msg+14*2]
|
||
|
; call num2dec
|
||
|
.skip:
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
|
||
|
cmp rax, EFI_SUCCESS
|
||
|
jnz .error
|
||
|
|
||
|
pop rbx
|
||
|
inc rbx
|
||
|
mov rcx, [gop_interface]
|
||
|
mov rdx, [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode]
|
||
|
cmp ebx, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode]
|
||
|
jnz .next_mode
|
||
|
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConIn]
|
||
|
eficall rbx, SIMPLE_INPUT_INTERFACE.Reset, rbx, 1
|
||
|
cmp rax, EFI_SUCCESS
|
||
|
jnz .error
|
||
|
xor ecx, ecx
|
||
|
@@:
|
||
|
push rcx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConIn]
|
||
|
eficall rbx, SIMPLE_INPUT_INTERFACE.ReadKeyStroke, rbx, msg
|
||
|
pop rcx
|
||
|
mov rdx, EFI_DEVICE_ERROR
|
||
|
cmp rax, rdx
|
||
|
jz .error
|
||
|
mov rdx, EFI_NOT_READY
|
||
|
cmp rax, rdx
|
||
|
jz @b
|
||
|
; cmp rax, EFI_SUCCESS
|
||
|
movzx eax, word[msg+2]
|
||
|
;jmp .key_done
|
||
|
cmp al, 0x0D
|
||
|
jz .key_done
|
||
|
imul ecx, 10
|
||
|
sub eax, '0'
|
||
|
add ecx, eax
|
||
|
jmp @b
|
||
|
.key_done:
|
||
|
mov [cfg_opt_value_vmode], cl
|
||
|
.error:
|
||
|
.done:
|
||
|
ret
|
||
|
|
||
|
main:
|
||
|
mov [efi_handle], rcx
|
||
|
mov [efi_table], rdx
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset, rbx, 1
|
||
|
test eax, eax
|
||
|
jz @f
|
||
|
jmp $ ; what can I do here?
|
||
|
@@:
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_u4k_loaded
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_read_options
|
||
|
call read_options_from_config
|
||
|
|
||
|
; read kernel file
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_load_kernel
|
||
|
push 1 ; fatal
|
||
|
push MAX_FILE_SIZE
|
||
|
push KERNEL_BASE
|
||
|
; push kernel_name
|
||
|
mov rax, kernel_name
|
||
|
push rax
|
||
|
push [esp_root]
|
||
|
call load_file
|
||
|
|
||
|
; read ramdisk image
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_load_ramdisk
|
||
|
push 1 ; fatal
|
||
|
push MAX_FILE_SIZE
|
||
|
push RAMDISK_BASE
|
||
|
; push ramdisk_name
|
||
|
mov rax, ramdisk_name
|
||
|
push rax
|
||
|
push [esp_root]
|
||
|
call load_file
|
||
|
|
||
|
; alloc buffer for devices.dat
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_alloc_devicesdat
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
|
||
|
eficall rbx, 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 rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_load_devicesdat
|
||
|
|
||
|
push 0 ; not fatal
|
||
|
push [devicesdat_size]
|
||
|
push [devicesdat_data]
|
||
|
; push devicesdat_name
|
||
|
mov rax, devicesdat_name
|
||
|
push rax
|
||
|
push [esp_root]
|
||
|
call load_file
|
||
|
mov [devicesdat_size], rax
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_locate_gop_handlers
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
|
||
|
eficall rbx, EFI_BOOT_SERVICES.LocateHandle, \
|
||
|
EFI_LOCATE_SEARCH_TYPE.ByProtocol, gopuuid, 0, \
|
||
|
gop_buffer_size, gop_buffer
|
||
|
mov [status], rax
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_gop_buffer_size
|
||
|
call clearbuf
|
||
|
mov rax, [gop_buffer_size]
|
||
|
mov rdi, msg
|
||
|
call num2hex
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
|
||
|
|
||
|
mov rax, [status]
|
||
|
test eax, eax
|
||
|
jz @f
|
||
|
call clearbuf
|
||
|
mov rdi, msg
|
||
|
call num2hex
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_error
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
|
||
|
jmp $
|
||
|
@@:
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_look_for_gop_handler
|
||
|
|
||
|
mov rbx, gop_buffer
|
||
|
.next_gop_handle:
|
||
|
mov rax, rbx
|
||
|
mov rcx, gop_buffer
|
||
|
sub rax, rcx
|
||
|
cmp rax, [gop_buffer_size]
|
||
|
jb @f
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_error_out_of_handlers
|
||
|
pop rbx
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg_error
|
||
|
pop rbx
|
||
|
jmp $
|
||
|
@@:
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_query_handler
|
||
|
pop rbx
|
||
|
|
||
|
mov rax, rbx
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
|
||
|
eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, [rax], gopuuid, \
|
||
|
gop_interface
|
||
|
pop rbx
|
||
|
;mov rax, 0x8000_0000_0000_0003
|
||
|
test eax, eax
|
||
|
jz @f
|
||
|
call clearbuf
|
||
|
mov rdi, msg
|
||
|
call num2hex
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
|
||
|
pop rbx
|
||
|
|
||
|
add rbx, 8
|
||
|
jmp .next_gop_handle
|
||
|
@@:
|
||
|
|
||
|
call find_rsdp
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_acpi_tables_done
|
||
|
|
||
|
cmp [cfg_opt_used_resolution], 0
|
||
|
jz .not_used_resolution
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
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 rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, 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 [rdx+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]
|
||
|
eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode, \
|
||
|
[gop_interface], rcx
|
||
|
test eax, eax
|
||
|
jz @f
|
||
|
call clearbuf
|
||
|
mov rdi, msg
|
||
|
call num2hex
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
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 ebx, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.Mode]
|
||
|
eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode, \
|
||
|
[gop_interface], rbx, 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 byte[rdx+BOOT_LO.pci_data+0], 1 ; PCI access mechanism
|
||
|
mov byte[rdx+BOOT_LO.pci_data+1], 8 ; last bus, don't know how to count them
|
||
|
mov byte[rdx+BOOT_LO.pci_data+2], 0x10 ; PCI version
|
||
|
mov byte[rdx+BOOT_LO.pci_data+3], 0x02
|
||
|
mov dword[rdx+BOOT_LO.pci_data+4], 0xe3
|
||
|
|
||
|
; 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 rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
|
||
|
eficall rbx, 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 rdi, [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 [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 rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_error
|
||
|
jmp $
|
||
|
|
||
|
|
||
|
halt_on_error:
|
||
|
test eax, eax
|
||
|
jz @f
|
||
|
call clearbuf
|
||
|
mov rdi, msg
|
||
|
call num2hex
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_error
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
|
||
|
jmp $
|
||
|
@@:
|
||
|
ret
|
||
|
|
||
|
find_rsdp:
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_look_for_rsdp
|
||
|
pop rbx
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
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
|
||
|
|
||
|
calc_memmap:
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
|
||
|
eficall rbx, EFI_BOOT_SERVICES.AllocatePages, EFI_ALLOCATE_ANY_PAGES, \
|
||
|
EFI_RESERVED_MEMORY_TYPE, MEMORY_MAP_SIZE/0x1000, memory_map
|
||
|
call halt_on_error
|
||
|
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
|
||
|
eficall rbx, 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 rbx, rsi
|
||
|
add rbx, [memory_map_size]
|
||
|
.next_descr:
|
||
|
call add_uefi_memmap
|
||
|
add rsi, [descriptor_size]
|
||
|
cmp rsi, rbx
|
||
|
jb .next_descr
|
||
|
ret
|
||
|
|
||
|
dump_memmap:
|
||
|
xor eax, eax
|
||
|
mov rsi, BOOT_LO.memmap_blocks
|
||
|
mov ebx, [rax+BOOT_LO.memmap_block_cnt]
|
||
|
|
||
|
call clearbuf
|
||
|
mov eax, ebx
|
||
|
mov rdi, msg
|
||
|
call num2dec
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
|
||
|
msg_memmap
|
||
|
pop rbx
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
|
||
|
pop rbx
|
||
|
call clearbuf
|
||
|
.next_mapping:
|
||
|
dec ebx
|
||
|
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
|
||
|
push rbx
|
||
|
mov rbx, [efi_table]
|
||
|
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
|
||
|
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
|
||
|
pop rbx
|
||
|
add rsi, sizeof.e820entry
|
||
|
jmp .next_mapping
|
||
|
.done:
|
||
|
ret
|
||
|
|
||
|
|
||
|
; linux/arch/x86/platform/efi/efi.c
|
||
|
; do_add_efi_memmap
|
||
|
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
|
||
|
|
||
|
|
||
|
num2dec:
|
||
|
push rax rbx rcx rdx rsi 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 rsi rdx rcx rbx rax
|
||
|
ret
|
||
|
|
||
|
|
||
|
num2hex:
|
||
|
push rax rbx rcx rdx rsi rdi
|
||
|
|
||
|
xchg rdx, rax
|
||
|
mov ecx, 16
|
||
|
.next_tetra:
|
||
|
rol rdx, 4
|
||
|
movzx eax, dl
|
||
|
and eax, 0x0f
|
||
|
movzx eax, byte[hex+eax]
|
||
|
stosw
|
||
|
loop .next_tetra
|
||
|
|
||
|
pop rdi rsi rdx rcx rbx rax
|
||
|
ret
|
||
|
|
||
|
hex db '0123456789ABCDEF'
|
||
|
|
||
|
clearbuf:
|
||
|
push rax rbx rcx rdx rsi rdi
|
||
|
mov eax, 0x0020
|
||
|
mov ecx, 79
|
||
|
mov rdi, msg
|
||
|
rep stosw
|
||
|
pop rdi rsi rdx rcx rbx rax
|
||
|
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
|
||
|
gopuuid db EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
|
||
|
lipuuid db EFI_LOADED_IMAGE_PROTOCOL_GUID
|
||
|
sfspguid db EFI_SIMPLE_FILE_SYSTEM_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_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_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_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
|
||
|
|
||
|
|
||
|
section '.data' data readable writeable
|
||
|
efi_handle dq 0
|
||
|
efi_table dq 0
|
||
|
uefi_rsptmp dq 0
|
||
|
|
||
|
fb_base dq 0
|
||
|
|
||
|
gop_buffer_size dq GOP_BUFFER_SIZE
|
||
|
gop_handle dq 0
|
||
|
gop_interface dq 0
|
||
|
gop_info_size dq 0
|
||
|
gop_info dq 0
|
||
|
|
||
|
lip_buffer_size dq LIP_BUFFER_SIZE
|
||
|
lip_handle dq 0
|
||
|
lip_interface dq 0
|
||
|
|
||
|
sfsp_interface dq 0
|
||
|
|
||
|
esp_root dq ?
|
||
|
file_handle dq ?
|
||
|
file_buffer_size dq 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 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
|
||
|
efi_fs_info EFI_FILE_SYSTEM_INFO
|
||
|
|
||
|
memory_map dq ?
|
||
|
gop_buffer rq GOP_BUFFER_SIZE/8
|
||
|
devicesdat_data dq 0xffffffff
|
||
|
devicesdat_size dq 0x1000
|
||
|
status dq ?
|
||
|
|
||
|
section '.reloc' fixups data discardable
|