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
, Документацию можно найти здесь. Краткое содержание:
/proc/$pid/maps
предоставляет список сопоставлений с их виртуальными адресами и соответствующий файл для сопоставленных файлов./proc/$pid/pagemap
предоставляет дополнительную информацию о каждой отображаемой странице, включая физический адрес, если он существует.
Как было показано позже в оригинальном постере, этот пример предоставляет пример реализации того, как использовать эти файлы.
Передайте виртуальный адрес ядру с помощью systemcall/procfs и используйте vmalloc_to_pfn. Вернуть физический адрес через procfs/registers.