Can't enable paging

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
orborneroberts
Posts: 1
Joined: Fri Dec 06, 2024 3:12 am

Can't enable paging

Post by orborneroberts »

Hello, i'm trying to create os in c++ and i stumbled upon 1 problem: setting the paging bit causes a Triple Fault. Code here:

paging.asm:

Code: Select all

[Bits 32]
[Global PagingLoadDirectory]
[Global PagingEnable]

PagingLoadDirectory:
    push ebp
    mov ebp, esp
    mov eax, [esp+8]
    mov cr3, eax
    mov esp, ebp
    pop ebp
    ret

PagingEnable:
    push ebp
    mov ebp, esp
    mov eax, cr0
    or eax, 0x80000000
    mov cr0, eax
    mov esp, ebp
    pop ebp
    ret
    
kernel.cpp:

Code: Select all

extern "C" void PagingLoadDirectory(psize_t directory);
extern "C" void PagingEnable();
//...
psize_t PageDirectory = (psize_t)0x1004000;
psize_t PageTable = (psize_t)0x1005000;
for (size_t i = 0; i < 1024; i++) PageDirectory[i] = 0x00000002;
for (size_t i = 0x1000; i < 0x1400; i++) PageTable[i] = (i * 0x1000) | 3;
PageDirectory[0] = (size_t)PageTable | 3;
PagingLoadDirectory(PageDirectory);
PagingEnable();    //Triple Fault
What am I doing wrong?
P.S. the value of the control registers after the error occurred:
CR0=0x80000011 CR2=0x01002580 CR3=0x01004000 CR4=0x00000000

The kernel is placed after 16 MB (at address 0x1000000)
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: Can't enable paging

Post by nexos »

A single page table (and therefore a PDE) covers only a 4 MiB region. By setting the first entry in the page directory you’re mapping 0x0-0x3fffff. You should set entry 3 to the page table. I would recommend using macros to index the directory and table, for example considering the fact that VAs are 32 bits wide and directory and table indices are 10 bits wide, that means that the upper 10 bits of a va are the directory index, middle 10 are table index, lower 12 are page offset. That means that to get the directory index of a VA, do

Code: Select all

int dirIdx = (va >> 22) & 0x3FF;
int tabIdx = (va >> 12) & 0x3FF;
I would recommend putting that either in an inline function or making a macro based off it so you don’t have to write the formula every time you want to use it.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
Post Reply