mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-27 15:04:33 +00:00
153 lines
2.6 KiB
NASM
153 lines
2.6 KiB
NASM
; https://wiki.osdev.org/Creating_a_64-bit_kernel
|
|
; https://wiki.osdev.org/Entering_Long_Mode_Directly
|
|
|
|
KERNEL_VIRTUAL_BASE equ 0xFFFFFFFF80000000 ; 512GB
|
|
KERNEL_LMA equ 0x1000000 ; 16MB
|
|
KERNEL_STACK_SIZE equ 0x4000 ; 16KB
|
|
|
|
extern Multiboot2Entry
|
|
extern BootPageTable
|
|
extern UpdatePageTable
|
|
extern UpdatePageTable64
|
|
extern DetectCPUID
|
|
extern Detect64Bit
|
|
extern LoadGDT32
|
|
global MB2_start
|
|
extern MB2_start_c
|
|
|
|
[bits 32]
|
|
|
|
section .bootstrap.data
|
|
global MB2_HeaderMagic
|
|
MB2_HeaderMagic:
|
|
times (0x64) dq 0
|
|
|
|
global MB2_HeaderInfo
|
|
MB2_HeaderInfo:
|
|
times (0x64) dq 0
|
|
|
|
section .bootstrap.text
|
|
MB2_start:
|
|
cli
|
|
mov word [0xb8F00], 0x072E ; .
|
|
mov [MB2_HeaderMagic], eax
|
|
mov [MB2_HeaderInfo], ebx
|
|
|
|
; We need to check if the CPU supports 64-bit mode
|
|
call DetectCPUID
|
|
call Detect64Bit
|
|
|
|
mov word [0xb8F02], 0x072E ; .
|
|
|
|
mov ecx, cr0
|
|
and ecx, 0x7fffffff ; Clear PG
|
|
mov cr0, ecx
|
|
|
|
mov ecx, cr4
|
|
or ecx, 0x10 ; Set PSE
|
|
or ecx, 0x20 ; Set PAE
|
|
mov cr4, ecx
|
|
|
|
; Load the GDT and update the page table
|
|
call LoadGDT32
|
|
call UpdatePageTable
|
|
|
|
; Load the new page table
|
|
mov edi, BootPageTable
|
|
mov cr3, edi
|
|
|
|
mov word [0xb8F04], 0x072E ; .
|
|
|
|
; Enable long mode
|
|
mov ecx, 0xC0000080 ; EFER
|
|
rdmsr
|
|
or eax, 0x800 | 0x100 | 0x1 ; Set LME, LMA, SCE
|
|
wrmsr
|
|
|
|
mov ecx, cr0
|
|
or ecx, (0x80000000 | 0x1) ; Set PG and PE
|
|
mov cr0, ecx
|
|
|
|
|
|
lgdt [GDT64.Ptr]
|
|
; xor eax, eax
|
|
; sgdt [eax]
|
|
; test eax, eax
|
|
; jz .InvalidGDT
|
|
|
|
; .InvalidGDT:
|
|
; mov word [0xb8F07], 0x4 ; Red
|
|
; hlt
|
|
|
|
jmp GDT64.code:HigherHalfStart
|
|
|
|
[bits 64]
|
|
HigherHalfStart:
|
|
cli
|
|
mov word [0xb8F06], 0x072E ; .
|
|
call UpdatePageTable64
|
|
|
|
; Load the new page table
|
|
mov rdi, BootPageTable
|
|
mov cr3, rdi
|
|
|
|
mov ax, GDT64.data
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov fs, ax
|
|
mov gs, ax
|
|
mov ss, ax
|
|
|
|
mov word [0xb8F08], 0x072E ; .
|
|
mov rsp, (KernelStack + KERNEL_STACK_SIZE)
|
|
mov rbp, (KernelStack + KERNEL_STACK_SIZE)
|
|
|
|
cld
|
|
cli
|
|
|
|
call Multiboot2Entry
|
|
.Loop:
|
|
hlt
|
|
jmp .Loop
|
|
|
|
section .bootstrap.bss
|
|
align 16
|
|
KernelStack:
|
|
resb KERNEL_STACK_SIZE
|
|
|
|
; Access bits
|
|
PRESENT equ 1 << 7
|
|
NOT_SYS equ 1 << 4
|
|
EXEC equ 1 << 3
|
|
DC equ 1 << 2
|
|
RW equ 1 << 1
|
|
ACCESSED equ 1 << 0
|
|
|
|
; Flags bits
|
|
GRAN_4K equ 1 << 7
|
|
SZ_32 equ 1 << 6
|
|
LONG_MODE equ 1 << 5
|
|
|
|
section .bootstrap.data
|
|
GDT64:
|
|
.null: equ $ - GDT64
|
|
dq 0
|
|
.code: equ $ - GDT64
|
|
dd 0xFFFF
|
|
db 0
|
|
db PRESENT | NOT_SYS | EXEC | RW
|
|
db GRAN_4K | LONG_MODE | 0xF
|
|
db 0
|
|
.data: equ $ - GDT64
|
|
dd 0xFFFF
|
|
db 0
|
|
db PRESENT | NOT_SYS | RW
|
|
db GRAN_4K | SZ_32 | 0xF
|
|
db 0
|
|
.tss: equ $ - GDT64
|
|
dd 0x00000068
|
|
dd 0x00CF8900
|
|
.Ptr:
|
|
dw $ - GDT64 - 1
|
|
dq GDT64
|