C 内存访问中的分段错误

C 内存访问中的分段错误,c,mmap,C,Mmap,我已将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"

我已将
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;
}
这一行没有错误:

_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
字节。

请显示一些代码。我觉得我忽略了一些内容。您映射了一个4kb内存区域(页面对齐),对应于0x1000,但您试图访问超出映射开头的地址0x100000字节?返回
MAP\u FAILED
如果失败,而不是
NULL
@KulaDamian您可以选择您想要的任何数字,但通常最好“只取您需要的”。我倾向于将我的映射设置为页面大小的倍数,但这是可选的。更改页面大小有助于@DillonDavis。谢谢你的帮助!!
fpga_ptr = mmap(NULL, 0x1000 * page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_addr);