Почему В Linux есть два сегмента данных, один для пользовательского режима, а другой для режима ядра?

Это во многом зависит от версии Gnome, которую вы используете:

В Gnome2 лучше всего использовать compiz (с плагином grid). Например, если вы нажмете ctrl+alt+numkey-left, активное окно займет левые 50% экрана. При повторном нажатии оно займет 2/3 экрана. А если нажать в третий раз, то оно займет 1/3 экрана.

Очевидно, compiz не совместим с Gnome3, так что вам придется использовать расширения оболочки. Я еще не пробовал ни одно из них, но вот:

  • gnome-shell-grid расширение - По-видимому, пытается имитировать поведение compiz, но я не нашел упоминания о том, что оно работает с третью экрана (упоминаются только половины).
  • gTile расширение - Кажется очень настраиваемым.
  • Put Windows расширение - Кажется очень простым в использовании.

3
07.04.2019, 02:34
1 ответ

Linux использует один и тот же дескриптор сегмента для SS (сегмента стека )и DS (сегмента данных ). Дескриптор сегмента SS должен иметь поле DPL, точно равное CPL, т. е. текущему уровню привилегий. Поэтому вам нужны отдельные дескрипторы сегментов данных для режима ядра и пользовательского режима.

Исходники (Мне лень скачивать руководства по ЦП)

Комментарий внутри определения gdt _страница:

We need valid kernel segments for data and code in long mode too. IRET will check the segment types. -- kkeil 2000/10/28

Веб-поиск :iret проверяет типы сегментов

Абхишек Ядав:

Instructions that load selectors into SS must refer to data segment descriptors for writable data segments. The descriptor privilege (DPL) and RPL must equal CPL. All other descriptor types or a privilege level violation will cause exception 13.

Веб-поиск :iret тип сегмента проверки ИЛИ "DPL" ИЛИ "CPL" "SS"

«Много, но конечно»:

... The exception is for the stack segment register ss, for which the three of CPL, RPL, and DPL must match exactly.

бохс -2.6.2/cpu/iret.cc :256:

    /* stack segment DPL must equal the RPL of the return CS selector,
     * else #GP(SS selector) */
    if (ss_descriptor.dpl != cs_selector.rpl) {
       BX_ERROR(("iret: SS.dpl != CS selector RPL"));
       exception(BX_GP_EXCEPTION, raw_ss_selector & 0xfffc);
    }

Предыстория :Почему в Linux есть отдельные сегменты кода для режима пользователя и режима ядра?

Связанный, еще один комментарий в исходном коде ядра:

We cannot use the same code segment descriptor for user and kernel mode, not even in long flat mode, because of different DPL.

Это происходит потому, что DPL текущего сегмента кода используется как CPL .

Я заметил, что вам также нужны разные сегменты кода для 32- и 64-битного кода-

https://en.wikipedia.org/wiki/Segment_descriptor-

L=Long-mode segment

If set, this is a 64-bit segment (and D must be zero), and code in this segment uses the 64-bit instruction encoding


Я предполагаю, что регистр сегмента DS сбрасывается при входе в ядро ​​​​из пользовательского пространства, по крайней мере, на x86 -32. Но мне не удалось определить код, который это делает.

Существует также недавняя статья LWN.net , в которой содержится интересный комментарий о наборе _fs ().

The original role of set_fs() was to set the x86 processor's FS segment register which, in the early days, was used to control the range of virtual addresses that could be accessed by unprivileged code. The kernel has... long since stopped using x86 segments this way.

2
27.01.2020, 21:24

Теги

Похожие вопросы