Update multiboot2 bootstrap code

This commit is contained in:
Alex 2023-03-29 10:56:23 +03:00
parent 298c6b3921
commit 73f38799eb
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
10 changed files with 281 additions and 81 deletions

View File

@ -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

View File

@ -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

View File

@ -1,4 +1,5 @@
[bits 32]
section .bootstrap.text
global DetectCPUID
DetectCPUID:
pushfd

View File

@ -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

View File

@ -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

View File

@ -4,7 +4,7 @@
#include <memory.hpp>
#include <io.h>
#include "../../../kernel.h"
#include "../../../../kernel.h"
BootInfo mb2binfo;

View File

@ -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

View File

@ -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 = .;