jump to physical address of kernel works, kernel prints HI to COM1

This commit is contained in:
rgimad
2025-02-27 11:19:19 +03:00
parent 0c16a5f65a
commit e15e608062
4 changed files with 76 additions and 23 deletions

View File

@@ -16,7 +16,7 @@ rd /s /q image
mkdir image\EFI\BOOT
copy kernel\boot\bootx64.efi image\EFI\BOOT\BOOTX64.EFI
copy kernel\kernel64.bin image\EFI\KERNEL64.BIN
qemu-system-x86_64 -cpu qemu64 -bios OVMF.fd -drive driver=vvfat,rw=on,dir=image\
qemu-system-x86_64 -cpu qemu64 -bios OVMF.fd -drive driver=vvfat,rw=on,dir=image\ -serial stdio
goto :eof
:error

View File

@@ -23,8 +23,6 @@ include 'uefi64.inc'
MEMORY_MAP_SIZE = 0x10000 ; NOTE: can be bigger?
VIRT_KERNEL_BASE = 0xFFFFFFFF80000000
; linux/arch/x86/include/uapi/asm/e820.h
E820_RAM = 1
E820_RESERVED = 2
@@ -396,8 +394,19 @@ proc main _efi_handle, _efi_table
cmp rcx, [kernel_image_phys_end]
jb .fill_p1
; causes fault and reboots. maybe i need exitbootservices first? maybe paging structures incorrect
; mov rax, table_p4
; mov cr3, rax
; TODO ExitBootServices here
mov rax, [kernel_image_phys_base]
mov rax, [rax + KERNEL64_HEADER.entry_point_offset]
add rax, [kernel_image_phys_base] ; jump to phys kernel for now
; add rax, VIRT_KERNEL_BASE
jmp rax
; TODO
;; put phys start / end into kernel header
;; map [kernel_phys_start; kernel_phys_end) to 0xFFFFFFFF80000000
;; (~~fill paging tables~~, ExitBootServices and switch to the new PML4), set kernel rsp, jmp to k64_entry
;; NOTE: dont allocate after getting memmap bc uefi allocations change the memmap. => perform GetMemoryMap last of all..

View File

@@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2025-2025. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License v2 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
VIRT_KERNEL_BASE = 0xFFFFFFFF80000000
struct DQ
union
lo dd ?

View File

@@ -7,39 +7,73 @@
use64
VIRT_KERNEL_BASE = 0xFFFFFFFF80000000
DEFAULT_STACK_SIZE = 8192
include 'struct.inc'
include 'proc64.inc'
include 'const.inc'
org VIRT_KERNEL_BASE
DEFAULT_STACK_SIZE = 4096*2
dq 'KERNEL64' ; magic
dq k64_entry - VIRT_KERNEL_BASE ; entry point's offset from base where it loaded
dq DEFAULT_STACK_SIZE ; how many bytes of stack we need
kernel_phys_start dq 0 ; bootloader will put here phys addr where it loaded kernel
kernel_phys_end dq 0 ; and phys end addr (including stack ofc)
PORT_COM1 = 0x3f8
macro outb port_, byte_ {
mov dx, port_
mov al, byte_
out dx, al
}
macro inb port_ {
mov dx, port_
in al, dx
}
; rcx - byte to write
; uses rdx
write_com1:
@@:
inb PORT_COM1 + 5
and al, 0x20
test al, al
jz @b
outb PORT_COM1, cl
ret
; 64 bit kernel entry point
k64_entry:
;; NOTE! oops addresses are incorrect
pop qword [qword puthex_ptr - VIRT_KERNEL_BASE]
pop qword [qword putstr_ptr - VIRT_KERNEL_BASE]
; init com port:
outb PORT_COM1 + 1, 0x00
outb PORT_COM1 + 3, 0x80
outb PORT_COM1 + 0, 0x03
outb PORT_COM1 + 1, 0x00
outb PORT_COM1 + 3, 0x03
outb PORT_COM1 + 2, 0xC7
outb PORT_COM1 + 4, 0x0B
outb PORT_COM1 + 4, 0x1E
outb PORT_COM1 + 0, 0xAE
; check if serial is faulty (i.e: not same byte as sent)
inb PORT_COM1 + 0
cmp al, 0xAE
jnz .abyss
; set port in normal operation mode
; (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
outb PORT_COM1 + 4, 0x0F
sub rsp, 0x20
mov rcx, kmsg_hello - VIRT_KERNEL_BASE
call qword [qword putstr_ptr - VIRT_KERNEL_BASE]
add rsp, 0x20
sub rsp, 0x20
mov rcx, kmsg_ripis - VIRT_KERNEL_BASE
call qword [qword putstr_ptr - VIRT_KERNEL_BASE]
add rsp, 0x20
sub rsp, 0x20
lea rcx, [rip]
call qword [qword puthex_ptr - VIRT_KERNEL_BASE]
add rsp, 0x20
;; try write some chars
mov rcx, 'H'
call write_com1
mov rcx, 'I'
call write_com1
jmp $
.abyss:
kmsg_hello db 'Hello from KERNEL',13,10,0