Linux (Ubuntu), язык C: преобразование виртуальных адресов в физические

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

Позвольте мне объяснить: учитывая объявление переменной в пространстве процесса, как я могу получить ее физический адрес, сопоставленный с ОС?

Я наткнулся на некоторые системные вызовы /asm/io.h где virt_to_phys() функция определена; однако кажется, что этот заголовок устарел, и я не могу найти обходной путь.

Тем не мение; io.h доступно по адресу: /usr/src/linux-headers-2.6.35-28-generic/arch/x86/include/asm/, Мое текущее ядро 2.6.35-28, но io.h не входит в /usr/include/asm/?

Итак, еще раз: мне нужен способ получить физический адрес из виртуального. Предпочтительно выводится из приложения во время выполнения. Но даже обходной путь использования монитора /proc/PID/maps Сделаю.

Любые идеи или комментарии будут с благодарностью.


РЕДАКТИРОВАТЬ После небольшого исследования по этой теме я нашел кое-что, что помогает в этом отношении.

Оказывается, это более чем выполнимо, хотя и требует некоторого обходного пути. Вот ссылка на простое приложение, которое анализирует текущие отображаемые страницы. Получается рассматриваемый файл (бинарный файл) /proc/pid/pagemap (содержит физическое отображение виртуальных страниц). В любом случае код в этой ссылке можно изменить, чтобы он служил в качестве приложения для монитора или чего-то еще.

Мне нужен был физический адрес для симуляции кеша.

Спасибо за помощь и ответы!

3 ответа

В коде пользователя вы не можете знать физический адрес, соответствующий виртуальному адресу. Эта информация просто не экспортируется за пределы ядра. Это может даже измениться в любое время, особенно если ядро ​​решит выгрузить часть памяти вашего процесса.

В /proc/$pid/maps, у вас есть информация о том, что соответствуют виртуальным адресам в адресном пространстве вашей программы (mmapped файлы, куча, стек и т. д.). Это все, что вы получите.

Если вы работаете с кодом ядра (которым вы, очевидно, не являетесь), вы можете узнать физический адрес, соответствующий странице памяти. Но даже тогда virt_to_phys не вся история; Я рекомендую прочитать Драйверы устройств Linux (особенно главы 8 и 15).

Заголовок asm/io.h заголовок ядра Он недоступен при компиляции пользовательского кода, потому что его содержимое просто не имеет смысла. Функции, которые он объявляет, недоступны ни в одной библиотеке, только в ядре.

Как частично ответил первоначальный постер, ядро ​​Linux демонстрирует свое отображение в пользовательском пространстве через набор файлов в /proc, Документацию можно найти здесь. Краткое содержание:

  1. /proc/$pid/maps предоставляет список сопоставлений с их виртуальными адресами и соответствующий файл для сопоставленных файлов.
  2. /proc/$pid/pagemap предоставляет дополнительную информацию о каждой отображаемой странице, включая физический адрес, если он существует.

Как было показано позже в оригинальном постере, этот пример предоставляет пример реализации того, как использовать эти файлы.

Передайте виртуальный адрес ядру с помощью systemcall/procfs и используйте vmalloc_to_pfn. Вернуть физический адрес через procfs/registers.

Другие вопросы по тегам