feat: setup paging and map kernel to higher half

Kernel is now at 0xC0100000, but still we use 4MiB pages, instruction like 'invlpg' which are invalid for cpu prior to 486, and we don't ensure multiboot structures are mapped. Still lot of work
This commit is contained in:
d0p1 🏳️‍⚧️ 2023-07-12 13:24:17 +02:00
parent fd991daeed
commit a9fec6e18c
9 changed files with 86 additions and 91 deletions

View file

@ -1,5 +1,6 @@
KERNEL = vmstupid
SRCS = boot/head.s boot/feat.s kernel.s gdt.s pic.s isr.s idt.s pmm.s paging.s \
SRCS = boot/head.s \
kernel.s gdt.s pic.s isr.s idt.s \
lib/log.s drivers/serial.s
INCS = sys/multiboot.inc \
sys/i386/cpuid.inc \

View file

@ -1,55 +0,0 @@
;; File: feat.s
%include "machdep.inc"
%include "sys/i386/registers.inc"
%include "sys/i386/cpuid.inc"
%include "sys/i386/mmu.inc"
section multiboot.text
extern machdep
;; Function: cpuid_detect
;; check if cpuid is avaible.
;;
;; ripped from <osdev wiki at https://wiki.osdev.org/CPUID#Checking_CPUID_availability>
cpuid_detect:
pushfd
pushfd
xor dword [esp], EFLAGS_ID
popfd
pushfd
pop eax
xor eax, [esp]
popfd
and eax, EFLAGS_ID
ret
;; Function: feat_detect
global feat_detect
feat_detect:
push ebp
mov ebp, esp
call cpuid_detect
test eax, eax
jz .has_cpuid
jmp .end
.has_cpuid:
mov byte [V2P(machdep) + machinfo.has_cpuid], 1
mov eax, CPUID_GETFEATURES
cpuid
;; test if PSE is available
mov eax, edx
and eax, CPUID_FEAT_EDX_PSE
jz .end
mov byte [V2P(machdep) + machinfo.has_pse], 1
;; test if PAE is available (we won't support PAE for now)
mov eax, edx
and eax, CPUID_FEAT_EDX_PAE
jz .end
mov byte [V2P(machdep) + machinfo.has_pae], 1
.end:
leave
ret

View file

@ -1,8 +1,11 @@
;; File: head.s
;;
;; About: CPU compatibility
;; /!\ Only work on *486+* for now.
;; - `invlpg` which is not part of 386 ISA.
;;
[BITS 32]
%include "machdep.inc"
%include "sys/multiboot.inc"
%include "sys/i386/registers.inc"
%include "sys/i386/mmu.inc"
@ -38,24 +41,35 @@ section .multiboot.text
;;
global entry
entry:
extern stack_top
mov esp, V2P(stack_top)
;; disable interrupt
cli
;; save boot params
mov edi, eax
mov esi, ebx
extern feat_detect
call feat_detect
;; setup 4MB paging
;; TODO: check if 4MB paging is available
mov eax, cr4
or eax, CR4_PSE
mov cr4, eax
cmp edi, MB_MAGIC
jne .skip_map_multiboot
;; check if multiboot struct is in first 4Mib
;; otherwith add entry in page dir
mov eax, 400000
cmp ebx, eax
jg .map_multiboot
jmp .skip_map_multiboot
.map_multiboot:
;; TODO: for now let's assume data are bellow 4Mib
jmp .end
.skip_map_multiboot:
add esi, KERNBASE
.end:
extern page_directory
mov eax, V2P(page_directory)
mov eax, V2P(boot_page_dir)
mov cr3, eax
;; enable paging
@ -63,7 +77,34 @@ entry:
or eax, CR0_PG | CR0_PE | CR0_WP
mov cr0, eax
extern page_directory
mov eax, page_directory - KERNBASE
extern kernel_start
mov ebx, kernel_start
;; Jump to higher half
lea eax, entry_high
jmp eax ; near jump, indirect
section .text
entry_high:
mov dword [boot_page_dir], 0
invlpg [0]
extern stack_top
mov esp, stack_top
xor ebp, ebp
push edi
push esi
extern kmain
call kmain
cli
hang:
hlt
jmp hang
section .data
align 0x1000
boot_page_dir:
dd 0 | PDE_P | PDE_W | PDE_PS
times (P2PDE(KERNBASE) - 1) dd 0
dd 0 | PDE_P | PDE_W | PDE_PS
times 0x400 - (boot_page_dir - $$) dd 0

View file

@ -1,7 +1,7 @@
; File: kernel.s
[BITS 32]
%include "machdep.inc"
%include "base.inc"
section .bss
align 16
@ -17,14 +17,16 @@ kmain:
push ebp
mov ebp, esp
extern serial_init
call serial_init
LOG msg_hello_world
leave
ret
section .data
global machdep
machdep:
istruc machinfo
at machinfo.has_cpuid, db 0
at machinfo.has_pse, db 0
at machinfo.has_pae, db 0
iend
section .rodata
msg_hello_world db "StupidOS v", STUPID_VERSION, " (built with ", __NASM_VER__, " on ", __DATE__, " ", __TIME__, ")", 0
file db __FILE__, 0

View file

@ -7,7 +7,7 @@ SECTIONS
kernel_start = .;
.multiboot : {
.multiboot ALIGN(0x1000): {
KEEP(*(.multiboot.data))
KEEP(*(.multiboot.text))
}

View file

@ -1,5 +0,0 @@
struc machinfo
.has_cpuid: resb 1
.has_pse: resb 1
.has_pae: resb 1
endstruc

View file

@ -45,8 +45,12 @@
%define PDE2P(addr) (addr << 22)
%define P2PTE(addr) ((addr >> 12) & 0x3FF)
;; Defines: PDE
;; PTE_P - Present
;; Defines: Page Directory Flags
;; PDE_P - Present
;; PDE_W - Writable
;; PDE_U - User
;; PDE_PWT - Write-Through
;; PDE_PS - 4MiB page
PDE_P equ 1 << 0
PDE_W equ 1 << 1
PDE_U equ 1 << 2
@ -57,7 +61,7 @@ PDE_D equ 1 << 6
PDE_PS equ 1 << 7
PDE_G equ 1 << 8
;; Defines: PTE
;; Defines: Page Table Flags
;; PTE_P - Present
;; PTE_W - Writable
;; PTE_U - User

View file

@ -108,8 +108,15 @@ endstruc
;
; MB_INFO_MEM - todo
; MB_INFO_BOOTDEV - todo
MB_INFO_MEM equ 1 << 0
MB_INFO_BOOTDEV equ 1 << 1
MB_INFO_MEM equ 1 << 0
MB_INFO_BOOTDEV equ 1 << 1
MB_INFO_CMDLINE equ 1 << 2
MB_INFO_MODULES equ 1 << 3
MB_INFO_MMAP equ 1 << 6
MB_INFO_DRIVES equ 1 << 7
MB_INFO_BOOTLOADER_NAME equ 1 << 9
MB_INFO_VBE equ 1 << 11
MB_INFO_FRAMEBUFFER equ 1 << 12
; Structure: mb_mmap
struc mb_mmap

View file

@ -3,4 +3,4 @@ SRCS = log.s
INCS = base.inc
include $(TOPDIR)/share/mk/stupid.lib.mk
include $(TOPDIR)/share/mk/stupid.inc.mk
#include $(TOPDIR)/share/mk/stupid.inc.mk