На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Все статьи должны быть оформлены согласно Правил оформления статей.
2. Любые обсуждения должны происходить в специальной теме, обсуждение в любых других темах раздела запрещены.
3. Запрещается писать статьи о создании и распространении вирусов, троянов и других вредоносных программ!
4. За грамотно написанные и правильно оформленные статьи авторы награждаются DigiMoney.

Дополнительные ссылки:
Желаю творческих успехов! ;)
Модераторы: Jin X
  
    > Реальный и защищенный режимы процессора , Общие вопросы
       
      Реальный и защищенный режимы работы процессора

      Главным недостатком работы процессора в реальном режиме (он устанавливается с момента запуска процессора, и в нем работает ДОС) является то, что любое приложение может нарушить работу системы. Чтобы избежать этого был придуман защищенный (начиная с i80386).
      Прим.: вообще говоря, с i80286, но с весьма ограниченных набором возможностей.
      Главным образом защищается память.


      Модель памяти защищенного режима

      В реальном режиме физический адрес формируется - seg:offset -> (seg<<4)+offset. И доступен только первый мегабайт (0ffff0h+0ffffh).
      В защищенном режиме физический адрес формируется немного сложнее. Теперь логический адрес определяется селектором (в сегментном регистре) : смещением.

      Формат селектора:
      ExpandedWrap disabled
        +15----------------+-2+1-0+
        |Индекс дескриптора|TI|RPL|
        +------------------+--+---+
      • Индекс дескриптора - индекс в предварительно сформированной таблице дескрипторов. GDT - глобальная таблица, LDT - локальная таблица дескрипторов.
      • Бит TI определяет, к какой таблице относится селектор. 0 - GDT, 1 - LDT.
      • RPL (Requested Privilege Level) определяет требуемый уровень привилегий для работы с селектором.

      Таблицы дескрипторов представляют собой массив структур дескрипторов. Причем первый дескриптор в GDT не используется, должен быть пустым.

      Дескриптор:
      ExpandedWrap disabled
        Байты:
          7           6          5          4     3     2   1          0
        +-----------+----------+----------+---------------+--------------+
        | База сег. | Атрибуты | Атрибуты | База сегмента |   Граница    |
        |  (биты    |    2     |    1     | (биты 0..23)  |   сегмента   |
        |  24..31)  |          |          |               | (биты 0..15) |
        +-----------+----------+----------+---------------+--------------+
                        /             \
                       /               \
                  Атрибуты 2        Атрибуты 1
            +7+6+5+4+-3------0-+  +7+6+5+4+3---0+
            | |D| |A| Граница  |  | |   | |     |
            |G|/|0|V| сегмента |  |P|DPL|S| Тип |
            | |B| |L| (16..19) |  | |   | |     |
            +-+-+-+-+----------+  +-+---+-+-----+
      • База сегмента - линейный адрес в памяти.
      • Граница сегмента - размер сегмента.
      • G (Granularity) - определяет, в чем измеряется размер сегмента. 0 - в байтах, 1 - в 4кб страницах.
      • D/B (Default operation size/Default stack pointer/or upper Bound flag) - флаг разрядности сегмента: 0 - 16 бит, 1 - 32 бита. В сегменте кода определяет разрядность по умолчанию (смена возможна префиксами 66h, 67h). Если это стек, то определяет что использовать esp (1) или sp (0).
      • AVL (Available) - этот флаг используется по усмотрению системы.
        Прим.: этот бит ещё называют U (User), т.е. пользовательский.
      • P (Present) - Присутствует ли сегмент: 0 - нет (в этом случае при попытке обратится к нему вызывается исключение отсутствия сегмента), 1 - да.
      • DPL (Descriptor Privilege Level) - определяет уровень привилегии сегмента.
      • S (Segment/System) - тип дескриптора: 0 - системный, 1 - сегмент данных или кода.
      • Тип - тип дескриптора:
        Если S=1, то нулевой бит типа определяет, было ли к нему обращение, а значение битов 3..1:
        0 - только чтение;
        1 - чтение и запись;
        2 - расширение вниз + чтение;
        3 - расширение вниз + чтение и запись;
        4 - только исполнение;
        5 - исполнение и чтение;
        6 - подчиненный сегмент + исполнение;
        7 - подчиненный сегмент + исполнение и чтение.

        Системные дескрипторы. Тип:
        0, 8 - недопустимые значения;
        1 - доступный сегмент состояния задачи (TSS) 80286;
        2 - таблица локальных дескрипторов (LDT);
        3 - занятый TSS 80286;
        4 - шлюз вызова 80286 (call gate);
        5 - шлюз задачи (task gate);
        6 - шлюз прерывания 80286 (interrupt gate);
        7 - шлюз ловушки 80286 (trap gate);
        9 - Доступный TSS 80386+;
        A - зарезервировано;
        B - занятый TSS 80386+.
        C - шлюз вызова (call gate);
        D - зарезервирован;
        E - шлюз прерывания (interrupt gate);
        F - шлюз ловушки (trap gate);

      В TASM это обычно описывается структурой:
      ExpandedWrap disabled
        GdtDescr struc
                limit       dw  ?
                base_low    dw  ?
                base_mid    db  ?
                attr1       db  ?
                attr2       db  ?
                base_high   db  ?
        GdtDescr ends

      Итак. Когда рассмотрели структуры данных защищенного режима, пора определить, как формируется физический адрес из sel:offset. В селекторе (он хранится в сегментном регистре) берется индекс дескриптора. По этому индексу ищется дескриптор в таблице GDT или LDT (в зависимости от бита TI). Проверяется, есть ли этот сегмент в памяти, CPL (Current Privilege Level - определяется полем RPL у cs) <= DPL (это будет рассмотрено отдельно), проверяется выход за границу, на исполнение, запись или чтение, в случае неудачи вызывается исключение.
      Далее берется база. База + offset = линейный адрес. При отключенной страничной адресации это и будет физическим адресом.

      Адрес GDT и LDT определяется регистрами соответственно GDTR и LDTR. Их структура:

      GDTR:
      ExpandedWrap disabled
        +-47------------------16-+-15----0-+
        | Линейный базовый адрес | Граница |
        +------------------------+---------+
      Граница = размер в байтах GDT - 1
      Для лучшей производительности таблица должна быть выровнена на 8 байт.

      LDTR:
      ExpandedWrap disabled
        +-15-----0-+
        | Селектор |
        +----------+

      Загрузка их осуществляется командами:
      • lgdt addr_m48 - загружает GDTR из памяти, куда указывает addr_m48
      • lldt addr_m16/r16 - загружает LDTR из памяти, куда указывает addr_m16 или из 16-ти разрядного регистра.

      Основные правила защиты по привилегиям:
      Уровни привилегий часто именуют кольцами защиты. Изменяются от 0 (самый высокий уровень привилегий) до 3 (наименьшие привилегии).
      • К данным возможно обращение только при CPL<=DPL
      • Вызов процедуры только при CPL>=DPL и только через шлюз
      • Привилегированные команды (lgdt, lidt, cli...) выполняются только при CPL=0.

      Прерывания и исключения в защищенном режиме

      Обработчики прерываний и исключений определяются таблицей дескрипторов прерываний (IDT).
      Дескриптор шлюза (дескриптор из IDT) имеет структуру:
      ExpandedWrap disabled
        Байты
          7           6   5          4          3      2   1          0
        +---------------+----------+----------+----------+--------------+
        |   Смещение    | Атрибуты | Атрибуты | Селектор |   Смещение   |
        | (биты 16..31) |    2     |    1     |          | (биты 0..15) |
        +---------------+----------+----------+----------+--------------+
                        /             \
                       /               \
                  Атрибуты 2        Атрибуты 1
               +7+6-5+4+3---0+   +7+6+5+4-----0+
               | |   | |     |   | | | | Word  |
               |P|DPL|0| Тип |   |0|0|0| count |
               | |   | |     |   | | | |       |
               +-+---+-+-----+   +-+-+-+-------+
      • Смещение - адрес обработчика.
      • Селектор - селектор кода, где он находится.
      • P (Present) - при попытке обратится к недействительному шлюзу (Р=0) вызывается исключение отсутствия сегмента.
      • DPL (Descriptor Privilege Level) - требуемый уровень привилегий, для обращения к этому шлюзу.
      • Тип - тип шлюза:
        5 - шлюз задачи (task gate);
        6 - шлюз прерывания 80286 (interrupt gate);
        7 - шлюз ловушки 80286 (trap gate);
        E - шлюз прерывания (interrupt gate);
        F - шлюз ловушки (trap gate);
      • Word count - используется только в шлюзах вызовов и определяет число слов из стека взывающей задачи, копируемых в стек вызываемой процедуры.

      В TASM это обычно описывается структурой:
      ExpandedWrap disabled
        IdtDescr struc
            l_off       dw  ?
            sel     dw  ?
            res     db  ?
            attr        db  ?
            h_offs      dw  ?
        IdtDescr ends

      Расположение IDT определяется регистром IDTR.
      • lidt addr_m48 - загружает IDTR из памяти, куда указывает addr_m48 (структура такая же, как и у GDTR).

      Таблица может содержать до 256 прерываний, и минимальный размер 256 байт (32 дескриптора). Обязательные 32 входа в IDT - исключения:
      ExpandedWrap disabled
        +------+-----------------------------------------------------------+-------------+-----------+
        |  No  |                    Исключение                             | Обозначение |    Тип    |
        +------+-----------------------------------------------------------+-------------+-----------+
        |   0  | Деление на 0                                              |     #DE     |     F     |
        |   1  | Исключение отладки (трассировка)                          |     #DB     |    F/T    |
        |   2  | Немаскируемое прерывание                                  |      -      | Interrupt |
        |   3  | Исключение отладки                                        |     #BP     |     T     |
        |   4  | Исключение по переполнению (into)                         |     #OF     |     T     |
        |   5  | Прерывание по контролю диапазона (bound)                  |     #BR     |     F     |
        |   6  | Недопустимый код операции                                 |     #UD     |     F     |
        |   7  | Сопроцессор недоступен или переключилась задача           |     #NM     |     F     |
        |   8  | Двойной отказ                                             |     #DF     |  A,EC=0   |
        |   9  | Нарушение границы сегмента сопроцессором (только 386/387) |             |     F     |
        |  10  | Недоступный сегмент состояния задачи (TSS)                |     #TS     |   F,EC    |
        |  11  | Сегмент отсутствует                                       |     #NP     |   F,EC    |
        |  12  | Ошибка сегмента стека                                     |     #SS     |   F,EC    |
        |  13  | Общее нарушение защиты                                    |     #GP     |   F,EC    |
        |  14  | Ошибка страницы                                           |     #PF     |   F,EC    |
        |  15  | Зарезервировано                                           |             |           |
        |  16  | Исключение сопроцессора                                   |     #MF     |     F     |
        |  17  | Контроль выравнивания(486+)                               |     #AC     |  F,EC=0   |
        |  18  | Машинный контроль(P5+)                                    |     #MC     |   A,EC    |
        |  19  | Исключение SIMD(XMM)                                      |     #XF     |     F     |
        |20..31| Зарезервировано                                           |             |           |
        +------+-----------------------------------------------------------+-------------+-----------+
      • F (Fault) - отказ. После обработки этого исключения, управление передается на инструкцию, которая его вызвала.
      • T (Trap) - ловушка. Управление передается после инструкции, которая его вызвала.
      • A (Abort) - авария. Не позволяет точно установить инструкцию, его вызвавшую. Серьезное нарушение.
      • EC (Error Code) - передается код ошибки.

      Формат кода ошибки (у ошибки страницы имеет другой формат):
      ExpandedWrap disabled
        +31--------16+15----3+-2+-1-+-0-+
        | Резерв (0) | Index |TI|IDT|EXT|
        +------------+-------+--+---+---+
      • Index - определяет дескриптор.
      • TI: 0 - GDT, 1 - LDT.
      • IDT: 0 - GDT или LDT, 1 - IDT.
      • EXP - внешнее событие (аппаратное прерывание).

      Cтек в обработчике прерывания:
      ExpandedWrap disabled
        +------------+ <-ESP в обработчике.
        | Код ошибки | - если требуется
        +------------+
        |    EIP     |
        +------------+
        |    CS      |
        +------------+
        |  EFLAGS    |
        +------------+
        |    ESP     | - только при смене привилегий
        +------------+
        |    SS      | - только при смене привилегий
        +------------+ <- ESP до вызова

      Переход в защищенный режим

      Системный регистр CR0:
      ExpandedWrap disabled
        31  30        18  16                    0
        +-+-+-+-------+-+-+-+-------+-+-+-+-+-+-+
        |P|C|N|       |A| |W|       |N|E|T|E|M|P|
        |G|D|W|       |M| |P|       |E|T|S|M|P|E|
        +-+-+-+-------+-+-+-+-------+-+-+-+-+-+-+
         | | |         |   |        | | | | | |
         | | |         |   |        | | | | | +-- Protection Enable
         | | |         |   |        | | | | +---- Monitor Processor Extension
         | | |         |   |        | | | +------ Processor Extension Emulated
         | | |         |   |        | | +-------- Task Switch
         | | |         |   |        | +---------- Extension Type
         | | |         |   |        +------------ Numeric Error
         | | |         |   +--------------------- Write Protect
         | | |         +------------------------- Alignment Mask
         | | +----------------------------------- Not WriteThrough
         | +------------------------------------- Cache Disable
         +--------------------------------------- Paging Enable
      Нас пока интересует только бит PE. Если он установлен, процессор работает в защищенном режиме, иначе - реальном.
      Для работы с ним (только младшие 16 бит) в 80286 предназначались команды lmsw и smsw. В новых процессорах можно работать с ним, используя mov (это более предпочтительно).

      Для того чтобы перейти в защищенный режим, надо выполнить несколько действий:
      • Инициализировать GDT.
      • Запретить маскируемые прерывания. Во время перехода не должны происходить аппаратные прерывания.
      • Загрузить GDTR.
      • В CR0 установить бит PE.
      • Используя jmp far или call far инициализировать cs:eip.
      • Инициализировать остальные сегментные регистры.
      • Перепрограммировать контроллер прерываний.
      • Инициализировать IDT и загрузить IDTR.
      • Разрешить прерывания.

      Переключение в реальный режим:
      Прим.: он же "режим реальных адресов" (real-address mode) - так даже правильнее, но длиннее :).
      • Запретить маскируемые прерывания.
      • Передать управление сегменту с лимитом 64k.
      • Сбросить бит PE в CR0.
      • Инициализировать cs:ip (как в п.5 перехода в защищенный режим).
      • Загрузить в сегментные регистры новые значения.
      • Инициализировать IDTR (lim=3FFh, base=0).
      • Разрешить прерывания.

      Примечание. Если при возврате не изменить сегментные регистры, то получается "нереальный" режим, в котором через эти регистры можно обращаться к памяти > 1Mb (как в защищенном режиме).
      Прим.: UnReal Mode, он же BigReal Mode, он же Flat Real Mode.

      Использованная литература

      [1] "Intel Architecture Software Developer's Manual. Volume 3. System Programming".

      Автор статьи - rcz
      Примечания - Jin X
      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0321 ]   [ 15 queries used ]   [ Generated: 26.04.24, 09:14 GMT ]