The "abstract" kernel-to-user-space address mapping in Linux allows the user-level application to directly access the kernel address, which is the Mmap method. The application can directly access the device's I/O storage or DMA buffers through memory mapping. A Memory map associates a segment of the user space with the device's memory, and the program reads or writes within the mapped address range, which is actually access to the device.
struct file_operations simple_fops = { .owner = THIS_MODULE, .open = simple_open, .mmap = simple_mmap,// mmap接口 .release = simple_release, };
Allocate memory at initialization time:
buffer = Kmalloc (4096 , Gfp_kernel); PRINTK ( "mmap buffer =%p\n" , buffer); Buffer_area= (int *) (((unsigned long ) buffer + page_size-1 ) & Page_mask); for (Virt_addr= (unsigned long ) Buffer_area; virt_ addr< (unsigned long ) Buffer_area+4096 ; Virt_addr+=page_size) {setpagereserved (Virt_to_page (VIRT_ADDR)); /* Configure the page to hold */} memset (Buffer, ' C ' , 100 ); //initialized to ' C '
The Simple_mmap function implements the Mmap file interface:
staticint simple_mmap(structstruct vm_area_struct *vma) { int ret; ret = remap_pfn_range(vma, vma->vm_start, virt_to_phys((void*)((unsignedlong)kmalloc_area)) >> PAGE_SHIFT, vma->vm_end-vma->vm_start, PAGE_SHARED); if0) { return -EAGAIN; } return0; }
The test program reference code is as follows:
intMain (void) {intFd Char*addr=null; FD =Open("/dev/mmap", O_RDWR);if(FD <0) {perror ("Open");Exit(1); } addr = Mmap (NULL,4096, prot_read| Prot_write, map_shared, FD,0);if(addr = = map_failed) {Perror ("Mmap");Exit(1); }printf('%s\ n ', addr); memset (addr,' F ', -); addr[0]=' P ';printf('%s\ n ', addr); Munmap (addr,4096); Addr=null;Close(FD); FD =Open("/dev/mmap", O_RDWR);//Re-open for verificationif(FD <0) {perror ("Open");Exit(1); } addr = Mmap (NULL,4096, prot_read| Prot_write, map_shared, FD,0);if(addr = = map_failed) {Perror ("Mmap");Exit(1); }printf('%s\ n ', addr); Munmap (addr,4096);Close(FD);return(0); }
The results of the operation are as follows:
[[email protected]/home]#insmod demo.ko mmap buffer = c3c82000 [[email protected]/home]#mknod /dev/mmap c 224 0 [[email protected]/home]#./read CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC pfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff pfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Kernel-state space address directly mapped to user-state space access