Memory
Linux Memory Management的一些说明
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
ulong phys;
struct page *page;
int temp;
/* First, get physical address of the user buffer page from page table
* of current process. So this routine must run in a process context.
*/
pgd = pgd_offset(current->mm, (unsigned long)virt_addr);
if (pgd_none (*pgd) || pgd_bad (*pgd)) {
IKC_PT_ERR("bad pgd\n");
return -1;
}
pud = pud_offset(pgd,(unsigned long)virt_addr);
if (pud_none(*pud) || pud_bad(*pud)){
IKC_PT_ERR("bad pud\n");
return -1;
}
pmd = pmd_offset(pud, (unsigned long)virt_addr);
if (pmd_none (*pmd) || pmd_bad (*pmd)) {
IKC_PT_ERR("bad pmd\n");
return -1;
}
pte = pte_offset_kernel(pmd, (unsigned long)virt_addr);
if (pte_none (*pte)) {
IKC_PT_ERR("bad pte va: %p pte: %p pteval: %p\n",
virt_addr, pte, pte_val(*pte));
return -1;
}
IKC_PT_DBG("pgd:%p pte:%p *pte:%p val:%08x\n",pgd,pte,*pte,pte_val(*pte));
while (!pte_present (*pte)) {
/* this page is not present, refresh it by read it */
IKC_PT_DBG("pte not present!\n");
temp = *(int *)(page);
}
IKC_PT_DBG("pte ok now!\n");
/* The following code to lock the user buffer page */
page = pte_page(*pte);
if (PageReserved(page)) {
IKC_PT_ERR("trying to register a mapping of a reserved memory area\n");
return -1;
}
if (PageLocked(page)) {
IKC_PT_ERR("trying to re-lock a locked memory page\n");
return -1;
}
if (page_count(page) < 1) {
IKC_PT_ERR("trying to register a page with count %d\n",
page_count(page));
return -1;
}
SetPageLocked(page);
get_page(page);
phys = __pa(page_address(page));
IKC_PT_DBG("phys is 0x%p\n",phys);
IKC_PT_DBG("pinu_page Ok\n");
return 0;