enabling paging leads to triple fault (solved)

0

In case this helps somebody in the future:

  • check if the global descriptor table is working
  • check if the elements of page table entry struct are ordered correctly

This code worked for me:

gdt.s

section .data
gdt:
    .null:
        dq 0
    .code:
        dw 0xFFFF
        dw 0x0000
        db 0x00
        db 0x9A
        db 0xCF
        db 0x00
    .data:
        dw 0xFFFF
        dw 0x0000
        db 0x00
        db 0x92
        db 0xCF
        db 0x00

gdtr:
    dw $-gdt-1
    dd gdt

section .text

global init_global_descriptor_table
init_global_descriptor_table:
    lgdt [gdtr]
    jmp 0x08:.reload_cs

.reload_cs:
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    ret

paging.c

enum flags {
    Present = 1 << 0,
    ReadWrite = 1 << 1,
    AccessAll = 1 << 2,
    WriteThroughCashing = 1 << 3,
    DisableCashing = 1 << 4,
    Accessed = 1 << 5,
    Dirty = 1 << 6,     // only for page-table-entries
    MPages = 1 << 7,
    Global = 1 << 8,    // only for page-table-entries
};

struct entry {
    unsigned int flags : 9;
    unsigned int available : 3;
    unsigned int addr : 20;
};

extern void load_paging_directory(int *ptr);

void init_paging() {
    struct entry *dir = (struct entry *)0x00105000;
    struct entry *t1 = (struct entry *)0x00106000;      

    for (int i = 0; i < 1024; i++) {
        dir[i] = (struct entry){0};
        if (i <= 262) t1[i] = (struct entry){Present | ReadWrite, 0, i};
    }

    dir[0] = (struct entry){Present, 0, (int)t1 >> 12};
    load_paging_directory((int *)dir);
}

paging_asm.s

global load_paging_directory
load_paging_directory:
    push ebp,
    mov ebp, esp
    mov eax, [ebp + 8]
    mov cr3, eax
    mov eax, cr0
    or eax, 0x80000001
    mov cr0, eax   
    mov esp, ebp
    pop ebp
    ret

My mistake was that my struct had the address field in the low bits and the flags field in the high bits. This was the cause for some very strange behavior. In the end it did not crash at mov cr0, eax but rather at mov esp, ebp. Thank you to every person who commented.

c
nasm
paging
gdt
asked on Stack Overflow Mar 25, 2021 by WernerDrasche • edited Mar 28, 2021 by WernerDrasche

1 Answer

0

The question has been solved using this struct:

struct entry {
    unsigned int flags : 9;
    unsigned int available : 3;
    unsigned int addr : 20;
};
answered on Stack Overflow Mar 29, 2021 by WernerDrasche

User contributions licensed under CC BY-SA 3.0