//---------------------------------------------------------------- // dos.c // // This character-mode Linux device-driver supports mapping // of the conventional MS-DOS memory areas into user space. // // NOTE: Written and tested w/ Linux kernel version 2.4.21. // // programmer: ALLAN CRUSE // written on: 06 DEC 2003 //---------------------------------------------------------------- #define __KERNEL__ #define MODULE #include // for init_module() #include #include #define SUCCESS 0 static char modname[] = "dos"; static int my_major = 86; static unsigned long mm_base = 0x000000000; static unsigned long mm_size = 0x000110000; static int my_mmap( struct file *file, struct vm_area_struct *vma ) { unsigned long region_length = vma->vm_end - vma->vm_start; unsigned long region_origin = vma->vm_pgoff * PAGE_SIZE; unsigned long phys_address = mm_base + region_origin; unsigned long virt_address = vma->vm_start; // sanity check: mapped region cannot extend beyond device if ( region_origin + region_length > mm_size ) return -EINVAL; // let the kernel know not to try swapping out this region vma->vm_flags |= VM_RESERVED; // tell the kernel to exclude this region from core dumps vma->vm_flags |= VM_IO; if ( io_remap_page_range( virt_address, phys_address, region_length, vma->vm_page_prot ) ) return -EAGAIN; return SUCCESS; } static struct file_operations my_fops = { owner: THIS_MODULE, mmap: my_mmap, }; int init_module( void ) { printk( "<1>\nInstalling \'%s\' module ", modname ); printk( "(major=%d) \n", my_major ); printk( " base=%08X size=%08X \n", mm_base, mm_size ); return register_chrdev( my_major, modname, &my_fops ); } void cleanup_module( void ) { unregister_chrdev( my_major, modname ); printk( "<1>Removing \'%s\' module\n", modname ); } MODULE_LICENSE( "GPL" );