#include #include #include #include #include #include struct file_operations fops ; static int major ; static int my_open(struct inode *inode, struct file *file) { int i ; void *data_ptr ; struct page *page ; printk("I am in my_open\n") ; data_ptr = (void *) __get_free_pages(GFP_KERNEL, 4) ; if (data_ptr == NULL) { printk("__get_free_pages failed\n") ; return -1 ; } else { printk("__get_free_pages successful data_ptr = %ld\n", (unsigned long)data_ptr) ; } for (i = 0 ; i < 16 ; i++) { page = virt_to_page(data_ptr + PAGE_SIZE * i) ; set_bit(PG_reserved, &page->flags) ; } strcpy((char *)data_ptr, "HelloWorld") ; file->private_data = data_ptr ; return 0 ; } static int my_close(struct inode *inode, struct file *file) { int i ; struct page *page ; unsigned long data_ptr = (unsigned long)file->private_data ; printk("I am in my_close\n") ; printk("%s data_ptr = %ld\n", (char *)data_ptr, data_ptr) ; for (i = 0 ; i < 16 ; i++) { page = virt_to_page(data_ptr + PAGE_SIZE * i) ; clear_bit(PG_reserved, &page->flags) ; } free_pages(data_ptr, 4) ; return 0 ; } static int my_mmap(struct file *file, struct vm_area_struct *vma) { void *data_ptr = (void *)file->private_data ; printk("I am in my_mmap\n") ; printk("data_ptr = %ld\n", (unsigned long) data_ptr) ; if (remap_page_range(vma, vma->vm_start, virt_to_phys(data_ptr), (vma->vm_end - vma->vm_start), vma->vm_page_prot)) { printk("remap_page_range failed\n") ; return -1 ; } return 0 ; } int init_module(void) { printk("I am in init_module\n") ; major = register_chrdev(0, "mydriver", &fops) ; if(major == -1) { printk("register_chrdev failed\n") ; return -1 ; } printk("module is registered with major no = %d\n", major) ; return 0 ; } void cleanup_module(void) { printk("I am in cleanup_module\n") ; unregister_chrdev(major, "mydriver") ; } struct file_operations fops = { .open = my_open, .release = my_close, .mmap = my_mmap, } ;