커널 모듈 (2.6.32-358.el6.x86_64)에서 프로세스의 가상 메모리에 매핑 된 모든 물리적 주소를 인쇄하고 싶습니다. 주어진 task->mm
, 나는 struct page
다음과 같이 프로세스를 횡단하려고 시도 합니다.
int i, j, k, l;
for (i = 0; i < PTRS_PER_PGD; ++i)
{
pgd_t *pgd = mm->pgd + i;
if (pgd_none(*pgd) || pgd_bad(*pgd))
continue;
for (j = 0; j < PTRS_PER_PUD; ++j)
{
pud_t *pud = (pud_t *)pgd_page_vaddr(*pgd) + j;
if (pud_none(*pud) || pud_bad(*pud))
continue;
for (k = 0; k < PTRS_PER_PMD; ++k)
{
pmd_t *pmd = (pmd_t *)pud_page_vaddr(*pud) + k;
if (pmd_none(*pmd) || pmd_bad(*pmd))
continue;
for (l = 0; l < PTRS_PER_PTE; ++l)
{
pte_t *pte = (pte_t *)pmd_page_vaddr(*pmd) + l;
if (!pte || pte_none(*pte))
continue;
struct page *p = pte_page(*pte);
unsigned long phys = page_to_phys(p);
printk(KERN_NOTICE "addr %lx", phys);
}
}
}
}
출력이 약간 이상해 보이므로 (특히 일련의 동일한 주소가 있음) 이론적으로 위의 내용이 올바른지 묻고 싶습니다.
더 나은 접근 방식은 프로세스의 VMA를 탐색하고 페이지 디렉터리를 통해 각 VMA를 물리적 페이지 / 주소로 변환하는 것입니다.
struct vm_area_struct *vma = 0;
unsigned long vpage;
if (task->mm && task->mm->mmap)
for (vma = task->mm->mmap; vma; vma = vma->vm_next)
for (vpage = vma->vm_start; vpage < vma->vm_end; vpage += PAGE_SIZE)
unsigned long phys = virt2phys(task->mm, vpage);
//...
어디 virt2phys
같을 것이다 :
//...
pgd_t *pgd = pgd_offset(mm, virt);
if (pgd_none(*pgd) || pgd_bad(*pgd))
return 0;
pud = pud_offset(pgd, virt);
if (pud_none(*pud) || pud_bad(*pud))
return 0;
pmd = pmd_offset(pud, virt);
if (pmd_none(*pmd) || pmd_bad(*pmd))
return 0;
if (!(pte = pte_offset_map(pmd, virt)))
return 0;
if (!(page = pte_page(*pte)))
return 0;
phys = page_to_phys(page);
pte_unmap(pte);
return phys;
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다