36

Предположительно это как-то связано с памятью? Что бы

sudo cat /dev/urandom > /dev/mem

делать? Корзина вся ОЗУ? Вся неядерная виртуальная память? Ни один из вышеперечисленных?

5 ответов5

29

Он обеспечивает доступ к физической памяти системы.

Страница man mem(4) объясняет, что такое /dev/mem .

Да, это может вызвать все виды проблем. Перезагрузка должна исправить вас, но плохие вещи могут произойти очень легко. Быть осторожен! :-)

16

/dev/mem обеспечивает доступ к физической памяти системы, а не к виртуальной памяти. Виртуальное адресное пространство ядра может быть доступно с помощью /dev/kmem.

Он в основном используется для доступа к адресам памяти ввода-вывода, связанным с периферийным оборудованием, например видеоадаптерами.

8

sudo cat /dev/urandom > /dev/mem ничего не сделает, так как sudo повысит привилегию cat, но не редиректа. Вы можете сделать sudo su и затем работать в корневой оболочке, или использовать
sudo dd if=/dev/urandom of=/dev/mem

/dev/mem обеспечивает доступ к физической памяти, то есть ко всей оперативной памяти в системе, однако это не означает, что он предоставляет вам полный доступ для чтения / записи в оперативную память (см. параметр CONFIG_STRICT_DEVMEM в этом документе). Также обратите внимание, что в некоторых областях физической памяти будут отображаться другие устройства, такие как память видеокарты и т.д.

Слепая запись в /dev/mem приведет к неопределенному поведению, здесь видео на YouTube делает то же самое.

5

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

Многие современные ядра будут сконфигурированы с "CONFIG_STRICT_DEVMEM", который ограничивает /dev /mem только для устройств ввода-вывода с отображением в памяти.

Писать случайный мусор - плохая идея, но точно, что случится, сложно предсказать. Аппаратные средства могут непредсказуемым образом реагировать на случайный мусор, поврежденные структуры памяти ядра могут вызывать непредсказуемое поведение ядра. В лучшем случае я ожидал бы сбой системы, в худшем случае не может быть и речи о повреждении данных или даже аппаратном блокировании.

PS обратите внимание, что ваша команда при запуске от имени обычного пользователя не должна ничего делать, потому что sudo уничтожает только команду cat, а не redirect.

4

Проверьте это с busybox devmem

busybox devmem - это крошечная утилита CLI, которая называется mmaps /dev/mem .

Вы можете получить его в Ubuntu с помощью: sudo apt-get install busybox

Использование: считывание 4 байтов с физического адреса 0x12345678:

sudo busybox devmem 0x12345678

Напишите 0x9abcdef0 по этому адресу:

sudo busybox devmem 0x12345678 w 0x9abcdef0

Источник: https://github.com/mirror/busybox/blob/1_27_2/miscutils/devmem.c#L85

MAP_SHARED

При mmapping /dev/mem вы, вероятно, захотите использовать:

open("/dev/mem", O_RDWR | O_SYNC);
mmap(..., PROT_READ | PROT_WRITE, MAP_SHARED, ...)

MAP_SHARED заставляет записи отправляться в физическую память, что облегчает наблюдение и имеет больше смысла для записей аппаратного регистра.

CONFIG_STRICT_DEVMEM и nopat

Чтобы использовать /dev/mem для просмотра и изменения обычной оперативной памяти в ядре v4.9, вы должны:

  • отключить CONFIG_STRICT_DEVMEM (устанавливается по умолчанию в Ubuntu 17.04)
  • передать параметр командной строки ядра nopat для x86

Порты ввода-вывода по-прежнему работают без них.

Смотрите также: https://stackoverflow.com/questions/39134990/mmap-of-dev-mem-fails-with-invalid-argument-for-virt-to-phys-address-but-addre/45127582#45127582

Сброс кеша

Если вы попытаетесь выполнить запись в ОЗУ, а не в регистр, память может быть кэширована ЦП: https://stackoverflow.com/questions/22701352/how-to-flush-the-cpu-cache-for-a-region -of-address-space-in-linux, и я не вижу очень переносимого / простого способа очистить его или пометить регион как не кэшируемый:

Так что, может быть, /dev/mem нельзя надежно использовать для передачи буферов памяти на устройства?

К сожалению, в QEMU этого не наблюдается, поскольку QEMU не моделирует кэши.

Как это проверить

Теперь самое интересное. Вот несколько классных настроек:

  • Пользовательская память
    • выделение volatile переменную процесса на UserLand
    • получить физический адрес с помощью /proc/<pid>/maps + /proc/<pid>/pagemap
    • физический адрес с devmem2 , и наблюдайте, как пользовательский процесс реагирует:
  • Ядро памяти
    • выделить память ядра с помощью kmalloc
    • получить физический адрес с помощью virt_to_phys и передать его обратно пользователю
    • изменить физический адрес с помощью devmem2
    • запросить значение из модуля ядра
  • IO mem и устройство виртуальной платформы QEMU
    • создать платформенное устройство с известными физическими адресами регистра
    • используйте devmem2 для записи в реестр
    • смотреть printf s выходят из виртуального устройства в ответ

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .