#include #include #include #include static int major; static struct class *demo_class; static struct page *common_page; struct page *drv_vma_nopage( struct vm_area_struct *vma, unsigned long address, int *type ) { printk("drv_vma_nopage( %p, %lx, %p )\n", vma, address, type ); if( (address-vma->vm_start) > 4095 ) return NOPAGE_SIGBUS; get_page( common_page ); if( type ) *type = VM_FAULT_MINOR; return common_page; } static struct vm_operations_struct drv_vma_ops = { .nopage = drv_vma_nopage, }; static int drv_mmap( struct file *instance, struct vm_area_struct *vma ) { printk("drv_mmap(%p, %p)\n", instance, vma); vma->vm_ops = &drv_vma_ops; vma->vm_flags |= VM_RESERVED; return 0; } static struct file_operations fops = { .mmap = drv_mmap, }; static int __init drv_init(void) { int *ptr; if( (major=register_chrdev(0,"mmap",&fops))==0 ) { printk("no major number available\n"); return -EIO; } demo_class = class_create(THIS_MODULE, "demo"); if( IS_ERR(demo_class) ) { printk("no udev support\n"); } else { printk("class_device_create...\n"); class_device_create(demo_class,NULL,MKDEV(major,0),NULL,"mmap"); } common_page = alloc_page( GFP_USER ); if( !common_page ) { if( !IS_ERR(demo_class) ) { class_device_destroy( demo_class, MKDEV(major,0) ); class_destroy( demo_class ); } unregister_chrdev( major, "mmap" ); return -ENOMEM; } ptr = (int *)page_address( common_page ); *ptr = 99; // Nur zur Demonstration! return 0; } static void __exit drv_exit(void) { unregister_chrdev( major, "mmap" ); if( !IS_ERR(demo_class) ) { class_device_destroy( demo_class, MKDEV(major,0) ); class_destroy( demo_class ); } } module_init( drv_init ); module_exit( drv_exit ); MODULE_LICENSE("GPL");