About mmap () function of the user and drive a little summary

About mmap () function of the user and drive a little summary

 

Introduction: the memory map, in a nutshell is to map the region of memory user space to kernel space, the mapping is successful, the user can modify this memory area is reflected directly into the kernel space, the same kernel space to this area modifications are a direct reflection of user space. Then for kernel space <----> requires user space therebetween large, then the operation efficiency data transmission is very high.

The following is a diagram of a general mapping file to the memory area of the user space.
Figure 1:

User space:

mmap function is a UNIX / Linux system calls in, details refer to "Unix Netword programming" Volume II 12.2.
In order for the shared memory is not entirely designed mmap system call. It itself provides a way different from the general access to common files, the process can be like memory read and write operations on a regular file. Or Posix and System V IPC shared memory is used solely for the purpose of sharing, of course, mmap () shared memory is one of its main applications.
mmap system call allows processes between shared memory by mapping with a common file. After the general file is mapped into the process address space, the process can be as accessible as normal memory access to files, do not have to call the read (), write () and so on. mmap not allocate space, just to map the file into the address space of the calling process's (but it will takes up your virutal memory), then you can write file operations such as memcpy instead of write () a. After writing, the contents of memory and not immediately update to the file, but there is a delay, you can call msync () explicitly synchronize it, so that you will be able to save what is written immediately to the file. this It should be relevant and drive. But to write in this way by mmap file can not increase the length of the file, because the length of time to be mapped in a call to mmap () of the decision. If you want to cancel a memory-mapped, you can call munmap () to cancel the memory mapping

[cpp] view plain copy

  1. void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset)  



mmap is used to map the file into memory space, simply mmap contents of a file is to do an in-memory image inside. After the mapping is successful, the user can modify this memory area is reflected directly into the kernel space, likewise, to modify the kernel space of this region is also a direct reflection of user space. Then for kernel space <----> requires user space therebetween large, then the operation efficiency data transmission is very high.
start: start address to be mapped to a memory area, usually with a NULL (NULL is, 0). NULL means the kernel is specified by the memory address 

length: to be mapped memory area the size of 
prot: the desired memory protection flags, can not conflict with the open mode of the file. Is one of the following values may reasonably be combined by calculation or 
PROT_EXEC // page content may be performed 
PROT_READ // pages may be read 
PROT_WRITE // pages may be written 
PROT_NONE // non-accessible page 
flags: Specifies type mapping object, mapping options and whether the map page can be shared. Its value may be one or more of the following bit combination 
MAP_FIXED: mapping using the specified start address, if specified by the start and len parameters in the memory area overlapping the existing mapping space, the overlapped portion will be discarded. If the specified start address is not available, the operation will fail. And the starting address must fall on the border of the page. 
MAP_SHARED: write data to the mapped region will be copied back inside files, but also allows other processes mapping the file sharing. 
MAP_PRIVATE: establish a written copy when private mapping. Write memory area will not affect the original file. This flag and the flags above are mutually exclusive and can only use one of them.
MAP_DENYWRITE: This flag is ignored. 
MAP_EXECUTABLE: ditto 
MAP_NORESERVE: Do not leave space for the exchange of maps. When swap space is reserved to modify the mapping area could be guaranteed. When swap space is not reserved, and out of memory, changes to the mapped region will cause a segmentation violation signal. 
MAP_LOCKED: Lock the page mapping area, thereby preventing the page is swapped out of memory. 
MAP_GROWSDOWN: for the stack, to tell the kernel VM system, mapping area can be extended downward. 
MAP_ANONYMOUS: anonymous mapping, mapping area not associated with any file. 
MAP_ANON: MAP_ANONYMOUS another name, no longer in use. 
MAP_FILE: compatible flag is ignored. 
MAP_32BIT: mapping the area on the lower 2GB of the process address space will be ignored when MAP_FIXED specified. This flag is currently only supported on x86-64 platform. 
MAP_POPULATE: ready for the file mapping page table read-ahead by the way. Subsequent access mapping zones will not be blocked pages violation. 
MAP_NONBLOCK: MAP_POPULATE and when used with the only meaningful. Do not read ahead, build page table entry only for pages that already exists in memory. 

fd: file descriptor (returned by the open function) 

offset: represents a mapping object (i.e., files) enantiomer from there, often with zeros. This value should be an integer multiple of a size of PAGE_SIZE 

return instructions 
when executed successfully, mmap () returns a pointer to the mapped region, munmap () returns 0. Failure, mmap () Returns MAP_FAILED [a value (void *) - 1], munmap -1. errno is set to one of the following values 
EACCES: Access error 
EAGAIN: file is locked, or too much memory has been locked 
EBADF: fd is not a valid file descriptor 
EINVAL: one or more parameters are invalid 
ENFILE: The system has reached the limit of open files 
ENODEV: Specifies the file where the file system It does not support memory mapping 
ENOMEM: Out of memory, or process have exceeded the maximum number of memory-mapped 
EPERM: lack of power, operation is not allowed 
ETXTBSY: open the file has been written, specifying MAP_DENYWRITE flag 
SIGSEGV: try to write to a read-only area 
SIGBUS: try to access the memory area is not part of the process 
 

[cpp] view plain copy

  1. int munmap(void *start, size_t length)   

start: starting address you want to cancel mapped memory area 
length: To cancel the memory size of the map area. 
Returning to the description 
munmap successful execution () returns 0. Munmap return on failure -1.
Int msync (const void * Start, size_t length, int flags); 

