Brief introduction of Linux MMAP and solution of bus error

Bus error occurs when mMAP Shared memory is used for communication between unrelated processes. 

Introduction to MMap communication mechanism
About the mmap

Mmap maps a file or other object into memory. A file is mapped to multiple pages, and if the file size is not the sum of all pages, the unused space of the last page is cleared. Munmap does the opposite, removing the object map for a specific address area.
When mmap is used to map the file to the process, the virtual address can be directly operated for file reading and writing operations, and there is no need to call read,write and other system calls. Note, however, that writing directly to this segment of memory does not write anything larger than the current file size.

An obvious benefit of using Shared memory communication is efficiency,
Because the process can read and write directly to memory without any copy of the data. For communications such as pipes and message queues, there are four copies of the data in the kernel and user space, and only two copies of the data in Shared memory: once from the input file to the Shared memory area, and once from the Shared memory area to the output file. In fact, when processes share memory, they do not always unmap after reading and writing a small amount of data, and re-establish the Shared memory area when there is new communication. Instead, the Shared area is kept until the communication is complete, so that the data content is kept in Shared memory and not written back to the file. Content in Shared memory is often written back to the file when the map is unmapped. Therefore, using the Shared memory communication method is very efficient.

Introduction to the MMAP function

Void * START, size_t length, int PROt,int FD, OFF_t offset);

Parameter description:

Start: The start address of the mapping area.
length: the length of the desired mapping area.
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 combined by an OR operation.
 PROT_EXEC// pages can be executed
 PROT_READ/page/content can be read
 PROT_WRITE// page can be written to the
 PROT_NONE // page not accessible

flags: specifies the type of mapping object, mapping options, and whether the mapping page can be Shared. Its value can be a combination of one or more of the following bits. MAP_SHARED is generally used.
MAP_SHARED// Shared with all the process of mapping the object mapping space. Writes to a Shared area, equivalent to output to a file. The file is not actually updated until either Msync () or Munmap () is invoked.

fd: valid file description. If MAP_ANONYMOUS is set, the value should be -1 for compatibility issues.
offset: offset of the mapped object content (generally 0).

 

Bus Error solution

After mMAP, when the memory copy is made, the write() function is first used to write to the file descriptor that has been opened.

 

Reference code

Write:

<span style="font-size:12px;">// Arthur: zhangxiao
// Data: 2014/12/24	
// Note: mmap write
/*******************/

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
//#define FILENAME "/home/zhangxiao/embededSystem/example/Mmap/test"

#define FILENAME "/tmp/test"
#define BUFLEN 128	
typedef struct
{
	char name[BUFLEN];
	int  id;
}people;

int main(int argc, char** argv) 
{
	int i;
	unsigned int pmap=0;
	int fd;
	fd=open(FILENAME ,O_CREAT|O_RDWR|O_TRUNC,00777 );
	assert(fd !=-1);
	pmap = (unsigned int)mmap(0,sizeof(people),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	assert(pmap!=-1);
	write(fd," ",sizeof(people)); //write something
	unsigned int addr;
	addr=pmap;
	char tempname[30]="helloworld";
	int tempid=253; 
	addr = pmap + sizeof(char)*BUFLEN;	
	memcpy((void *)pmap,tempname,strlen(tempname)+1);
	memcpy((void *)addr, &tempid,sizeof(int));
	munmap((void *) pmap,sizeof(char)*BUFLEN);
	close(fd);
	printf("umap ok\r\n");
	return 0;
}</span><strong style="color: rgb(255, 0, 0); font-size: 19px;">
</strong>

Read:

// Arthur: zhangxiao
// Data: 2014/12/24	
// Note: mmap read 
/*******************/
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
//#define FILENAME "/home/zhangxiao/embededSystem/example/Mmap/test"
#define FILENAME "/tmp/test"
#define BUFLEN 128	
typedef struct
{
	char name[BUFLEN];
	int  id;
}people;

int main(int argc, char** argv) 
{
	int i;
	unsigned int pmap=0;
	int fd;
	fd=open(FILENAME ,O_CREAT|O_RDWR,00777 );
	assert(fd !=-1);
	pmap = (unsigned int)mmap(0,sizeof(people),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	unsigned int addr;
	addr = pmap + sizeof(char)*BUFLEN;	
	printf("id=%d   name=%s\n\r",*((int *)addr),(char *)pmap);	
	munmap((void *) pmap,sizeof(char)*BUFLEN);
	close(fd);
	printf("umap ok\r\n");
	return 0;
}

 

Makefile:

CROSS = gcc

flags=-o
all:mmap_read mmap_write

mmap_read:mmap_read.c
	$(CROSS) $(flags) mmap_read mmap_read.c
mmap_write:mmap_write.c
	$(CROSS) $(flags) mmap_write mmap_write.c

clean:
	rm -rf mmap_read mmap_write<strong>
</strong>

 


Read More: