Вопрос или проблема
В настоящее время я исследую использование виртуальных адресных пространств в ядре Linux. Я понимаю преимущества их наличия, как работают обходы таблицы страниц в x86 и структуру виртуального адресного пространства.
Вот часть, которую я не понимаю:
Во время одной из моих лекций было объяснено, что ядро Linux использует “идентичное отображение” в пространстве ядра. Это означает:
В пространстве ядра вы можете преобразовать любой виртуальный адрес в его физический адрес, вычитая постоянное число.
Это число часто называют PAGE_OFFSET, и оно отличается в зависимости от 64-битной или 32-битной архитектуры, 4-х уровневой или 5-ти уровневой адресной трансляции и может также быть настроено. kASLR увеличивает PAGE_OFFSET на случайное значение при каждом запуске как мера безопасности.
Я видел это объяснение во многих местах, но большинство из них немного устарели:
https://stackoverflow.com/a/36640733/15113903
https://stackoverflow.com/questions/24632905/mapping-of-kernel-virtual-address-directly?rq=1
Самое недавнее неявное объяснение заключается в том, что volatility3, похоже, полагается на это идентичное отображение при определении сдвига kASLR для дампа памяти.
Теперь: (Почему) адресное пространство виртуального ядра (по-прежнему) таково? Есть ли преимущества в производительности? Необходимо ли это по какой-то причине? Это наследие из более ранних времен? Насколько вероятно, что это изменится в ближайшем будущем?
Спасибо
вы можете преобразовать любой виртуальный адрес в его физический адрес, вычитая постоянное число
Не совсем; любой виртуальный адрес в конце адресного пространства ядра.
Ядро Linux на некоторых архитектурах (включая x86) по-прежнему имеет линейное отображение физического адресного пространства в виртуальном адресном пространстве. Это имеет ряд преимуществ:
- уменьшение нагрузки на TLB (помогает с большими отображениями страниц, которые ядро использует для этого отображения, когда это возможно)
- почти прямой доступ к физическим адресам (имейте в виду, что с MMU код, выполняющийся на ЦПУ, может обращаться только к виртуальным адресам)
- доступ к адресам, которые иначе не отображаются (потому что они используются для процессов, отличных от текущего процесса, или потому что они вообще не отображаются)
Ни одно из этих условий не является жестким требованием, и некоторые люди хотели бы избавиться от линейного отображения в какой-то момент, но я не знаю, работает ли кто-то над этим.
Ответ или решение
Почему ядро Linux использует идентичное отображение виртуального адресного пространства?
Виртуальные адресации играют ключевую роль в современных операционных системах, включая ядро Linux. Выбор между различными способами отображения виртуального и физического адресного пространства вызывает множество вопросов. Одним из наиболее заметных решений является использование идентичного отображения в пространстве адресов ядра Linux. Это означает, что любую виртуальную адресу в пространстве ядра можно легко сопоставить с соответствующим физическим адресом, вычитая определённое значение, часто обозначаемое как PAGE_OFFSET
.
Технический контекст
В системе адресации x86 ядро Linux имеет выделенную область виртуального адресного пространства, куда помещаются ядровые данные и коды, причём эта область начинается с PAGE_OFFSET
. Это значение различается в зависимости от архитектуры (например, 32 или 64 бита) и конфигурации системы (например, наличие 4- или 5-слойного отображения адресов). Введённое изменение PAGE_OFFSET
, как например, kASLR
, повышает безопасность за счёт рандомизации адресного пространства при каждом запуске системы.
Причины использования идентичного отображения
-
Снижение нагрузки на TLB (Translation Lookaside Buffer):
- Идентичное отображение помогает улучшить эффективность работы с кэшом TLB, поскольку ядро может использовать большие единицы отображения (например, гигантские страницы). Это минимизирует количество записей в TLB и улучшает производительность, так как меньше обращений требуется для кэширования адресов.
-
Практически прямой доступ к физическим адресам:
- С использованием идентичного отображения, код, выполняемый на процессоре, может обращаться к физическим адресам почти напрямую, что упрощает доступ к оборудованию и другим критически важным данным.
-
Доступ к неотображаемым адресам:
- Такой подход предоставляет возможность доступа к физическим адресам, которые могут использоваться другими процессами, либо вообще не иметь отображения в контексте текущего процесса.
Наследие и перспектива изменений
Идентичное отображение в адресном пространстве ядра можно рассматривать как результат исторической необходимости и эволюции операционных систем. Этот механизм был внедрён на ранних этапах проектирования ядер Linux, где производительность и прямой доступ были критически важными для взаимодействия с аппаратным обеспечением. С течением времени это решение стало основой для многих других архитектур и систем.
Хотя существует мнение, что существующее отображение может быть изменено или оптимизировано, в настоящее время нет активной работы над заменой идентичного отображения, поскольку преимущества, которые оно предоставляет, по-прежнему актуальны. Переход к новым архитектурным решениям потребовал бы обширных тестов и изменений на уровне программного обеспечения, что, в свою очередь, может повлиять на стабильность и производительность всей системы.
Заключение
Идентичное отображение в пространстве адресов ядра Linux сохраняется как важный элемент, обеспечивающий высокую производительность, удобство доступа и простоту реализации доступа к физической памяти. Способность легко сопоставлять виртуальные и физические адреса является важным аспектом архитектуры и пока что не подвержена изменениям, что делает её необходимым элементом для современного и будущего развития ядра Linux.