cx86paginginline-assemblyosdev

Enabling Paging restarts QEMU


In my paging code, qemu restarts because of some of the inline assembly. It could be something else, but removing the assembly causes the program to work fine. Alternatively, it could be possible that some of the earlier code is causing paging to initialize incorrectly. Here is the Paging Init Function:

void paging_init(){
    //Enable Paging
    uint32 cr0;
    memset(g_page_directory, 0, sizeof(page_directory_t) * 1024);
    memset(g_page_tables, 0, sizeof(page_table_t) * 1024);
    
    // Set All page directories to have rw and u/s access (only by kernel)
    for(int i = 0; i < 1024; i++){
        g_page_directory[i].user_supervisor = 1;
        g_page_directory[i].read_write = 1;
    }
    
    // fill all the entries in page table to map all 4MB memory
    for (int i = 0; i < 1024; i++) {
        g_page_tables[i].present = 1;
        g_page_tables[i].read_write = 1;
        g_page_tables[i].user_supervisor = 1;
        g_page_tables[i].frame = (i * PAGE_SIZE) >> 12;
    }
    
    // set first page directory to be accessed with frame 0x11a(kernel region address)
    g_page_directory[0].present = 1;
    g_page_directory[0].accessed = 0;
    g_page_directory[0].user_supervisor = 1;
    g_page_directory[0].frame = 0x11a;
    //Register Page Fault Handler
    isr_register_interrupt_handler(14, page_fault_handler);

    // set cr3 point to page directory
    asm volatile("mov %0, %%cr3" ::"r"(g_page_directory));
    
    // set bit in cr0 to enable paging
    asm volatile("mov %%cr0, %0": "=r"(cr0));
    cr0 = cr0 | 0x80000000;
    asm volatile("mov %0, %%cr0" ::"r"(cr0));
}

QEMU restarts because of these lines of inline assembly:

    // set cr3 point to page directory
    asm volatile("mov %0, %%cr3" ::"r"(g_page_directory));
    
    // set bit in cr0 to enable paging
    asm volatile("mov %%cr0, %0": "=r"(cr0));
    cr0 = cr0 | 0x80000000;
    asm volatile("mov %0, %%cr0" ::"r"(cr0));

How can I fix this error?

Edit (here are the typedefs):

// Page Directory Struct
typedef struct {
    uint32 present :1;
    uint32 read_write :1;
    uint32 user_supervisor :1;
    uint32 write_through :1;
    uint32 cache_disable :1;
    uint32 accessed :1;
    uint32 dirty :1;
    uint32 page_size :1;
    uint32 global :1;
    uint32 available :3;
    uint32 frame :20;
} page_directory_t;

// Page Table
typedef struct {
    uint32 present :1;
    uint32 read_write :1;
    uint32 user_supervisor :1;
    uint32 write_through :1;
    uint32 cache_disable :1;
    uint32 accessed :1;
    uint32 dirty :1;
    uint32 page_size :1;
    uint32 global :1;
    uint32 available :3;
    uint32 frame :20;
} page_table_t;

Edit: Code Sample with paging code (Some of the names of structs are different but code is all the same other than that): https://filebin.net/hql1zrigj8dgbmto


Solution

  • Ok, adding g_page_directory[0].frame = ((uint32)g_page_tables >> 12); helped, and the code went without errors. Thanks!