I have mmapped a base address of 0x40000000
to a virtual memory address. But when I try to read the value of register on the location of 0x40100000
, I get a segmentation fault. The page size used in the mmap()
function is 4K
where the file descriptor has a value of 3
.
The init()
function is called from the main to initialize the memory:
Here UWord8
is unsigned char
and UWord32
is unsigned int
.
UWord8 init()
{
UWord8 error;
printf("Initializing Devices in Zynq...\n\r\n\r");
error = initMemory();
if(error)
{
printf("PL:\tAccess Denied\n\r");
return 1;
}
if(!error)
{
error = initFpga();
if(error)
{
printf("Access Denied to mmap...\n\r");
return 1;
}
}
}
UWord8 initMemory(void)
{
UWord8 error = 0;
//Initializing /dev/mem
fd = open(MEMORY_ACCESS, READ_WRITE);
if(fd < 1)
{
error = 1;
#if DEBUG_MODE
printf("Could not open /dev/mem for access\n");
#endif
}
else
{
printf("Value of fd is %u\n", fd);
page_size = sysconf(_SC_PAGESIZE);
printf("The page size is %u\n", page_size);
#if DEBUG_MODE
printf("Successfully opened /dev/mem for access\n");
#endif
}
//Opening text file for writing pointer data
fp = fopen("/home/pointer_data.txt", "a");
if(fp == NULL)
{
error = 1;
#if DEBUG_MODE
printf("Could not open text file for writing.\n\r");
#endif
}
else
{
#if DEBUG_MODE
printf("Successfully opened text file for writing.\n\r");
#endif
}
return error;
}
UWord8 initFpga(void)
{
UWord8 error = 0;
unsigned page_addr, device_addr;
device_addr = BASE_ADDRESS;
page_addr = (device_addr & (~(page_size-1)));
fpga_pageOffset = device_addr - page_addr;
fpga_ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr); //mmap the device into memory
if(fpga_ptr == NULL)
{
printf("Memory mapping to Base address 0x%08x failed...\n\r",BASE_ADDRESS);
error = 1;
}
return error;
}
The following is the function is read the value at a particular address, the address being sent to the function is the offset from base address:
UWord32 _getWord(UWord32 address)
{
UWord32 data = *((unsigned *)(fpga_ptr + fpga_pageOffset + address));
printf("peek 0x%08x =0x%08x\n\r", BASE_ADDRESS + address, data);
return data;
}
There is no error on this line:
_getWord(0x000ffff8)
But I get a segmentation fault on:
_getWord(0x00100000)
When you create your memory map, you give it a size equal to your pagesize- 4kb.
fpga_ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr); //mmap the device into memory
This translates to 0x1000
bytes, however you attempt to access data 0x100000
bytes after the beginning of your map, which raises the segmentation fault. To fix this issue, map a larger region of memory. For example:
fpga_ptr = mmap(NULL, 0x1000 * page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr);
This will allow you to access the next 0x1000000
bytes after the beginning of your memory map.