内存访问分段错误
Segmentation fault on Memory Access
我已经将 0x40000000
的基地址映射到虚拟内存地址。但是当我尝试读取 0x40100000
位置的寄存器值时,出现了分段错误。 mmap()
函数中使用的页面大小为 4K
,其中文件描述符的值为 3
.
从main调用init()
函数初始化内存:
这里 UWord8
是 unsigned char
而 UWord32
是 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;
}
以下是函数读取特定地址的值,发送给函数的地址是相对于基地址的偏移量:
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;
}
这一行没有错误:
_getWord(0x000ffff8)
但是我遇到了分段错误:
_getWord(0x00100000)
当你创建你的内存映射时,你给它的大小等于你的页面大小——4kb。
fpga_ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr); //mmap the device into memory
这转换为 0x1000
字节,但是您尝试在地图开始后访问数据 0x100000
字节,这会引发分段错误。要解决此问题,请映射更大的内存区域。例如:
fpga_ptr = mmap(NULL, 0x1000 * page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr);
这将允许您访问内存映射开始后的下一个 0x1000000
字节。
我已经将 0x40000000
的基地址映射到虚拟内存地址。但是当我尝试读取 0x40100000
位置的寄存器值时,出现了分段错误。 mmap()
函数中使用的页面大小为 4K
,其中文件描述符的值为 3
.
从main调用init()
函数初始化内存:
这里 UWord8
是 unsigned char
而 UWord32
是 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;
}
以下是函数读取特定地址的值,发送给函数的地址是相对于基地址的偏移量:
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;
}
这一行没有错误:
_getWord(0x000ffff8)
但是我遇到了分段错误:
_getWord(0x00100000)
当你创建你的内存映射时,你给它的大小等于你的页面大小——4kb。
fpga_ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr); //mmap the device into memory
这转换为 0x1000
字节,但是您尝试在地图开始后访问数据 0x100000
字节,这会引发分段错误。要解决此问题,请映射更大的内存区域。例如:
fpga_ptr = mmap(NULL, 0x1000 * page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr);
这将允许您访问内存映射开始后的下一个 0x1000000
字节。