1

В ядре Linux, а также во многих обучающих программах x86 в Интернете, я вижу, что люди рекомендуют использовать два сегмента кода и два сегмента данных. Я понимаю необходимость в двух сегментах кода, поскольку CPL должен точно соответствовать DPL (для несоответствующих сегментов).Почему есть два перекрывающихся сегмента данных (например, в ядре Linux)?

Однако ни одно из этих руководств (или любые связанные с ним вопросы по StackOverflow), в частности, говорят, почему нам нужны два сегмента данных. Они работают иначе, чем сегменты кода, поскольку процесс с CPL = 0 может обращаться к сегменту данных с DPL = 3.

Недостатком двух сегментов данных является перезагрузка DS, ES и т. Д., Если мы переключаемся между процессами с разными уровнями привилегий.

Так что мой конкретный вопрос: учитывая, что мы используем модель с плоской памятью, так что весь код и сегменты полностью перекрываются, какая цель служит для пользователя и сегмента данных ядра, в отличие от одного пользователя сегмент данных?

ответ

3

Существует пояснение here.

Цитирование из руководств Intel (раздел 5.7)

Privilege проверки уровня также происходит, когда регистр SS загружается селектором сегмента для сегмента стека.
Здесь все уровни привилегий, относящиеся к сегменту стека, должны соответствовать CPL; то есть CPL, RPL селектора сегментов стека и DPL дескриптора сегмента стека должны быть одинаковыми. Если RPL и DPL не равны для CPL, генерируется исключение общей защиты (#GP).

Упор шахта

То есть, SS требует сегмент данных с ЗПР равен 0, когда загружаются из ядра (или во время переключателей).
Это относится к 32-разрядному режиму.

В 64-битном режиме, it is possible to use a NULL selector, чтобы подавить любые проверки во время выполнения (включая предыдущий)

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

Из полноты, при выполнении операции стека всей необходимой информации, адрес размера, размера операнда и стеки-адрес размера, либо выделенные из кодового сегмента или неявно установлен в 64 биты.


Если я правильно помню, 64-битный режим до сих пор использует сегмент данных ядра, хотя, по соображениям совместимости.