Convert a virtual address to a physical address

Source: Internet
Author: User
1. Page-related data structures and macro definitions
The paging mechanism is the hardware support for paging, which is the hardware basis for virtual memory management. To make this hardware mechanism fully functional, you must have the support of the corresponding software. Let's take a look at some of the main data structures defined in Linux, the page is distributed in the include/asm-i386/directory. h, pgtable. H and pgtable-2level.h in three files.
1. Definition of table items
As described above, table items in PGD, PMD, and PT tables all occupy 4 bytes. Therefore, they are defined as unsigned long integers, pgd_t, pmd_t, and pte_t (Pte is the page table entry. H is defined as follows:
Typedef struct {unsignedlong pte_low;} pte_t;
Typedef struct {unsignedlong PMD;} pmd_t;
Typedef struct {unsigned long PGD;} pgd_t;
Typedefstruct {unsigned long pgprot;} pgprot_t;
It can be seen that Linux does not define long integers for these types but a structure to enable GCC to perform more rigorous type checks during compilation. In addition, several macros are defined to access the components of these structures, which is also an embodiment of Object-oriented thinking:
# Definepte_val (x). pte_low)
# Define pmd_val (x). pMD)
# Define pgd_val (x). PGD)
As shown in Figure 2.13, these table items should be defined as bit segments, but the kernel is not defined as such. Instead, a page protection structure pgprot_t and some macros are defined:
Typedefstruct {unsigned long pgprot;} pgprot_t;
# Definepgprot_val (x). pgprot)
The pgprot value of the field corresponds to the low 12 phase of the table in Figure 2.13, and the nine digits correspond to 0 ~ The corresponding macro is defined in pgtalbe. h:
# DEFINE _ page_present 0 × 001
# DEFINE _ page_rw 0 × 002
# DEFINE _ page_user 0 × 004
# DEFINE _ page_pwt 0 × 008
# DEFINE _ page_pcd 0 × 010
# DEFINE _ page_accessed 0x020
# DEFINE _ page_dirty 0 × 040
# DEFINE _ page_pse 0x080/* 4 MB (or 2 MB) page, Pentium +, if present ..*/
# DEFINE _ page_global 0x100/* Global TLB entry ppro + */
When you read the source code, you can understand that defining a flag as a macro rather than a bit segment is more conducive to encoding.
In addition, the page Directory table and page table are defined in pgtable. h as follows:
Externpgd_t swapper_pg_dir [1024];
Externunsigned long pg0 [2, 1024];
Swapper_pg_dir is a temporary page Directory table, which is statically initialized during kernel compilation. Pg0 is a temporary page table used during initialization.
2. Linear address domain definition

(1) number of digits of page offset
# Define page_shift 12
# Define page_size (1ul
# Include # Include # Include # Include # Include
# Include

Module_license ("GPL ");
Static int PID;
Static unsigned long Va;

Module_param (PID, Int, 0644 );
Module_param (va, ulong, 0644 );

Static int find_pgd_init (void)
{
Unsigned long Pa = 0;
Struct task_struct * pcb_tmp = NULL;
Pgd_t * pgd_tmp = NULL;
Pud_t * pud_tmp = NULL;
Pmd_t * pmd_tmp = NULL;
Pte_t * pte_tmp = NULL;

Printk (kern_info "page_offset = 0x % LX/N", page_offset );
Printk (kern_info "pgdir_shift = % d/N", pgdir_shift );
Printk (kern_info "pud_shift = % d/N", pud_shift );
Printk (kern_info "pmd_shift = % d/N", pmd_shift );
Printk (kern_info "page_shift = % d/N", page_shift );

Printk (kern_info "ptrs_per_pgd = % d/N", ptrs_per_pgd );
Printk (kern_info "ptrs_per_pud = % d/N", ptrs_per_pud );
Printk (kern_info "ptrs_per_pmd = % d/N", ptrs_per_pmd );
Printk (kern_info "ptrs_per_pte = % d/N", ptrs_per_pte );

Printk (kern_info "page_mask = 0x % LX/N", page_mask );

If (! (Pcb_tmp = find_task_by_pid (PID ))){
Printk (kern_info "can't find the task % d./N", pid );
Return 0;
}
Printk (kern_info "PGD = 0x % P/N", pcb_tmp-> MM-> PGD );
/* Determine whether the given address VA is valid (va <vm_end )*/
If (! Find_vma (pcb_tmp-> MM, VA )){
Printk (kern_info "cmd_addr 0x % lx not available./N", VA );
Return 0;
}
Pgd_tmp = pgd_offset (pcb_tmp-> MM, VA );
Printk (kern_info "pgd_tmp = 0x % P/N", pgd_tmp );
Printk (kern_info "pgd_val (* pgd_tmp) = 0x % LX/N", pgd_val (* pgd_tmp ));
If (pgd_none (* pgd_tmp )){
Printk (kern_info "not mapped in PGD./N ");
Return 0;
}
Pud_tmp = pud_offset (pgd_tmp, VA );
Printk (kern_info "pud_tmp = 0x % P/N", pud_tmp );
Printk (kern_info "pud_val (* pud_tmp) = 0x % LX/N", pud_val (* pud_tmp ));
If (pud_none (* pud_tmp )){
Printk (kern_info "not mapped in pud./N ");
Return 0;
}
Pmd_tmp = pmd_offset (pud_tmp, VA );
Printk (kern_info "pmd_tmp = 0x % P/N", pmd_tmp );
Printk (kern_info "pmd_val (* pmd_tmp) = 0x % LX/N", pmd_val (* pmd_tmp ));
If (pmd_none (* pmd_tmp )){
Printk (kern_info "not mapped in PMD./N ");
Return 0;
}
/* Here, change the original pte_offset_map () to pte_offset_kernel */
Pte_tmp = pte_offset_kernel (pmd_tmp, VA );

Printk (kern_info "pte_tmp = 0x % P/N", pte_tmp );
Printk (kern_info "pte_val (* pte_tmp) = 0x % LX/N", pte_val (* pte_tmp ));
If (pte_none (* pte_tmp )){
Printk (kern_info "not mapped in PTE./N ");
Return 0;
}
If (! Pte_present (* pte_tmp )){
Printk (kern_info "PTE not in Ram./N ");
Return 0;
}
Pa = (pte_val (* pte_tmp) & page_mask) | (va &~ Page_mask );
Printk (kern_info "cmd_addr 0x % lx in Ram is 0x % lx./N", VA, PA );
Printk (kern_info "contect in 0x % lx is 0x % LX/N", Pa,
* (Unsigned long *) (char *) PA + page_offset ));

Return 0;

}

Static void find_pgd_exit (void)
{
Printk (kern_info "goodbye! /N ");

}

Module_init (find_pgd_init );
Module_exit (find_pgd_exit );
Test: Open gedit, and then open the task manager. Check that the process ID of gedit is pid = 12749,
Right-click its memory ing and find a valid virtual address Va = 0xb8041000. Then:
Sudo insmod mem. Ko pid = 12749 Va = 0xb8041000

If your kernel is later than 2.6.24, change find_task_by_pid to find_task_by_vpid.
.

Result: pid = 12749 Va = 0xb8041000

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.