- 论坛徽章:
- 0
|
在kernelnewbies 邮件列表上看到的一个帖子。
In this module, i want to get the phy address for kmalloc() through page table. i think the phy address of kmalloc() is __pa(va), but when i use page
table, it does not seem the same. May be i am not fully understand the principle. Is any one can help me about this program?
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <linux/highmem.h>
#include <asm/kmap_types.h>
MODULE_LICENSE("GPL");
u32 ka = 0;
static int find_phy_init(void)
{
printk(KERN_ALERT "Hello in\n");
u32 kpa = 0;
pgd_t *k_pgd = NULL;
pud_t *k_pud = NULL;
pmd_t *k_pmd = NULL;
pte_t *k_pte = NULL;
ka = (u32)kmalloc(4096, GFP_KERNEL);
if(!ka)
{
printk(KERN_ALERT "kmalloc failed\n");
return 0;
}
memset(ka, 0x5a, 4096);
printk(KERN_ALERT "ka = 0x%08x\n", ka);
/* kmalloc */
k_pgd = pgd_offset_k(ka);
printk(KERN_ALERT "k_pgd = 0x%p, *k_pgd = 0x%08x\n", (u32)k_pgd, *k_pgd);
if(!pgd_none(*k_pgd))
{
k_pud = pud_offset(k_pgd, ka);
if(!pud_none(*k_pud))
{
k_pmd = pmd_offset(k_pud, ka);
printk(KERN_ALERT "k_pmd = 0x%08x, *k_pmd = 0x%08x\n", (u32)k_pmd, *k_pmd);
if(!pmd_none(*k_pmd))
{
k_pte = pte_offset_kernel(k_pmd, ka);
printk(KERN_ALERT "k_pte = 0x%08x, *k_pte = 0x%08x\n", (u32)k_pte, *k_pte);
if(!pte_none(*k_pte))
{
kpa = (pte_val(*k_pte) & PAGE_MASK) |
(ka & ~PAGE_MASK);
if(!pte_present(*k_pte))
printk(KERN_ALERT "k-page not in RAM\n");
}
else
printk(KERN_ALERT "pte is none\n");
}
}
}
if(kpa != 0)
{
printk(KERN_ALERT "k_addr 0x%08x in RAM is 0x%08x\n", ka, kpa);
printk(KERN_ALERT "__pa(k_addr) = 0x%08x\n", __pa(ka));
}
kfree((void *)ka);
return 0;
}
static void find_phy_exit(void)
{
printk(KERN_ALERT "Exit!\n");
}
module_init(find_phy_init);
module_exit(find_phy_exit); |
|