switch to user mode fails when paging is enabled
Posted: Sun May 08, 2011 2:34 pm
Hello,
I cannot switch to user mode while paging is enabled. Only then...but when it's disabled it works just fine. I have been struggling with this for a long time but cannot figure it out so I'm asking you guys for help.
Here's paging code:
Please, request more if needed...I red the manual over and over, but apparently I'm missing something (probably stupid).
Thank you, best regards!
I cannot switch to user mode while paging is enabled. Only then...but when it's disabled it works just fine. I have been struggling with this for a long time but cannot figure it out so I'm asking you guys for help.
Here's paging code:
Code: Select all
#include <stdint.h>
#include <print.h>
#include <compiler.h>
#include <mem.h>
#define PAGE_SIZE 4096
/* PDE */
typedef struct pde_structure {
uint32_t present : 1;
uint32_t rw : 1;
uint32_t us : 1;
uint32_t pwt : 1;
uint32_t pcd : 1;
uint32_t accessed : 1;
uint32_t unused : 6;
uint32_t address : 20;
} pde_t;
/* PTE */
typedef struct pte_structure {
uint32_t present : 1;
uint32_t rw : 1;
uint32_t us : 1;
uint32_t pwt : 1;
uint32_t pcd : 1;
uint32_t accessed : 1;
uint32_t dirty : 1;
uint32_t unused : 5;
uint32_t address : 20;
} pte_t;
/* page directory */
pde_t current_pd[1024] __ALIGNED(PAGE_SIZE);
/* page table */
pte_t current_pt[1024] __ALIGNED(PAGE_SIZE);
void install_handler();
void init_paging()
{
int i;
uint32_t address = 0;
memset(current_pt, 0, sizeof(current_pt));
memset(current_pd, 0, sizeof(current_pd));
install_handler(14, page_fault_handler);
address = (uint32_t)¤t_pt>>12;
/* set kernel PD */
current_pd[0].present = 1;
current_pd[0].rw = 1;
current_pd[0].us = 1;
current_pd[0].address = address;
address = 0;
/* first 4MB identity mapped */
for (i = 0; i != 1024; i++) {
current_pt[i].present = 1;
current_pt[i].rw = 1;
current_pt[i].address = address>>12;
address += PAGE_SIZE;
}
init_msg(Initializing paging);
/*
* Intel, Vol 3a, ch. 19.30.3
*/
asm volatile("movl %0, %%eax; movl %%eax, %%cr3;"
::"r"(¤t_pd):);
asm volatile(
"movl %cr0, %eax;"
"orl $0x80000000, %eax;"
"movl %eax, %cr0;"
"jmp 1f; 1:"
);
}
Thank you, best regards!