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
How to Fix Permission Denied for .Git/ Directory When Performing Git Push
How to Convert String to Number in Gnuplot
How to Write Linux Driver Module Call/Use Another Driver Module
Selecting the Right Linux I/O Scheduler for a Host Equipped with Nvme Ssd
How to Look Up a Variable by Name with #!/Bin/Sh (Posix Sh)
How to Run Dos2Unix on an Entire Directory
How to See Top Processes Sorted by Actual Memory Usage
Undefined Reference to 'Clock_Gettime' Although '-Lrt' Is Given
How Were the Weightings in the Linux Load Computation Chosen
Does Gcc, Icc, or Microsoft's C/C++ Compiler Support or Know Anything About Numa
Stripping Single and Double Quotes in a String Using Bash/Standard Linux Commands Only
Understanding Bash Short-Circuiting
Bash File Is Running Fine in Windows for Testng But It Is Not Working in Linux/Mac
Language-Agnostic Properly-Tabbing Code Editors for Linux
Linux Perf Reporting Cache Misses for Unexpected Instruction
How to Add Date String to Each Line of a Continuously Written Log File
How to Run a Docker Container in Aws Elastic Beanstalk with Non-Default Run Parameters