ldd3 用vm_operations_struct结构中的fault成员代替no_page成员过程

源自:http://blog.csdn.net/nevil/article/details/7718259

关于ldd3的scullv,在编译过程中,主要是vm_operations_struct中现在的kernel中已经没有.nopage这一operation了,其被 fault替换了。下面逐一说明:

(1)main.c中,主要就是就是上一篇文章提到的INIT_WORK, schedule_delayed_work等改变。可以参考逐一改变即可。

(2)在scullv.h中,需要包含头文件<linux/semaphore.h>,否则会提示struct semaphore sem没有定义之类的错误。

(3)关键的改变在mmap.c中,由于vm_operations_struct的变化,需要对mmap.c做如下变化:

a.包含头文件<linux/fs.h>,否则在函数scull_mmap中,会提示

        vma->vm_private_data = filp->private_data;

dereferencing pointer to incomplete type.这是因为其找不到struct file的定义。

b. 以前的函数

        struct page *scullv_vma_nopage(struct vm_area_struct *vma, unsigned long address, int *type)

现在其后面的参数address, type都可以通过结构struct vm_fault来获得。该函数需要改变为:

        static int scullv_vma_fault (struct vm_area_struct *vma, struct vm_fault *vmf)

其函数体也需要作出相应改变:

vm_fault的成员如下:

struct vm_fault {
    unsigned int flags;        /* FAULT_FLAG_xxx flags */
    pgoff_t pgoff;            /* Logical page offset based on vma */
    void __user *virtual_address;    /* Faulting virtual address */

    struct page *page;        /* ->fault handlers should return a
                     * page here, unless VM_FAULT_NOPAGE
                     * is set (which is also implied by
                     * VM_FAULT_ERROR).
                     */
};

[cpp]  view plain copy
  1. static int scullv_vma_fault(struct vm_area_struct *vma,  
  2.                             struct vm_fault *vmf)  
  3. {  
  4.     unsigned long offset;  
  5.     struct scullv_dev *ptr, *dev = vma->vm_private_data;  
  6.         struct page *page;  
  7.     void *pageptr = NULL; /* default to "missing" */  
  8.         pgoff_t pgoff = vmf->pgoff;  
  9.   
  10.     down(&dev->sem);  
  11.     offset = (pgoff << PAGE_SHIFT) + (vma->vm_pgoff << PAGE_SHIFT);  
  12.     if (offset >= dev->size) goto out; /* out of range */  
  13.   
  14.     /* 
  15.      * Now retrieve the scullv device from the list,then the page. 
  16.      * If the device has holes, the process receives a SIGBUS when 
  17.      * accessing the hole. 
  18.     */  
  19.    offset >>= PAGE_SHIFT; /* offset is a number of pages */  
  20.    for (ptr = dev; ptr && offset >= dev->qset;) {  
  21.         ptr = ptr->next;  
  22.         offset -= dev->qset;  
  23.     }  
  24.     if (ptr && ptr->data) pageptr = ptr->data[offset];  
  25.     if (!pageptr) goto out; /* hole or end-of-file */  
  26.   
  27.     /* 
  28.      * After scullv lookup, "page" is now the address of the page 
  29.      * needed by the current process. Since it's a vmalloc address, 
  30.      * turn it into a struct page. 
  31.      */  
  32.      page = vmalloc_to_page(pageptr);  
  33.      if (!page)  
  34.           return VM_FAULT_SIGBUS;  
  35.   
  36.      /* got it, now increment the count */  
  37.      vmf->page = page;  
  38.   
  39. out:  
  40.      up(&dev->sem);  
  41.      return 0;  
  42. }  

c. 在结构scull_vm_ops初始化时:

去掉.nopage = scullv_vma_nopage;

修改为.fault = scullv_vma_fault;


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值