使用“mmap”从文件读取时获取空输出

时间:2017-12-12 08:56:23

标签: c linux mmap pci virtual-address-space

考虑到使用mmap,我遇到了问题。我正在尝试将pci设备映射到虚拟地址并读取其内容。在未来,我也打算为它写一些价值。

问题是我(貌似)成功地将设备映射到虚拟内存空间。但是,当我读取该虚拟地址的内容时,所有值都为零,尽管文件不是空的。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "../include/types.h"
#include "../include/pci.h"

#define PRINT_ERROR \
    do { \
        fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
        __LINE__, __FILE__, errno, strerror(errno)); exit(1);\
     } while(0)

#define MAP_SIZE 4069
#define MAP_MASK (MAP_SIZE - 1)

int main(int argc, char *argv[])
{
    int pci_dev;
    int *mmap_base;
    int *content;
    char file[] = {"/sys/bus/pci/devices/0000:04:00.0/resource"};
    int i;

    printf("File to be read from: %s\n", file);

    pci_dev = open(file, O_RDONLY);
    if (pci_dev < 0)
    {
        PRINT_ERROR;
    }

    mmap_base = mmap(NULL, MAP_SIZE, PROT_READ, MAP_PRIVATE | MAP_ANON, pci_dev, 0);
    if (mmap_base == (void *)-1 || mmap_base == NULL)
    {
        PRINT_ERROR;
    }
    printf("Mapped on address %p of size %d Byte\n", mmap_base, (int)MAP_SIZE);
    content = (int *)mmap_base;

    for(i = 0; i < 1024; i++)
    {
        printf("%x", content[i]);
    }


    return 0;
}

以下是我尝试访问的文件"/sys/bus/pci/devices/0000:04:00.0/resource"中第一行的内容:

0x00000000cd000000 0x00000000cd07ffff 0x0000000000040200

然而我得到的输出是:

File to be read from: /sys/bus/pci/devices/0000:04:00.0/resource
Mapped on address 0xb7705000 of size 4096 Byte
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...

我做错了吗?感谢每一位帮助!

1 个答案:

答案 0 :(得分:0)

实际上你有两个错误:

  1. 在为文件系统上的真实文件创建映射时不要使用MAP_ANON,它适用于IPC并需要来自OS的额外内存,例如:而malloc()。
  2. 当你删除标志时,mmap()可能会返回ENODEV,因为linux sysfs不支持mmaping;所以你必须在这里使用read()。