LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (https://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   Address of PGD or 'swapper_pg_dir' and its contents (https://www.linuxquestions.org/questions/linux-kernel-70/address-of-pgd-or-swapper_pg_dir-and-its-contents-940329/)

hardric88 04-17-2012 06:48 PM

Address of PGD or 'swapper_pg_dir' and its contents
 
Hi guys,
I need to get the value of PGD and its contents. I was able to get the address of PGD from CR3 register but I am not able to print the entries in PGD. Please look at my code and help me out.

unsigned int *memptr,mem1,*mem2ptr,i=255;
asm volatile ("\tmovl %%cr3, %%eax\n\t"
"movl %%eax, %0\n\t"
:"=rm"(mem1)
:);
printk(KERN_INFO "\nvalue of cr3: %x",mem1);
memptr=(void *)mem1; //cr3 value in memptr
mem2ptr=&i; //mem2ptr given an address(known)
printk(KERN_INFO "\nCR3 value is %x\n",memptr);
printk(KERN_INFO "\nEntry 0 in CR3:%x",*memptr);
printk(KERN_INFO "\nValue of i:%d\n",i);

memcpy(mem2ptr,memptr,4);
printk(KERN_INFO "Entry in 0th entry of pgd:%x",*mem2ptr);
printk(KERN_INFO "Value of i:%x",i);

From the code above, I am able to print 'memptr' which is the address of PDG (content of CR3), but I am not able to print the value of *memptr(0th entry of PGD). Please help me out how I can do it.
Also that, the line "memcpy(em2ptr,memptr,4) doesn't work. I have no idea why it is not working.
For both the problems above, I guess I am not able to access the address of CR3 and print its contents. But again, I'm not sure what's wrong. Please let me know. Thanks in advance.
Regards.

ChazZeromus 04-17-2012 09:25 PM

What does it output? Does it panic?

hardric88 04-18-2012 05:44 PM

Quote:

Originally Posted by ChazZeromus (Post 4655634)
What does it output? Does it panic?

Hi,
The output is that the kernel gets compiled. When I restart it, it just stays (hangs) showing "Loading initial ramdisk". I then have to manually restart the machine and then choose a different image to start loading. I'm not sure what's wrong in the code. As I've mentioned in my first post, if I comment the '*memptr' print statement and the 'memcpy' statement, then the image is loading and I can see the output in 'dmesg'. Don't know how to get over this problem. Please help out.
Thanking you.

ChazZeromus 04-18-2012 06:10 PM

Hm, I don't know much kernel about modules, if they don't share the same page layout that could be why. As CR3 points to the PDG as a physical address, the module code probably isn't allowed due to possibly restrictive address space layout for LKMs, I'm not sure. I read that they share the same exact address space as the kernel I so wouldn't see why.

UPDATE: Forgot that bits below the 12th are extra flag stuff, try clearing everything below memptr with 0xFFFFF000.

Code:

memptr &= 0xFFFFF000;

hardric88 04-19-2012 02:02 AM

Hi,
I didn't understand what you were trying to say with the statement:
memptr &= 0xFFFFF000;

Were you asking me to add this statement below the 'memptr' print statement? I couldn't understand about the extra flag stuff you were mentioning about. Can you please elaborate on that. However, I tried compiling the kernel after including the code you sent me (the line 'memptr &= 0xFFFFF000', and I was getting an error "invalid operands to binary &". Please let me know what to do.
Thanking You.

ChazZeromus 04-19-2012 02:34 AM

The CR3 register containers additional paging information and operation flags, in the first 19 bits, the 20th bit and the rest is an aligned pointer to the location of the PGD. So all you need is the last twenty bits. Um try this instead:
Code:

memptr = (void*)( mem1 & 0xFFFFF000 )
Replace the first assignment of memptr with that.

hardric88 04-19-2012 02:37 PM

Hi,
I tried doing what you mentioned. The actual value of memptr was b29000. Even after I try assigning memptr as - "memptr = (void*)( mem1 & 0xFFFFF000 )", the value of memptr was b29000. So in either case, *memptr is not able to reach the address 'b29000' and print the value present at that address. Don't know how to solve this. Do you have any other solution, please let me know.
Thanking You.

ChazZeromus 04-19-2012 09:25 PM

Well I decided to do some investigation and all I can say is that it IS possible that kernel space does not allow writing of global page tables as a security/saftey precaution. To put simply, when the global pages were setup, it effectively locked itself out of the page tables contents.

But, you could read them again by disabling paging, perform a far jump serialize the processor, writng the pages into a known part of memory that presists in physical and GPT address spaces, then reenabling paging along with another far jump. (I believe the jumping is just required on older processors) This could work, that is if the GDT hasn't been mapped in a such a way that the page tables are locked out too.


But if all you wanted to do was learn how paging is setup and that since you're directly modifying the kernel, you can look in the source code yourself and see how they're setup. Or save more time by reading articles/books on how linux sets up kernel space.

I'm sorry if I haven't been helpful.


All times are GMT -5. The time now is 10:16 AM.