changes to the contents of the memory map does not update the file immediately, but there is a delay, you can call msync () explicitly synchronize it, so you can save memory update file immediately to
start: to start address of the memory region mapped synchronized. 
length: memory size of the area to be synchronized 
flag: flags can be one of three values: 
MS_ASYNC: Please Kernel soon to write data. 
MS_SYNC: msync return before the end of the write data. 
MS_INVALIDATE: let the heart decide whether written, used only in special circumstances

Drive space:

3.1, the basic process
first of all, for some drivers allocate memory, then the user through the process of library function mmap () to tell the kernel how much memory you want mapped to kernel space, the kernel calls after a series of function calls the corresponding driver file_operation specified in the mmap function, call remap_pfn_range in the function () to establish the mapping.
3.2, maps the
first in the driver allocates an amount of memory, then the user process by mmap () the user space memory page size is also mapped to kernel space memory this page. After the mapping is done, this driver is to write 10 bytes of data memory, the user process will display the data out.
driver:
 

[cpp] view plain copy

  1. #include <linux/miscdevice.h>   
  2. #include <linux/delay.h>   
  3. #include <linux/kernel.h>   
  4. #include <linux/module.h>   
  5. #include <linux/init.h>   
  6. #include <linux/mm.h>   
  7. #include <linux/fs.h>   
  8. #include <linux/types.h>   
  9. #include <linux/delay.h>   
  10. #include <linux/moduleparam.h>   
  11. #include <linux/slab.h>   
  12. #include <linux/errno.h>   
  13. #include <linux/ioctl.h>   
  14. #include <linux/cdev.h>   
  15. #include <linux/string.h>   
  16. #include <linux/list.h>   
  17. #include <linux/pci.h>   
  18. #include <linux/gpio.h>   
  19.   
  20.   
  21. #define DEVICE_NAME "mymap"   
  22.   
  23.   
  24. static unsigned char array[10]={0,1,2,3,4,5,6,7,8,9};   
  25. static unsigned char *buffer;   
  26.   
  27.   
  28. static int my_open(struct inode *inode, struct file *file)   
  29. {   
  30. return 0;   
  31. }   
  32.   
  33.   
  34. static int my_map(struct file *filp, struct vm_area_struct *vma)   
  35. {   
  36. unsigned long page;   
  37. unsigned char i;   
  38. unsigned long start = (unsigned long)vma->vm_start;   
  39. //unsigned long end = (unsigned long)vma->vm_end;   
  40. unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start);   
  41.   
  42. // get the physical address   
  43. page = virt_to_phys(buffer);   
  44. // to map a virtual memory area vma user space to the period of continuous physical page to page beginning   
  45. IF (of remap_pfn_range (VMA, Start, Page >> PAGE_SHIFT, size, PAGE_SHARED)) // The third parameter is the page frame number obtained by the physical address right PAGE_SHIFT   
  46. return -1;   
  47.   
  48. // write to the memory 10 bytes of data   
  49. for(i=0;i<10;i++)   
  50. buffer[i] = array[i];   
  51.   
  52. return 0;   
  53. }   
  54.   
  55.   
  56. static struct file_operations dev_fops = {   
  57. .owner = THIS_MODULE,   
  58. .open = my_open,   
  59. .mmap = my_map,   
  60. };   
  61.   
  62. static struct miscdevice misc = {   
  63. .minor = MISC_DYNAMIC_MINOR,   
  64. .name = DEVICE_NAME,   
  65. .fops = &dev_fops,   
  66. };   
  67.   
  68.   
  69. static int __init dev_init(void)   
  70. {   
  71. an int  Ret;   
  72.   
  73. // Register hybrid device   
  74. ret = misc_register(&misc);   
  75. // memory allocation   
  76. buffer = (unsigned char *)kmalloc(PAGE_SIZE,GFP_KERNEL);   
  77. // set the memory segment reserved   
  78. SetPageReserved(virt_to_page(buffer));   
  79.   
  80. Return  the right;   
  81. }   
  82.   
  83.   
  84. static void __exit dev_exit(void)   
  85. {   
  86. // write-off equipment   
  87. misc_deregister(&misc);   
  88. // clear reservations   
  89. ClearPageReserved(virt_to_page(buffer));   
  90. // release memory   
  91. kfree(buffer);   
  92. }   
  93.   
  94.   
  95. module_init(dev_init);   
  96. module_exit(dev_exit);   
  97. MODULE_LICENSE("GPL");   
  98. MODULE_AUTHOR("LKN@SCUT");   

 

 

Application examples:

#include <unistd.h> 

#include <stdio.h> 

#include <stdlib.h> 

#include <string.h> 

#include <fcntl.h> 

#include <linux/fb.h> 

#include <sys/mman.h> 

#include <sys/ioctl.h> 

 

#define PAGE_SIZE 4096 

 

 

int main(int argc , char *argv[]) 

int fd; 

int i; 

unsigned char *p_map; 

 

// Open device 

fd = open("/dev/mymap",O_RDWR); 

if(fd < 0) 

printf("open fail\n"); 

exit(1); 

 

// memory map 

p_map = (unsigned char *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0); 

if(p_map == MAP_FAILED) 

printf("mmap fail\n"); 

goto here; 

 

10 bytes before the contents of the memory map is printed // 

for(i=0;i<10;i++) 

printf("%d\n",p_map[i]); 

 

 

here: 

munmap(p_map, PAGE_SIZE); 

return 0; 

Guess you like

Origin blog.csdn.net/ll148305879/article/details/94456254