Linux memory-mapped function mmap () function details __ Android

Source: Internet
Author: User
I. Overview memory mapping, in short, is to map a section of memory area of user space to the kernel space, after the successful mapping, user changes to this area of memory can be directly reflected to the kernel space, the same, the kernel space for this section of the changes also directly reflect the user space. The efficiency is very high for both kernel space <----> user space, which requires a large amount of data transfer. The following is a schematic diagram of an area of memory that maps universal files to user space. figure I:
second, the basic function The mmap function is a system call under Unix/linux, and the details can refer to "Unix Netword Programming" Vol. 12.2 section. mmap system calls are not designed entirely for shared memory. It itself provides a different way of accessing normal files, and processes can manipulate normal files like memory. The shared memory IPC for POSIX or System V is purely for shared purposes, and of course mmap () is one of the main applications of shared memory. mmap system calls enable shared memory to be realized by mapping the same common file between processes. After the normal file is mapped to the process address space, the process can access the file like normal memory without having to call read (), write (), and so on. Mmap does not allocate space, but maps files to the address space of the calling process (but takes up your virutal memory), and then you can write files with memcpy and so on without write () . After writing, the contents of the memory are not immediately updated to the file, but there is a time delay, you can call Msync () to explicitly sync, so that you can write content immediately saved to the file. This should be related to the driver. However, by Mmap to write a file this way can not increase the length of the file, because the length of the mapping is called mmap () when the decision. If you want to cancel the memory map, call Munmap () to cancel the memory map
void * Mmap (void *start, size_t length, int prot, int flags, int fd, off_t offset)

mmap is used to map files to memory space, and simply mmap is to make an image of the contents of a file in memory. After the success of the mapping, the user changes to the memory area can be directly reflected to the kernel space, the same, the kernel space changes to this area directly reflect the user space. The efficiency is very high for both kernel space <----> user space, which requires a large amount of data transfer.
Start: The starting address of the memory area to map to, usually null (0). Null indicates that the memory address is specified by the kernel

Length: The size of the memory area to map

Prot: The desired memory protection flag cannot conflict with the open mode of the file. is one of the following values that can be reasonably grouped together by or operation
prot_exec//page content can be executed
prot_read//page content can be  read
prot_write//page can be written
prot_ NONE  //Page not accessible

Flags: Specifies the type of mapping object, whether the mapping options and the mapping page can be shared. Its value can be a combination of one or more of the following bits
map_fixed: With the specified mapping start address, if the memory area specified by the start and Len parameters overlaps the existing mapping space, the overlapping portions are discarded. If the specified starting address is not available, the operation will fail. And the starting address must fall on the page boundary.
map_shared: Write data to the mapped region is copied back to the file, and other processes that map the file are shared.
Map_private: Creates a private mapping of a write-time copy. Memory area writes do not affect the original file. This flag is mutually exclusive with the above flags and only one of them can be used.
Map_denywrite: This flag is ignored.
map_executable: Ditto
Map_noreserve: Do not reserve swap space for this mapping. When the swap space is retained, the modification of the mapping area may be guaranteed. When the swap space is not preserved and the memory is low, modifications to the mapping area can cause an offending signal.
map_locked: Locks the page of the mapping area to prevent the page from being swapped out of memory.
Map_growsdown: For the stack, tell the kernel VM system that the mapping area can be scaled down.
map_anonymous: Anonymous mapping, the mapping area is not associated with any files.
Map_anon:map_anonymous's nickname is no longer used.
Map_file: Compatible flag, ignored.
Map_32bit: The mapping area is ignored when it is specified in the low 2gb,map_fixed of the process address space. The current logo is supported only on the X86-64 platform.
map_populate: Prepares the page table for file mapping by prefetching. Subsequent access to the map area will not be blocked by the page violation.
Map_nonblock: It makes sense only when used with Map_populate. Does not perform prefetching, only creating page table entries for pages that already exist in memory.

FD: File descriptor (returned by the Open function)

Offset: Indicates that the mapped object (that is, the file) starts from there, usually with 0. The value should be an integer multiple of the size page_size

