#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)
; показанное начальное значение равно 12. Проверьте возвращаемые значения
mmap
иfopen
. Один из двух сбоев. Используйтеperror()
для печати описания ошибки.3. Можете ли вы показать содержимое /proc / pid /maps после возврата вызова mmap?
4. @Milag Достаточно интересно, что если я установлю параметр длины в mmap больше 65536, то произойдет сбой mmap. Я использовал perror для проверки errno, как сказал Марко Бонелли, и сообщение об ошибке «: ОПЕРАЦИЯ НЕ РАЗРЕШЕНА». При этом не похоже, что значение для длины в диапазоне 1-65536 оказывает какое-либо влияние на выходные данные или на местоположение segfault при чтении из /dev / mem. Опять же, у этого файла есть права root.
5. Смотрите процедуру ядра
mmap_mem()
. Похоже, есть некоторые ограничения по диапазону. Попробуйте поэкспериментировать с доступом только для чтения, другими флагами или обоими.