mapping 1TB linear address in long mode
Posted: Sat Aug 07, 2010 7:51 am
Hello!
sorry for my absent for months, I had been preparing my exams until a month ago.When i return to my previous work of my kernel, i got troubles.
Problem Description:
i started my micro(CPL0) kernel and an idle task(CPL1), and then i try to creat a kernel thread for process manag(CPL1), which may also called process, for it's using an independent page tables.my code:
but it will got an #PF with error code 0x02 (Write,not present,right?) , cr2 = 0xffffffffe8 (the rsp) and the rip is on a call instruction.
what's the problem? i think it is somewhere on my mapping code, but i can see where after my check AMD's document.
does address 0x10000000000ull (1TB, ten zeros,right?) maps to 2M page as PML4[1]->PDP[511]->PD[511]->2M Page?
thanks,
lemonyii.
sorry for my absent for months, I had been preparing my exams until a month ago.When i return to my previous work of my kernel, i got troubles.
Problem Description:
i started my micro(CPL0) kernel and an idle task(CPL1), and then i try to creat a kernel thread for process manag(CPL1), which may also called process, for it's using an independent page tables.my code:
Code: Select all
#define PG_P 0x1ULL
#define PG_RW 0x2ULL
GLOBAL VOID IdleTask(THREAD* pMe){ //given the thread pointer of myself
U64 PML4,PDP,PD,Stk;
THREAD* p;
/* alloc page and thread struct for proc task.
just a stack at linear address 1TB,
the lower address was in kernel space,
and was set G attribute in MemInit */
p = (THREAD*)AllocPageK(4096);
PML4 = AllocPageK(4096);
PDP = AllocPageK(4096);
PD = AllocPageK(4096);
Stk = AllocPageK(0x200000);
if(p==NULL||PML4==NULL||PDP==NULL||PD==NULL){
Printk(COLOR_FR, L"\nFailed to creat process task.");
while(1);
}
CleanMem((U64)p,4096);
CleanMem(PML4,4096);
CleanMem(PDP,4096);
CleanMem(PD,4096);
((U64*)PML4)[0] = ((U64*)(pMe->Cr3))[0]|PG_RW|PG_P; //lower 512G is the same as kernel.Though G is set,but it got error without this
((U64*)PML4)[1] = PDP|PG_RW|PG_P; //this entry is 512G to 1T
((U64*)PDP)[511] = PD|PG_RW|PG_P; //use the last items,so it will be at 1T
((U64*)PD)[511] = Stk|PG_RW|PG_P;
p->IntStk[0] = (U64)ProcTask;
p->IntStk[1] = SELECTORC1;
p->IntStk[2] = 0x1002ULL; //IOPL=1
p->IntStk[3] = 0x10000000000ull - 8; //rsp = 1T - 8byte
p->IntStk[4] = SELECTORD1;
p->Cr3 = PML4;
.......
}
what's the problem? i think it is somewhere on my mapping code, but i can see where after my check AMD's document.
does address 0x10000000000ull (1TB, ten zeros,right?) maps to 2M page as PML4[1]->PDP[511]->PD[511]->2M Page?
thanks,
lemonyii.