Сопоставляется ли последний ГБ в адресном пространстве процесса Linux с одной и той же физической памятью?

Я читал, что первые 3 ГБ зарезервированы для процесса, а последние ГБ — для ядра. Еще читал, что ядро ​​загружается начиная со 2-х Мб физического адресного пространства (в зависимости от конфигурации). Мой вопрос в том, что сопоставление этого последнего 1 ГБ одинаково для всех процессов и сопоставлений с этой физической областью памяти?

Другой вопрос, когда процесс переходит в режим ядра (например, когда происходит вызов sys), то какие таблицы страниц используются, таблицы страниц процесса или таблицы страниц ядра? Если используются таблицы страниц ядра, то они не могут получить доступ к ячейкам памяти, принадлежащим процессу. Если это так, то, по-видимому, виртуальная память ядра бесполезна, поскольку весь доступ к коду ядра и данным будет осуществляться через сопоставление последнего 1 ГБ адресного пространства процесса. Пожалуйста, помогите мне прояснить это (любые полезные ссылки будут высоко оценены)


person pflz    schedule 21.05.2011    source источник


Ответы (2)


Да, отображение ядерной части адресного пространства одинаково во всех процессах. Часть отображает ту часть физической памяти, в которую загружается образ ядра, но это не основная ее часть — оставшаяся часть используется для отображения других участков физической памяти для рабочего набора ядра во время выполнения.

Когда процесс переключается в режим ядра, таблицы страниц не изменяются. Часть адресного пространства ядра просто становится доступной, потому что CPL (текущий уровень привилегий) теперь равен нулю.

person caf    schedule 23.05.2011
comment
тогда зачем нужны таблицы страниц ядра? - person pflz; 25.05.2011
comment
@Naman Mishra: Таблицы страниц ядра будут той частью таблиц страниц, которая соответствует верхнему 1 ГБ линейного адресного пространства. Смысл их в том, чтобы эти части (виртуальной) памяти вообще можно было использовать. - person caf; 25.05.2011
comment
Большое спасибо. Это было полезно. - person pflz; 26.05.2011

Кажется, вы говорите о 32-битных системах x86, верно?

Если не ошибаюсь, ядро ​​можно настроить не только на распределение памяти 3Gb/1Gb, могут быть и другие варианты (например, 2Gb/2Gb). Тем не менее, 3Gb/1Gb, вероятно, наиболее распространены на x86-32.

Ядерная часть адресного пространства должна быть недоступна из пользовательского пространства. С точки зрения ядра, да, отображение памяти, занимаемой самим ядром, всегда одинаково. Неважно, в контексте какого процесса (или обработчика прерываний, или чего-то еще) в данный момент работает ядро.

Как одно из следствий, если вы посмотрите на адреса символов ядра в /proc/kallsyms из разных процессов, вы каждый раз будете видеть одни и те же адреса. И это как раз адреса соответствующих функций ядра, переменных и прочего с точки зрения ядра.

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

Что касается второго вопроса, то, если ядро ​​в настоящее время работает в контексте какого-либо процесса, оно может получить доступ к пользовательской памяти этого процесса. Я не могу описать это подробно, но, вероятно, реализация функций ядра copy_from_user и copy_to_user может дать вам некоторые подсказки. См. arch/x86/lib/usercopy_32.c и arch/x86/include/asm/uaccess.h в исходниках ядра. Кажется, что в x86-32 доступ к памяти пользовательского пространства в этих функциях осуществляется напрямую, используя сопоставления памяти по умолчанию для текущего контекста процесса. «Волшебные» вещи там связаны только с оптимизацией и проверкой адреса области памяти на правильность.

person Eugene    schedule 21.05.2011