diff --git a/build.bat b/build.bat index c5dbafc..39c809c 100644 --- a/build.bat +++ b/build.bat @@ -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 diff --git a/kernel/boot/bootx64.asm b/kernel/boot/bootx64.asm index 790c938..bed07e8 100644 --- a/kernel/boot/bootx64.asm +++ b/kernel/boot/bootx64.asm @@ -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.. diff --git a/kernel/const.inc b/kernel/const.inc index de0259d..ba73c1f 100644 --- a/kernel/const.inc +++ b/kernel/const.inc @@ -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 ? diff --git a/kernel/kernel64.asm b/kernel/kernel64.asm index 90d643d..ffb73cc 100644 --- a/kernel/kernel64.asm +++ b/kernel/kernel64.asm @@ -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] - - sub rsp, 0x20 - mov rcx, kmsg_hello - VIRT_KERNEL_BASE - call qword [qword putstr_ptr - VIRT_KERNEL_BASE] - add rsp, 0x20 + ; 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_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