How to Get the Physical Address from the Logical One in a Linux Kernel Module

How to get the physical address from the logical one in a Linux kernel module?

Well, it might looks as something like that (follow PTE from an virtual address):

void follow_pte(struct mm_struct * mm, unsigned long address, pte_t * entry)
{
pgd_t * pgd = pgd_offset(mm, address);

printk("follow_pte() for %lx\n", address);

entry->pte = 0;
if (!pgd_none(*pgd) && !pgd_bad(*pgd)) {
pud_t * pud = pud_offset(pgd, address);
struct vm_area_struct * vma = find_vma(mm, address);

printk(" pgd = %lx\n", pgd_val(*pgd));

if (pud_none(*pud)) {
printk(" pud = empty\n");
return;
}
if (pud_huge(*pud) && vma->vm_flags & VM_HUGETLB) {
entry->pte = pud_val(*pud);
printk(" pud = huge\n");
return;
}

if (!pud_bad(*pud)) {
pmd_t * pmd = pmd_offset(pud, address);

printk(" pud = %lx\n", pud_val(*pud));

if (pmd_none(*pmd)) {
printk(" pmd = empty\n");
return;
}
if (pmd_huge(*pmd) && vma->vm_flags & VM_HUGETLB) {
entry->pte = pmd_val(*pmd);
printk(" pmd = huge\n");
return;
}
if (pmd_trans_huge(*pmd)) {
entry->pte = pmd_val(*pmd);
printk(" pmd = trans_huge\n");
return;
}
if (!pmd_bad(*pmd)) {
pte_t * pte = pte_offset_map(pmd, address);

printk(" pmd = %lx\n", pmd_val(*pmd));

if (!pte_none(*pte)) {
entry->pte = pte_val(*pte);
printk(" pte = %lx\n", pte_val(*pte));
} else {
printk(" pte = empty\n");
}
pte_unmap(pte);
}
}
}
}

How to find physical and logical core number in a kernel module?

Have a look at the end of include/linux/smp.h: smp_processor_id()
gives you the number of the current executing CPU. get_cpu() will do
the same and will also disable preemption so that you will stay on
that CPU until put_cpu() is called.

From user-space, you can use sched_getcpu() or getcpu() to obtain the same information.

Which implementation to get memory with it's physical address is correct?

if(1) is right.

Here are quotes about linux kernel addressing types from chapter 15 of LDD3 book:

Kernel logical addresses
These make up the normal address space of the kernel. These addresses map some portion (perhaps all) of main memory and are often treated as if they were physical addresses. On most architectures, logical addresses and their associated physical addresses differ only by a constant offset. ... Memory returned from kmalloc has a kernel logical address.

Kernel virtual addresses
Kernel virtual addresses are similar to logical addresses in that they are a map- ping from a kernel-space address to a physical address. Kernel virtual addresses do not necessarily have the linear, one-to-one mapping to physical addresses that characterize the logical address space, however. All logical addresses are kernel virtual addresses, but many kernel virtual addresses are not logical addresses.



Related Topics



Leave a reply



Submit