MMAP

Linux Device driver MMAP()

We have Discussed Architecture of Linux Operating System (==>) in our previous Linux Device Tutorials . Now You must be knowing that every device in Linux operating system is represented as a Device file . This device file is just like the other files which can be accessed by using file descriptors. Different application which are running in user space might need to access different devices for their own specific purpose. For example camera application will need to access Camera sensor for many things.

Linux Kernel provides various ways of accessing the devices from user space. One way of sending and receiving data to and from user space is by using copy_to_user() and copy_from_user() system calls respectively. We have already seen usage of both these system call in writing a simple driver tutorial(==>). Both of these system calls comes with some extra over head. One overhead is that you have to allocate a buffer in user space buffer also with the kernel buffer. Which is just wastage of extra memory. To overcome these limitations Linux kernel provides a way of mapping the device to some user space address . Mapping a Device means associating a range of user space address to device memory. Whenever the program reads or write in the assigned address range , it is actually accessing the device .

linux-mmap

Linux Kernel provides mmap system calls for mapping a device file to user space address range. Lets first understand mmap system call prototype and argument then we will understand mmap usage.

Calls to mmap asks kernel to map len bytes of device represented by the fd , starting at offset bytes into the file , into memory. Below is the prototype of mmap()

void *mmap(void *addr,size_t len, int prot, int flags , int fd, off_t offset );

addr:- Requesting to kernel for starting mapping from this address addr. If address addr is not being used for any other purpose the Linux Kernel start mapping from given address otherwise it will find other available address and return the address as a result of call. If addr value is 0 then you are asking kernel to give any random address.

len:- len is the number of bytes of device need to be mapped.

prot :- this parameter describe the desired memory protection of mapping. Linux kernel provides various pre defined values for this parameters Two most used values are PROT_READ and PROT_WRITE.

PROT_READ:- The pages of memory can be read.

PROT_WRITE:- The pages may be overwritten .

You can know about more flags at http://linux.die.net/man/2/mmap .

flags:- This parameters specifies that any updates to the mapped memory should be visible to other processed mapping the same memory region or not. Various values are defined by Linux kernel for this flags . Below are these values

MAP_SHARED:- This flag value specify to share the mapping with other processes . It means any updates to mapped region of memory will also be visible to other processes that map this file.

MAP_PRIVATE:- Any updates to mapped memory is not visible to other processes mapping the same device or file.

For more flag you can refer http://linux.die.net/man/2/mmap ..

fd:- fd is the file descriptor of the file which needs to be mapped .

offset:- offset in the file from where mapping of file will start.

Please note mmap system call operates on Page basis. hence addr and offset must be aligned as multiple of page size. If the file size is not multiple of page size then remaining memory is zeroed when mapped .

Return Value:-

on success, mmap() returns a pointer to the mapped area. On error MAP_FAILED is returned.

Linux mmap performance

There are various benefits of using mmap as compared to standard read() and write() calls.

1) Reading from and writing to file mapped memory doesn’t need any extra memory buffer but in case of standard read and write we need some extra memory for writing to   and reading from user space.

2) It doesn’t include any context witch overhead.

3) mapping a device can be used by multiple process sharing same device .

With the various advantages MMAP also has some limitation

1) If you need to map very large file then it’s very difficult to find contiguous memory available for that size.

2) As this mapping is aligned with page because of this memory can have fragmentation issue.

munmap()

munmap is a linux system call which is used remove the mapping of device which we did by using of mmap system call. below is the prototype of munmap()

int munmap (void *addr, size_t len);

munmap removes the mapped pages located in memory from address specified by addr till length len. If any call made to access the mapping which has been already removed by munmap will cause SIGSEGV signal.

on success munmap() return 0 and on failure it returns -1 and error no is set accordingly.

Linux mmap usage example

As mmap in Linux Kernel is very efficient and easy to use so its obvious to use it heavily in Linux device drivers . Linux Device Drivers generally implement mmap function for providing facility to user space applications to access the device memory. Drivers contain mmap system in the file_operations(==>) structure and and is invoked when mmap system call is used by any application.

struct file_operations my_fops = {

read   :       my_read,

write   :       my_write,

open   :       my_open,

release :       my_close,

mmap   :        my_mmap,

owner   :       THIS_MODULE,

};

Now Let’s understand Linux mmap usage by writing a simple example. Below is the simple C program which open /dev/mem device and map this device in user space memory by using mmap system call. After mapping device we get pointer to the mapped memory in character pointer data.

By using of this character pointer we can read the data of /dev/mem device. /dev/mem device represents our system main memory. We no need to write driver from ourselves as its already built-in. Please note while accessing the /dev/mem we should not try to write in /dev/mem device as it may corrupt our system memory and can cause system crash. So we should be careful while accessing system memory.

===========================================================================

 mmap_test.c

#include<stdio.h>

#include<fcntl.h>

#include<unistd.h>

#include<sys/types.h>

#include<sys/mman.h>

int main()

{

 

int fd;

char *data;

 

printf(“starting of program\n”);

fd=open(“/dev/mem”,O_RDWR);

if(fd<0)

printf(“device not opened\n”);

data=mmap(NULL,0x100,PROT_WRITE|PROT_READ,MAP_SHARED,fd,0);

printf(“%p\n”,data);

printf(“%c\n”,data[0]);

printf(“%c\n”,data[1]);

close(fd);

}

===========================================================================

 

above c program can be compiled in the same way as we compiled other c programs.

mmap-1

after execution of above c example we can see some random data printed by pointer data.

mmap2

 

adana elektrikci

', 'auto'); ga('send', 'pageview');