当前位置: 技术问答>linux和unix
内核程序会诊 高手请进!!
来源: 互联网 发布时间:2015-05-13
本文导语: 写了一个内核程序,想获得用户空间的虚拟地址所对应的物理地址,但是老是有问题,请大侠们帮忙! 内核:linux 2.4.20 static char * virt_to_phy(struct task_struct * p, struct vm_area_struct *vm, unsigned long addr) { pgd_t...
写了一个内核程序,想获得用户空间的虚拟地址所对应的物理地址,但是老是有问题,请大侠们帮忙!
内核:linux 2.4.20
static char * virt_to_phy(struct task_struct * p,
struct vm_area_struct *vm,
unsigned long addr) {
pgd_t *pgd;
pmd_t *page_middle;
pte_t *pte;
pgd = pgd_offset(p->mm, addr);
page_middle =ckpt_pmd_offset(pgd, addr);
pte = pte_offset_kernel(page_middle,addr);
if (!pte_present(*pte)) {
printk("ERROR: Page for %08lx still not present!n", addr);
return NULL;
}
return (char *)(page_address(pte_page(*pte)) + (addr & ~PAGE_MASK));
经过初步调试 ,好像错误在最后一行。
内核:linux 2.4.20
static char * virt_to_phy(struct task_struct * p,
struct vm_area_struct *vm,
unsigned long addr) {
pgd_t *pgd;
pmd_t *page_middle;
pte_t *pte;
pgd = pgd_offset(p->mm, addr);
page_middle =ckpt_pmd_offset(pgd, addr);
pte = pte_offset_kernel(page_middle,addr);
if (!pte_present(*pte)) {
printk("ERROR: Page for %08lx still not present!n", addr);
return NULL;
}
return (char *)(page_address(pte_page(*pte)) + (addr & ~PAGE_MASK));
经过初步调试 ,好像错误在最后一行。
|
通过找资料,我发现:
1,内核编译时,关于x86cpu 有两种映射方式,他们一宏定义 CONFIG_x86_PAE来区分,是不是你的方法和内核的编译方式相冲突:
(很可能是这种原因,尤其是你改动后能转换一部分,我查了一下原代码,但还不能肯定)
2,pte_offset_kernel() ckpt_pmd_offset()两个函数我从2。4。18和2。4。21中都没有找到,不能确定其运行方式!
可以用pmd_offset和pte_offset 试一下!
3,看过 《Linux内核源代码情景分析》吗,存储管理一章讲得比较清楚,网上有下载的
应该可以解决你的问题了
1,内核编译时,关于x86cpu 有两种映射方式,他们一宏定义 CONFIG_x86_PAE来区分,是不是你的方法和内核的编译方式相冲突:
(很可能是这种原因,尤其是你改动后能转换一部分,我查了一下原代码,但还不能肯定)
2,pte_offset_kernel() ckpt_pmd_offset()两个函数我从2。4。18和2。4。21中都没有找到,不能确定其运行方式!
可以用pmd_offset和pte_offset 试一下!
3,看过 《Linux内核源代码情景分析》吗,存储管理一章讲得比较清楚,网上有下载的
应该可以解决你的问题了
|
是否考虑到有的虚拟地址没有物理地址?