Accessing specific memory address from user code

Written by Ian on 26/08/09


This code uses the /dev/mem interface to connect from user space (code running with root privilege) to any physical memory address.


You can use it when prototyping to test out memory-mapped peripherals.
• It's been tested on the PC and on ARM linux, and works great.
• This compiles into a standalone little application to talk to memory, but you can strip out the 'guts' and use it in your own code.




#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

#define MAP_SIZE 48UL
#define MAP_MASK (MAP_SIZE -1)

int main(int argc, char **argv){
int fd, read_result, writeval;
void *map_base, *virt_addr;
off_t target=0xB5000000;

if(argc==2)
{
target=strtoul(argv[1], 0, 0);
printf("Reading from address %p.\\n", target);
}
else
{
if(argc==3)
{
target=strtoul(argv[1], 0, 0);
writeval=strtoul(argv[2], 0, 0);
printf("Writing %p to address %p.\\n", writeval, target); }
else
{
printf("Error: wrong number of arguments given.\\n");
printf("Usage: %s 0x10009876 will read from address 0x10009876\\n");
printf(" %s 0x12340000 0xff will write 0xff to address 0x12340000\\n");
exit(0);
}
}

if((fd=open("/dev/mem", O_RDWR | O_SYNC)) == -1){
printf("/dev/mem could not be opened.\\n");
exit(1);
} else
printf("/dev/mem opened.\\n");

//
map_base=mmap(0,MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED,fd,target & ~MAP_MASK);
if(map_base==(void *)-1)
printf("Mapping failed.\\n");
else
printf("Mapped to addr %p.\\n",map_base);

virt_addr=map_base + (target & MAP_MASK);

if(argc==2)
{
read_result=*((volatile unsigned long *)virt_addr);
printf("We read back the value %p\\n",read_result);
}
else
{
*((volatile unsigned int *)virt_addr)=writeval;
}

if(munmap(map_base,MAP_SIZE)==-1){
printf("Unmapping failed.\\n");
}
close(fd);
}