Return Description upon successful execution, mmap () returns a pointer to the mapped area, Munmap () returns 0. On Failure, mmap () returns map_failed[whose value is (void *) -1],munmap returns-1. Errno is set to one of the following values
Eacces: Access error
eagain: File is locked, or too much memory is locked
EBADF:FD is not a valid file descriptor
einval: One or more arguments are invalid
Enfile: The system has reached the limit on open files
enodev: The file system where the specified file resides does not support memory mapping
ENOMEM: Not enough memory, or the process has exceeded the maximum number of memory mappings
eperm: Insufficient power, operation not allowed
Etxtbsy: Opened the file in a written way, specifying the MAP_DENYWRITE flag
SIGSEGV: Trying to write to a read-only area
Sigbus: Trying to access memory areas that are not part of the process

int Munmap (void *start, size_t length)

Start: The starting address of the memory area to be unmapped

Length: The size of the memory area to be unmapped.

Return Description Munmap () returns 0 upon successful execution. Munmap returns -1 upon failure.

changes to the contents of the mapped memory are not immediately updated to the file, but are delayed for a period of time, and you can call Msync () to explicitly synchronize so that your memory updates can be saved to the file immediately .
Start: The starting address of the mapped memory area to be synchronized.
Length: The size of the memory area to be synchronized
flag:flags can be one of the following three values: 
ms_async: Please kernel write the data quickly. 
Ms_sync: Writes the data before the end of Msync is returned. 
ms_invalidate: Let the core decide whether to write, only in special situations

Third, user space and Driver memory mapping 3.1. Basic Process first, the driver allocates a memory first, then the user process through the library function mmap () to tell the kernel how much memory to map to the kernel space, the kernel after a series of function calls to the corresponding driver file_operation specified in the Mmap function, Call Remap_pfn_range () in this function to establish a mapping relationship. 3.2, the realization of the map first, the driver allocates a page-size memory, and then the user process maps the memory in the user space to the page memory on the kernel space by mmap (). After the mapping is complete, the driver writes 10 bytes of data to this memory, and the user process displays the data. Driver:
#include <linux/miscdevice.h> #include <linux/delay.h> #include <linux/kernel.h> #include <linux /module.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux /types.h> #include <linux/delay.h> #include <linux/moduleparam.h> #include <linux/slab.h> #inclu
 De <linux/errno.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/string.h> #include <linux/list.h> #include <linux/pci.h> #include <linux/gpio.h> #define DEVICE_NAME "Myma
 P "Static unsigned char array[10]={0,1,2,3,4,5,6,7,8,9};
 
 
 static unsigned char *buffer;
 static int My_open (struct inode *inode, struct file *file) {return 0;
     static int my_map (struct file *filp, struct vm_area_struct *vma) {unsigned long page;
     unsigned char i;
     unsigned long start = (unsigned long) vma->vm_start; unsigned long end = (unsigned long) vma->vm_end;
 
     unsigned long size = (unsigned long) (Vma->vm_end-vma->vm_start);    
     Get Physical Address page = Virt_to_phys (buffer); Maps a VMA virtual memory area of user space to a contiguous physical page starting with page if (Remap_pfn_range (vma,start,page>>page_shift,size,page_shared))//
 
     The third parameter is the page frame number, from the physical address to the right page_shift get return-1;
     
     Write 10 byte data to this memory for (i=0;i<10;i++) buffer[i] = Array[i];
 return 0; static struct File_operations Dev_fops = {. Owner = This_module,. Open = My_open,. mmap = My
 
 _map,};
 static struct Miscdevice misc = {. minor = Misc_dynamic_minor,. Name = Device_name,. FoPs = &dev_fops,
 
 
 };    
 
     static int __init dev_init (void) {int ret;
     Register Hybrid Device ret = Misc_register (&AMP;MISC);
     Memory allocation buffer = (unsigned char *) kmalloc (Page_size,gfp_kernel);
 
     Set the segment memory to a reserved setpagereserved (virt_to_page (buffer));
 return ret;
} static void __exit dev_exit (void) {//Logoff equipment Misc_deregister (&AMP;MISC);
     Clear retention clearpagereserved (virt_to_page (buffer));
 Free memory kfree (buffer);
 } module_init (Dev_init);
 Module_exit (Dev_exit);
 Module_license ("GPL"); Module_author ("Lkn@scut");

Application:
#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;
     }
 
     Print the first 10 bytes of the mapped memory for
     (i=0;i<10;i++)
         printf ("%d\n", P_map[i]);
     
 
 Here:
     Munmap (P_map, page_size);
     return 0;
 }

after loading the driver to execute the application, the user space is printed as follows:

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.