Showing posts with label Register. Show all posts
Showing posts with label Register. Show all posts

Thursday, May 2, 2013

Access x86 debug register DR0 to DR7

x86 debug register allow access in ring0 or SMM.

On Windows, you may want to write a device driver to run your code
On Linux, you need to write a kernel module to run your code

This sample code sets the DR0 to value 0x4013c8, which is an entry point of a program. It also sets the DR7 to value 0x401, which is to enable local breakpoint of DR0.

Tested code is following:


u32 dr0_RD=0xff;
u32 dr7_RD=0xff;



asm __volatile__ (
"mov %%dr0, %0\n"
"mov %%dr7, %1\n"
:"=r"(dr0_RD), "=r"(dr7_RD)
);
printk("\ndr0_RD is: %x\ndr7_RD is: %x\n", dr0_RD, dr7_RD);


asm __volatile__ (
"movl $0x401, %eax\n"
"movl %eax, %dr7\n"
"movl $0x4013c8, %eax\n"
"movl %eax, %dr0\n"
);

asm __volatile__ (
"mov %%dr0, %0\n"
"mov %%dr7, %1\n"
:"=r"(dr0_RD), "=r"(dr7_RD)
);


printk("\ndr0_RD is: %x\ndr7_RD is: %x\n", dr0_RD, dr7_RD);


Notes about inline gcc assembly

For the block of code in red, I cannot do movl $0x401, %dr4; Additionally, I cannot define a variable u32 dr7 =0x401, and pass it to the inline gcc assembly, "movl %0, %%dr7\n":"=r"(dr7)

Additionally, if there is a paramater passing, all of the register need to use two percent. Otherwise  compile error will generates.

Wednesday, September 21, 2011

Understanding the kernel code, and CR3 register

Recently, I was working on the kernel code and CR3 register. This article is going to record what I have learn.
First Question: How can we get the kernel code of Operating System?
Get Virtual Address of kernel code:
$ cat /boot/System.map-2.6.32-33-generic | grep text
c0100000 T_text
The first one is start virtual address of kernel code

Get Physical Address of kernel code:
$ cat /proc/iomem
00100000-00590de6 : Kernel Code

More info: please see
http://fengweizhang.blogspot.com/2010/12/boot-cat-system.html
http://jianggmulab.blogspot.com/2009/09/blog-post.html

Second Question: How to translate virtual address to physical address? 
Control Register 3 (CR3) stores the base address of Page Directory Table. More info please see page 47 in ULK book. 

Third Question: Which CR3 I should use to translate VA to PA of kernel code?
Any CR3. For each process, it has its own address spaces and CR3. No matter which processes the operating system is running, the virtual address and physical address of kernel code will never change. Although the CR3 is different depends on the running process, same VA will map to same PA by CR3.

Each process has its own address space. From the virtual address point of view, it has some address space at 0-3G region, and it also has some address space at 3-4G region (this is for kernel mode). All Processes get same mappings for the kernel address space (3-4G). Each process also has its own page directory table and page tables. CR3 is the base address of page directory table. The address space at 3-4G region must have its own translation entries in page directory table and page tables. These entries are always same in different page directory table and page tables. 

Process 1 has virtual address space from 0xc0100000-0xc0590de6 (kernel code), translate to physical address is 0x00100000-0x00590de6
Process 2 has virtual address space from 0xc0100000-0xc0590de6 (kernel code), translate to physical address is 0x00100000-0x00590de6

Thus, process 1 and process 2 has same kernel memory mappings. (CR3 is different)