Page 1 of 1

mapping 1TB linear address in long mode

Posted: Sat Aug 07, 2010 7:51 am
by lemonyii
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:

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;
.......
}
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.

Re: mapping 1TB linear address in long mode

Posted: Sat Aug 07, 2010 8:17 am
by geppyfx

Code: Select all

((U64*)PD)[511] = Stk|PG_RW|PG_P;
Make sure bit 7 is set. I think Intel calls it 'PS' bit

Re: mapping 1TB linear address in long mode

Posted: Sat Aug 07, 2010 8:27 am
by gerryg400
I have a couple of other questions.
1. Does AllocPageK return a physical address or a virtual address?
2. Where do you set cr3?

Re: mapping 1TB linear address in long mode

Posted: Sat Aug 07, 2010 9:19 am
by lemonyii
Make sure bit 7 is set. I think Intel calls it 'PS' bit
That's the point! Thank you!
i did it when kernel page table is loaded in MemInit, but forgot here.
AddThreadK is a interface of my microkernel: GLOBAL VOID AddThreadK(THREAD* p); it can't fail for its implementation.
And of course, cr3 is set in scheduler of CPL0, on task switching. Thank you all the same!
lemonyii