- 论坛徽章:
- 0
|
本帖最后由 wzw200 于 2014-06-03 17:58 编辑
在学习 LDD3的MMAP nopage_fault 函数,看的是头痛,
其中地址计算 看的头痛,不解,我下面的问题一个老帖子也发过,最中也没有得到结论,
struct vm_area_struct *vma 成员 vm_pgoff 是相对文件的 偏移,怎么计算着就成了 物理地址呢?
新的内核 有个vm_fault *vmf变量,vmf->pgoff成员 差不多,想不通,这应该文件的偏移地址,- int simple_vma_nopage(struct vm_area_struct *vma,struct vm_fault *vmf)
- {
- struct page *pageptr;
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- unsigned long physaddr = (unsigned long)vmf->virtual_address - vma->vm_start + offset;
- unsigned long pageframe = physaddr >> PAGE_SHIFT;
- // Eventually remove these printks
- printk (KERN_NOTICE "---- Nopage, off %lx phys %lx,vm_pgoff:%lx\n", offset, physaddr,vma->vm_pgoff);
- printk (KERN_NOTICE "VA is %p\n", __va (physaddr));
- printk (KERN_NOTICE "Page at %p\n", virt_to_page (__va (physaddr)));
- if (!pfn_valid(pageframe))
- return 0;
- pageptr = pfn_to_page(pageframe);
- printk (KERN_NOTICE "page->index = %ld mapping %p\n", pageptr->index, pageptr->mapping);
- printk (KERN_NOTICE "Page frame %ld\n", pageframe);
- get_page(pageptr);
- // if (type)
- // *type = VM_FAULT_MINOR;
- return VM_FAULT_NOPAGE;
- }
复制代码 别人说这个 vma->vm_pgoff是页帧号,
offset = vma->vm_pgoff << PAGE_SHIFT就得出了那一页的物理地址,
刚好 hysaddr = (unsigned long)vmf->virtual_address - vma->vm_start + offset;得到了 virtual_address对应的物理地址,如果 vma->vm_pgoff是页帧号那么还要 pageframe变量
做什么呢,如果 vma->vm_pgoff是文件偏移,那后面的变量怎么就计算出来了呢!相不通
- [size=3][size=4]#define SHARE_MEM_SIZE (PAGE_SIZE * 2)
- static char *sh_mem = NULL;
- static int nopage_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
- {
- struct page *page;
- void *kernel_vaddr = NULL;
- if ((NULL == vma) || (NULL == sh_mem))
- {
- return VM_FAULT_SIGBUS;
- }
- if ((vmf->pgoff <<PAGE_SHIFT) > SHARE_MEM_SIZE)
- {
- return VM_FAULT_SIGBUS;
- }
- kernel_vaddr = sh_mem + (vmf->pgoff << PAGE_SHIFT);
- page = virt_to_page(kernel_vaddr);
- get_page(page);//获得页,实际是增加页的使用计数
- vmf->page = page;
- return 0;
- }
- static int nopage_init(void)
- {
- sh_mem = kmalloc(SHARE_MEM_SIZE, GFP_KERNEL);
- }[/size][/size]
复制代码 这是我在网上查的一个例子,用的新版本内核,他的计算好像 vmf->pgoff 文件偏移 + sh_mem 刚好是 kernel_vaddr
|
|