内存访问分段错误

Segmentation fault on Memory Access

我已经将 0x40000000 的基地址映射到虚拟内存地址。但是当我尝试读取 0x40100000 位置的寄存器值时,出现了分段错误。 mmap() 函数中使用的页面大小为 4K,其中文件描述符的值为 3.

从main调用init()函数初始化内存: 这里 UWord8unsigned charUWord32unsigned 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 字节。