Programming, for all ages and all languages.
narke
Member
Posts: 119 Joined: Wed Dec 26, 2007 3:37 am
Location: France
Post
by narke » Thu Jan 30, 2014 5:33 pm
Hi guys,
I wrote a code like that (linux kernel module) in order to explore page tables on Linux x86_64, but it seems that it's not getting the right PDPTE, maybe even the right PML4, do you see something odd.
Any help would would be appreciated.
I get inspired by this method:
http://lists.xen.org/archives/html/xen- ... 1xYc8b.txt
Code: Select all
// See Table 4-14.
#define PRESENT (1ULL << 0)
#define PAGE_GRANULARITY (1ULL << 7)
#define PML4_INDEX(address) ((address >> 39) & 0x1ff)
#define PDPT_INDEX(address) ((address >> 30) & 0x1ff)
unsigned long paging_entry(unsigned long address)
{
unsigned long cr3;
unsigned long pml4, pml4e;
unsigned long pdpt, pdpte;
unsigned long pd, pde;
asm volatile("movq %%cr3, %0\n\t"
:"=r" (cr3));
pml4 = __va(cr3 & 0xfffffffffffff000);
pml4e = pml4 + PML4_INDEX(address) * 0x8;
if ((pml4e & PRESENT) == 0)
return -EINVAL;
pdpt = pml4e & ~0xfff;
pdpte = pdpt + PDPT_INDEX(address) * 0x8;
if ((pdpte & PRESENT) == 0)
return -EINVAL;
}
Last edited by
narke on Mon Feb 03, 2014 4:32 pm, edited 2 times in total.
thepowersgang
Member
Posts: 734 Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:
Post
by thepowersgang » Thu Jan 30, 2014 5:48 pm
I don't see any attempt at reading physical memory there, that's probably your problem
narke
Member
Posts: 119 Joined: Wed Dec 26, 2007 3:37 am
Location: France
Post
by narke » Fri Jan 31, 2014 2:33 am
It appears that the cr3 value should be mapped, so do I need to add PAGE_OFFSET or to use annoter function?
Combuster
Member
Posts: 9301 Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:
Post
by Combuster » Fri Jan 31, 2014 2:52 am
This is called desk checking. Your problem is mainly that you're not doing anything close to what you want
Code: Select all
pml4 = __va(cr3 & 0xfffffffffffff000);
// because paging never alters the bottom 12 bits
// pml4 = table & 0xff...ff000
pml4e = pml4 + PML4_INDEX(address) * 0x8;
// pml4e = (table & 0xff...ff000) + (x << 3)
if ((pml4e & PRESENT) == 0)
// pml4e & PRESENT =
// ((table & 0xff...ff000) + (x << 3)) & 1 =
// (because the first argument doesn't contribute to bit 0)
// table & 0xff...ff000 & 1 + (x << 3) & 1 =
// table & 0 + (x << 3) & 1 =
// (multiple of eight is never odd)
// table & 0 + 0 =
// 0
// 0 == 0 always true.
return -EINVAL;
// rest of code unreachable
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[
My OS ] [
VDisk/SFS ]
narke
Member
Posts: 119 Joined: Wed Dec 26, 2007 3:37 am
Location: France
Post
by narke » Fri Jan 31, 2014 7:37 am
combuster
The pml4 contains other tables, so how can you get pml4 from a table?
Combuster
Member
Posts: 9301 Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:
Post
by Combuster » Fri Jan 31, 2014 8:00 am
Learn C.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[
My OS ] [
VDisk/SFS ]
narke
Member
Posts: 119 Joined: Wed Dec 26, 2007 3:37 am
Location: France
Post
by narke » Mon Feb 03, 2014 4:29 pm
There was nothing related to the lacking of knowledge of C.
In fact each page table entry (cr3, PML4, PDPT, PD, PT) contains a physical address which must be mapped to a virtual address, with __va() on Linux, to acess the next entry.