I have a few other questions to ask now.
For the physical memory manager, I can't find examples for the stack based method. If I use the bit map based method and lets say I have 2 MiB (0x200000) of memory, I will need 512 bits to mark physical pages of 0x1000 bytes (0x200000/0x1000=0x200=512), which leads to 64 bytes I will need (512/8=64). Is that correct?
For the virtual memory manager, what does higher half kernel mean? I my example, I go from 32 bit protected mode without paging to 64 bit long mode with paging. Does this mean that virtual memory must map physical memory? If I don't do that a triple fault comes up.
Now the problem is where do I put the physical memory manager's data? At the 1MiB mark and make virtual = physical. How much size does it need if I have 8GB of RAM?
Here is the part of my source code where I jump to long mode:
Code: Select all
.section .text
.globl start
start:
.code16
# Read in Control Register 0
# Enable Protected Mode (Bit 0)
# Write to Control Register 0
movl %cr0, %eax
orl $(1<<0), %eax
movl %eax, %cr0
# Load Global Descriptor Table
lgdt gdt32ptr
# Setup all Segment Registers
# and reload Code Segment, Instruction Pointer
movw $0x0010, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
ljmp $0x0008, $jump_to_pm
jump_to_pm:
.code32
# Set A Register to 0x0000
# Set C Register to 0x1000
# Set Destination Index to 0x0000
# Store A Register times C Register
clrl %eax
movl $0x1000, %ecx
clrl %edi
rep stosl
# Set Page Present (Bit 0)
# Set Page Read & Write (Bit 1)
# Enable Page-Level Writethrough (Bit 3)
# Disable Page-Level Cache (Bit 4)
clrl %ebx
orl $(1<<0), %ebx
orl $(1<<1), %ebx
orl $(1<<3), %ebx
orl $(1<<4), %ebx
movl $0x0003, %ecx
movl $0x0000, %edi
create_pt_entry_0:
movl %edi, %eax
addl $0x1000, %eax
orl %ebx, %eax
movl %eax, (%edi)
addl $0x1000, %edi
loop create_pt_entry_0
clrl %eax
movl $0x0100, %ecx
create_pt_entry_1:
orl %ebx, %eax
movl %eax, (%edi)
addl $0x1000, %eax
addl $0x0008, %edi
loop create_pt_entry_1
# Use Model Specific Register 0xc0000080
# Read in Model Specific Register
# Enable System-Call Extension (Bit 0)
# Enable Long Mode (Bit 8)
# Enable No Execute (Bit 11)
# Write to Model Specific Register
movl $0xc0000080, %ecx
rdmsr
orl $(1<<0), %eax
orl $(1<<8), %eax
orl $(1<<11), %eax
wrmsr
# Read in Control Register 4
# Enable Physical Address Extension (Bit 5)
# Enable Page Global Enabled (Bit 7)
# Write to Control Register 4
movl %cr4, %eax
orl $(1<<5), %eax
orl $(1<<7), %eax
movl %eax, %cr4
# Set PML4 address
# Enable Page-Level Writethrough (Bit 3)
# Disable Page-Level Cache (Bit 4)
# Store Control Register 3
clrl %eax
orl $(1<<3), %eax
orl $(1<<4), %eax
movl %eax, %cr3
# Read in Control Register 0
# Enable Paging (Bit 31)
# Write to Control Register 0
movl %cr0, %eax
orl $(1<<31), %eax
movl %eax, %cr0
# Load Global Descriptor Table
# Load Interrupt Descriptor Table
lgdt gdt64ptr
lidt idt64ptr
# Setup all Segment Registers
# and reload Code Segment, Instruction Pointer
movw $0x0020, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
ljmp $0x0008, $jump_to_lm
jump_to_lm:
.code64
# Setup the stack
movq $0x7e00, %rbp
movq %rbp, %rsp
# Call Main Function
call kmain
hang:
# Halt the CPU
# Infinit loop if Halt doesn't work
hlt
jmp hang