使用 "mmap" 从文件读取时得到空输出
Getting empty output when reading from file using "mmap"
考虑到 mmap 的使用,我遇到了问题。我正在尝试将 pci 设备映射到虚拟地址并读取其内容。以后我也打算给它写值。
问题是我(貌似)成功地将设备映射到虚拟内存space。但是,当我读取该虚拟地址的内容时,尽管文件不为空,但所有值均为零。
这是我的代码:
#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...
我做错了什么吗?感谢您的帮助!
实际上你有 2 个错误:
- 在文件系统上为真实文件创建映射时不要使用 MAP_ANON,它用于 IPC 并且需要来自 OS 的额外内存,例如而 malloc().
- 当您删除该标志时,mmap() 可能会 return ENODEV,因为 linux sysfs 不支持 mmaping;所以你必须在这里使用read()。
考虑到 mmap 的使用,我遇到了问题。我正在尝试将 pci 设备映射到虚拟地址并读取其内容。以后我也打算给它写值。
问题是我(貌似)成功地将设备映射到虚拟内存space。但是,当我读取该虚拟地址的内容时,尽管文件不为空,但所有值均为零。
这是我的代码:
#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...
我做错了什么吗?感谢您的帮助!
实际上你有 2 个错误:
- 在文件系统上为真实文件创建映射时不要使用 MAP_ANON,它用于 IPC 并且需要来自 OS 的额外内存,例如而 malloc().
- 当您删除该标志时,mmap() 可能会 return ENODEV,因为 linux sysfs 不支持 mmaping;所以你必须在这里使用read()。