ldd3中scullv模块vm_operations_struct -> nopage到vm_operations_struct ->fault的变换

来源:互联网 发布:成都金域名人酒店小姐 编辑:程序博客网 时间:2024/05/16 11:20

关于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)

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

static int scullv_vma_fault(struct vm_area_struct *vma,                            struct vm_fault *vmf){    unsigned long offset;    struct scullv_dev *ptr, *dev = vma->vm_private_data;        struct page *page;    void *pageptr = NULL; /* default to "missing" */        pgoff_t pgoff = vmf->pgoff;    down(&dev->sem);    offset = (pgoff << PAGE_SHIFT) + (vma->vm_pgoff << PAGE_SHIFT);    if (offset >= dev->size) goto out; /* out of range */    /*     * Now retrieve the scullv device from the list,then the page.     * If the device has holes, the process receives a SIGBUS when     * accessing the hole.    */   offset >>= PAGE_SHIFT; /* offset is a number of pages */   for (ptr = dev; ptr && offset >= dev->qset;) {        ptr = ptr->next;        offset -= dev->qset;    }    if (ptr && ptr->data) pageptr = ptr->data[offset];    if (!pageptr) goto out; /* hole or end-of-file */    /*     * After scullv lookup, "page" is now the address of the page     * needed by the current process. Since it's a vmalloc address,     * turn it into a struct page.     */     page = vmalloc_to_page(pageptr);     if (!page)          return VM_FAULT_SIGBUS;     /* got it, now increment the count */     vmf->page = page;out:     up(&dev->sem);     return 0;}

c. 在结构scull_vm_ops初始化时:

去掉.nopage = scullv_vma_nopage;

修改为.fault = scullv_vma_fault;

原创粉丝点击