os-k/boot/loader/mem/management.inc

161 lines
6.6 KiB
PHP
Raw Permalink Normal View History

;=----------------------------------------------------------------------------=;
2020-09-27 17:33:48 +02:00
; OS on Kaleid ;
; ;
; Desc: Memory management from protected mode ;
; (x86_64 architecture only) ;
; ;
; ;
2021-02-18 19:54:35 +01:00
; Copyright © 2018-2021 The OS/K Team ;
; ;
; This file is part of OS/K. ;
; ;
; OS/K is free software: you can redistribute it and/or modify ;
; it under the terms of the GNU General Public License as published by ;
; the Free Software Foundation, either version 3 of the License, or ;
; (at your option) any later version. ;
; ;
; OS/K is distributed in the hope that it will be useful, ;
; but WITHOUT ANY WARRANTY; without even the implied warranty of ;
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;
; GNU General Public License for more details. ;
; ;
; You should have received a copy of the GNU General Public License ;
; along with OS/K. If not, see <https://www.gnu.org/licenses/>. ;
;=----------------------------------------------------------------------------=;
[BITS 32]
[section .text]
; ---------------------------------------------------------------------------- ;
; Constructor for the page tables in protected mode ;
; ---------------------------------------------------------------------------- ;
Setup_paging:
2020-01-15 16:26:44 +01:00
;; Map first PML4 entry to PDP table
mov eax, PDP_table
2020-01-15 16:26:44 +01:00
or eax, 0b11 ; Present + writable
mov [PML4_table], eax
2020-01-15 16:26:44 +01:00
;; Map first PDP entry to PD table
mov eax, PD_table
or eax, 0b11 ; Present + writable
mov [PDP_table], eax
2020-01-15 16:26:44 +01:00
;; Map each PD entry to a huge 2MiB page
mov ecx, 0 ; counter variable
2019-03-28 10:34:18 +01:00
.map_pd_table:
2020-01-15 16:26:44 +01:00
;; Map ecx-th PD entry to a huge page that starts at address 2MiB*ecx
mov eax, 0x200000 ; 2MiB
mul ecx ; start address of ecx-th page
2020-01-15 16:26:44 +01:00
or eax, 0b10000011 ; present + writable + huge
mov [PD_table + ecx * 8], eax ; map ecx-th entry
inc ecx ; increase counter
cmp ecx, 512 ; if counter == 512, the whole P2 table is mapped
jne .map_pd_table ; else map the next entry
2020-01-15 16:26:44 +01:00
2019-05-15 02:26:55 +02:00
ret
; ---------------------------------------------------------------------------- ;
; Enable long mode and paging ;
; ---------------------------------------------------------------------------- ;
Go64:
pusha
;; Registering paging
mov eax, PML4_table
mov cr3, eax ; Load PML4 to cr3
mov eax, cr4
or eax, 1 << 5
mov cr4, eax ; Enable PAE
;; Activate long mode
mov ecx, 0xC0000080 ; Address of MSR
rdmsr ; Read MSR
or eax, 1 << 8 ; LME = 1. (Long Mode Enable)
2019-05-15 15:55:57 +02:00
or eax, 1 << 11 ; NXE = 1 (No execute bit)
wrmsr ; Write MSR
;; Enable paging
mov eax, cr0
or eax, 1 << 31 ; Make MSR bit 31 (PG = Paging) to 1 :
; |1|000000000000000000000000000000
; |
; `------ Paging bit
mov cr0, eax
jmp .end
nop
nop
.end:
popa
ret
; ---------------------------------------------------------------------------- ;
; Checks if Grub has enabled A20 line ;
; ---------------------------------------------------------------------------- ;
CheckA20:
pushad
mov edi, 0x112345 ; Odd megabyte address.
mov esi, 0x012345 ; Even megabyte address.
mov [esi],esi ; Making sure that both addresses contain diffrent values.
mov [edi],edi ; (if A20 line is cleared the two pointers would point to the address 0x012345 that would contain 0x112345 (edi))
cmpsd ; Compare addresses to see if the're equivalent.
popad
jne .A20_on ; If not equivalent , A20 line is set.
jmp .A20_err
.A20_on:
ret
.A20_err:
mov ax, "04" ; ERROR 04 : A20 line failed
jmp Error
2019-03-25 23:10:06 +01:00
[BITS 64]
; ---------------------------------------------------------------------------- ;
; Initilizes the stack ;
2019-05-13 15:18:00 +02:00
; ;
; Not a function because it wipes the stack ;) ;
2019-03-25 23:10:06 +01:00
; ---------------------------------------------------------------------------- ;
InitStack:
xor rax, rax ; "Fill pattern"
push rcx
push rdi
;; Begin address to fill and length
2019-05-15 15:55:57 +02:00
mov rdi, kernelEnd
2019-05-13 15:18:00 +02:00
2019-05-15 15:55:57 +02:00
;; Alignes it to 4096o / FUTURE PAGE FRAME
shr rdi, 12
shl rdi, 12
add rdi, 0x1000
2019-05-13 15:18:00 +02:00
2019-05-15 15:55:57 +02:00
;; Passing info to kernel
mov qword [newKernelEnd], rdi
mov rcx, KERNEL_STACK ; counter
2019-03-25 23:10:06 +01:00
;; If bit 0 is on, fill one byte
sar rcx, 1 ; Shift bit 0 into CY
jnc $ + 3
stosb
2019-03-25 23:10:06 +01:00
;; We are word aligned and if bit 1 was on fill another word
sar rcx, 1 ; Shift bit 1 into CY
jnc $ + 4
stosw
2019-03-25 23:10:06 +01:00
;; We are dword aligned and if bit 2 was on fill another dword
2019-05-15 15:55:57 +02:00
sar rcx, 1 ; Shift bit 2 into CY
jnc $ + 3
2019-03-25 23:10:06 +01:00
stosd
2019-05-13 15:18:00 +02:00
2019-03-25 23:10:06 +01:00
;; RCX now equals the number of qwords to fill
2019-05-15 15:55:57 +02:00
repnz stosq ; Finish by writing RCX qwords.
;; New info for the kernel
mov qword [newStackEnd], rdi
mov rsp, rdi
2019-03-25 23:10:06 +01:00
pop rdi
pop rcx
2019-11-08 14:39:20 +01:00
jmp AfterInitStack