У меня проблема с использованием 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...
Я делаю что-то неправильно? Каждая помощь приветствуется!
4069
вместоMAP_SIZE
? Не обычное значение степени двойки4096
? Это опечатка в самом коде, или вы переписали код для вопроса? Если второе, то не делайте этого. Вместо скопируйте и вставьте минимальный, полный и проверяемый пример. Таким образом, вы не внесете несвязанных ошибок или, возможно, даже (по ошибке и не осознавая этого) устраните проблему. - person Some programmer dude   schedule 12.12.2017#include ...
), и вывод, который вы показываете, не соответствует коду (код говорит, чтоMAP_SIZE
равен4069
, но ваш вывод показывает его как4096
). Таким образом, код, который вы показываете, не является фактическим кодом, который вы создаете и запускаете. Подобные мелочи мешают нам доверять остальному коду, поэтому многие, кто мог бы вам помочь, не будут этого делать. - person Some programmer dude   schedule 12.12.2017do{ ... } while(0);
-->do{ ... } while(0)
[иначе причудливое do-while не имело бы никакого смысла] - person joop   schedule 12.12.2017resource
? Это просто сообщает вам информацию об областях ввода-вывода порта и памяти ввода-вывода и представляет собой довольно небольшой файл. Вам необходимо сопоставить один изresourceN
файлов (гдеN
— номер PCI BAR (регистра базового адреса)) для доступа к области памяти PCI, охватываемой PCI BAR N. - person Ian Abbott   schedule 12.12.2017