diff --git a/Architecture/amd64/Bootstrap/MB2.asm b/Architecture/amd64/Bootstrap/MB2.asm deleted file mode 100644 index 6b8fd55..0000000 --- a/Architecture/amd64/Bootstrap/MB2.asm +++ /dev/null @@ -1,70 +0,0 @@ -; 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 DetectCPUID -extern Detect64Bit -global MB2_start - -[bits 32] -section .text -MB2_start: - cli - - mov word [0xb8F00], 0x072E ; . - - call DetectCPUID - call Detect64Bit - - mov ecx, cr4 - or ecx, 0x00000010 ; Set PSE in CR4 - mov cr4, ecx - - mov word [0xb8F02], 0x072E ; . - - mov ecx, (BootPageTable - KERNEL_VIRTUAL_BASE) - mov cr3, ecx - - mov ecx, cr0 - or ecx, 0x80000000 ; Set PG in CR0 - mov cr0, ecx - - cli - hlt - - mov word [0xb8F04], 0x072E ; . - - - mov word [0xb8F06], 0x072E ; . - - cli - hlt - - ; lea ecx, [HigherHalfStart] - ; jmp ecx - -[bits 64] -HigherHalfStart: - mov word [0xb8F08], 0x072E ; . - mov dword [BootPageTable], 0 - invlpg [0] - - mov rsp, KernelStack + KERNEL_STACK_SIZE - - push rax ; Multiboot2 Magic - add rbx, KERNEL_VIRTUAL_BASE - push rbx ; Multiboot2 Header - call Multiboot2Entry -Loop: - hlt - jmp Loop - -section .bss -align 16 -KernelStack: - resb KERNEL_STACK_SIZE diff --git a/Architecture/amd64/Bootstrap/MB2PageTable.asm b/Architecture/amd64/Bootstrap/MB2PageTable.asm deleted file mode 100644 index 16c0d86..0000000 --- a/Architecture/amd64/Bootstrap/MB2PageTable.asm +++ /dev/null @@ -1,10 +0,0 @@ -section .data -align 0x1000 -global BootPageTable -BootPageTable: - dq 0x0000000000000083 - dq 0x0000000000000083 - TIMES (512-2) dq 0 - dq 0x0000000000000083 - dq 0x0000000000000083 - TIMES (512-2) dq 0 \ No newline at end of file diff --git a/Architecture/amd64/Bootstrap/MB2Switch.asm b/Architecture/amd64/Bootstrap/MB2Switch.asm deleted file mode 100644 index e69de29..0000000 diff --git a/Architecture/amd64/Bootstrap/MB2Detection.asm b/Architecture/amd64/Bootstrap/Multiboot2/Detection.asm similarity index 95% rename from Architecture/amd64/Bootstrap/MB2Detection.asm rename to Architecture/amd64/Bootstrap/Multiboot2/Detection.asm index 22ba295..ee6166a 100644 --- a/Architecture/amd64/Bootstrap/MB2Detection.asm +++ b/Architecture/amd64/Bootstrap/Multiboot2/Detection.asm @@ -1,4 +1,5 @@ [bits 32] +section .bootstrap.text global DetectCPUID DetectCPUID: pushfd diff --git a/Architecture/amd64/Bootstrap/Multiboot2/Entry.asm b/Architecture/amd64/Bootstrap/Multiboot2/Entry.asm new file mode 100644 index 0000000..ddcf1df --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot2/Entry.asm @@ -0,0 +1,139 @@ +; 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.text +MB2_start: + cli + mov word [0xb8F00], 0x072E ; . + + ; 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) + + push rax ; Multiboot2 Magic + add rbx, KERNEL_VIRTUAL_BASE + push rbx ; Multiboot2 Header + 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 diff --git a/Architecture/amd64/Bootstrap/Multiboot2/GDT32.asm b/Architecture/amd64/Bootstrap/Multiboot2/GDT32.asm new file mode 100644 index 0000000..e9fa980 --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot2/GDT32.asm @@ -0,0 +1,47 @@ +[bits 32] +section .bootstrap.text + +align 32 +global gdtr +gdtr: + dw GDT32_END - GDT32 - 1 + dd GDT32 + +align 32 +GDT32: + dq 0x0 + + dw 0xffff + dw 0x0000 + db 0x00 + dw 0xcf9a + db 0x00 + + dw 0xffff + dw 0x0000 + db 0x00 + dw 0xcf92 + db 0x00 + + dw 0x0100 + dw 0x1000 + db 0x00 + dw 0x4092 + db 0x00 +GDT32_END: + +global LoadGDT32 +LoadGDT32: + lgdt [gdtr] + + jmp 0x8:ActivateGDT + ActivateGDT: + mov cx, 0x10 + mov ss, cx + mov ds, cx + mov es, cx + mov fs, cx + mov cx, 0x18 + mov gs, cx + + ret diff --git a/Architecture/amd64/Bootstrap/MB2Header.asm b/Architecture/amd64/Bootstrap/Multiboot2/Header.asm similarity index 100% rename from Architecture/amd64/Bootstrap/MB2Header.asm rename to Architecture/amd64/Bootstrap/Multiboot2/Header.asm diff --git a/Architecture/amd64/Bootstrap/Multiboot2.cpp b/Architecture/amd64/Bootstrap/Multiboot2/Multiboot2.cpp similarity index 99% rename from Architecture/amd64/Bootstrap/Multiboot2.cpp rename to Architecture/amd64/Bootstrap/Multiboot2/Multiboot2.cpp index 99ed39a..f85ac3b 100644 --- a/Architecture/amd64/Bootstrap/Multiboot2.cpp +++ b/Architecture/amd64/Bootstrap/Multiboot2/Multiboot2.cpp @@ -4,7 +4,7 @@ #include #include -#include "../../../kernel.h" +#include "../../../../kernel.h" BootInfo mb2binfo; diff --git a/Architecture/amd64/Bootstrap/Multiboot2/PageTable.asm b/Architecture/amd64/Bootstrap/Multiboot2/PageTable.asm new file mode 100644 index 0000000..f6525d5 --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot2/PageTable.asm @@ -0,0 +1,85 @@ +PAGE_TABLE_SIZE equ 0x4 ; 1GB +[bits 32] + +section .bootstrap.data +align 0x1000 +global BootPageTable +BootPageTable: + times (0x10000) dq 0 ; 0x4000 + +section .bootstrap.text +global UpdatePageTable +UpdatePageTable: + mov edi, (BootPageTable + 0x0000) + + mov eax, (BootPageTable + 0x1000) + or eax, 0x3 + mov dword [edi], eax + + mov ecx, PAGE_TABLE_SIZE + mov edi, (BootPageTable + 0x1000) + mov eax, (BootPageTable + 0x2000) + or eax, 0x3 + mov ebx, 0x0 + + .FillPageTableLevel3: + mov dword [edi], eax + mov dword [edi + 4], ebx + add eax, 1 << 12 + adc ebx, 0 + add edi, 8 + loop .FillPageTableLevel3 + + mov ecx, (512 * PAGE_TABLE_SIZE) + mov edi, (BootPageTable + 0x2000) + mov eax, 0x0 | 0x3 | 1 << 7 + mov ebx, 0x0 + + .FillPageTableLevel2: + mov dword [edi], eax + mov dword [edi + 4], ebx + add eax, 1 << 21 + adc ebx, 0 + add edi, 8 + loop .FillPageTableLevel2 + + ret + +[bits 64] +section .bootstrap.text +global UpdatePageTable64 +UpdatePageTable64: + mov rdi, (BootPageTable + 0x0000) + + mov rax, (BootPageTable + 0x1000) + or rax, 0x3 + mov [rdi], rax + + mov rcx, PAGE_TABLE_SIZE + mov rdi, (BootPageTable + 0x1000) + mov rax, (BootPageTable + 0x2000) + or rax, 0x3 + mov rbx, 0x0 + + .FillPageTableLevel3: + mov [rdi], rax + mov [rdi + 4], rbx + add rax, 1 << 12 + adc rbx, 0 + add rdi, 8 + loop .FillPageTableLevel3 + + mov rcx, (512 * PAGE_TABLE_SIZE) + mov rdi, (BootPageTable + 0x2000) + mov rax, 0x0 | 0x3 | 1 << 7 + mov rbx, 0x0 + + .FillPageTableLevel2: + mov [rdi], rax + mov [rdi + 4], rbx + add rax, 1 << 21 + adc rbx, 0 + add rdi, 8 + loop .FillPageTableLevel2 + + ret diff --git a/Architecture/amd64/linker.ld b/Architecture/amd64/linker.ld index 9407e8b..96e0e54 100644 --- a/Architecture/amd64/linker.ld +++ b/Architecture/amd64/linker.ld @@ -15,6 +15,14 @@ SECTIONS *(.multiboot2 .multiboot2.*) } + .bootstrap : + { + *(.bootstrap.text .bootstrap.text.*) + *(.bootstrap.data .bootstrap.data.*) + *(.bootstrap.rodata .bootstrap.rodata.*) + *(.bootstrap.bss .bootstrap.bss.*) + } + . += KERNEL_VMA; _kernel_start = .;