Чтение физической памяти с помощью /dev /mem

#memory #linux-kernel #kernel #ram #mmap

#память #linux-ядро #ядро #ОЗУ #mmap

Вопрос:

Я пытаюсь выяснить, как напрямую считывать любое местоположение в физической памяти на процессоре Power9, используя /dev / mem. Ниже приведен код, который я использовал с этой целью.

 FILE* fp;
int _fdmem;
int *map = NULL;
const char memDevice[] = "/dev/mem";

_fdmem = open( "/dev/mem", O_RDWR | O_SYNC );

if (_fdmem < 0){
printf("Failed to open the /dev/mem !n");
return 0;
}
else{
printf("open /dev/mem successfully !n");
}

map= (int *)(mmap(NULL,1,PROT_READ|PROT_WRITE,MAP_PRIVATE,_fdmem,0));

fp=fopen("./memm2out.txt","w");

for (int i=0; i<131073;i  )
{
fprintf(fp, "%x",*(map i));
}
  

Когда я запускаю код, я получаю следующий вывод.

 open /dev/mem successfully !
Segmentation fault
  

При использовании GDB именно здесь возникает ошибка segfault

 Program received signal SIGSEGV, Segmentation fault.
0x0000000100000a2c in main () at memmapper2.c:34
34      fprintf(fp, "%x",*(map i));
  

Когда я использую 131072 в качестве значения для i, segfault отсутствует, что заставляет меня поверить, что существует какая-то граница для чтения после 64 КБ. Файл запускается с правами root. Процессор, который я использую, работает под управлением ядра Linux версии 4.18. Что может ограничивать мой доступ?

Редактировать: Когда второму параметру mmap присваивается любое значение, большее 65536, mmap не открывается и выдает сообщение об ошибке «: ОПЕРАЦИЯ НЕ РАЗРЕШЕНА». Насколько я понимаю, здесь происходит то, что mmap сопоставляет указатель файла для /dev / mem с определенным местоположением в виртуальной памяти, из которого вы можете вызвать функциональность / dev / mem для чтения физической памяти. Ошибаюсь ли я в этом понимании?

Комментарии:

1. Попробуйте вызвать mmap() с размером, достаточно большим, чтобы охватить ваш (количество циклов) * sizeof(int) ; показанное начальное значение равно 1

2. Проверьте возвращаемые значения mmap и fopen . Один из двух сбоев. Используйте perror() для печати описания ошибки.

3. Можете ли вы показать содержимое /proc / pid /maps после возврата вызова mmap?

4. @Milag Достаточно интересно, что если я установлю параметр длины в mmap больше 65536, то произойдет сбой mmap. Я использовал perror для проверки errno, как сказал Марко Бонелли, и сообщение об ошибке «: ОПЕРАЦИЯ НЕ РАЗРЕШЕНА». При этом не похоже, что значение для длины в диапазоне 1-65536 оказывает какое-либо влияние на выходные данные или на местоположение segfault при чтении из /dev / mem. Опять же, у этого файла есть права root.

5. Смотрите процедуру ядра mmap_mem() . Похоже, есть некоторые ограничения по диапазону. Попробуйте поэкспериментировать с доступом только для чтения, другими флагами или обоими.