Файл: А. В. Гордеев А. Ю. Молчанов системное программное обеспечение электронный вариант книги издательства Питер СанктПетербург Челябинск юургу каф. Автоматика и управление 2002 2 Предисловие Настоящий учебник.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 12.01.2024

Просмотров: 1024

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

139
В пределах одной задачи используются сегменты с различным уровнем приви- легии и в определенные моменты времени выполняются или обрабатываются сег- менты с соответствующими им уровнями привилегии. Механизм проверки приви- легий работает в ситуациях, которые можно назвать межсегментными переходами
(обращениями). Это доступ к сегменту данных или стековому сегменту, межсег- ментные передачи управления в случае прерываний (и особых ситуаций), при ис- пользовании команд CALL, JMP, INT, IRET, RET. В таких межсегментных обра- щениях участвуют два сегмента: целевой сегмент (к которому мы обращаемся) и текущий сегмент кода, из которого идёт обращение.
Процессор сравнивает упомянутые значения CPL, RPL, DPL и на основе поня- тия эффективного уровня привилегий
1
(EPL=max(RPL, DPL)) ограничивает воз- можности доступа к сегментам по следующим правилам, в зависимости от того,
идёт ли речь об обращении к коду или к данным.
При доступе к сегментам данным проверяется условие CPL w EPL. Нарушение этого условия вызывает так называемую особую ситуацию ошибки защиты и воз- никает прерывание. Уровень привилегии сегмента данных, к которому осуществ- ляется обращение, должен быть таким же, как и текущий уровень, или меньше его.
Обращение к сегменту с более высоким уровнем привилегии воспринимается как ошибка, так как существует опасность изменения данных с высоким уровнем при- вилегий в программе с низким уровнем привилегии. Доступ к данным с меньшим уровнем привилегии разрешается.
Если целевой сегмент является сегментом стека, то правило проверки имеет вид CPL=DPL=RPL.
В случае его нарушения также возникает исключение. Поскольку стек может использоваться в каждом сегменте кода и всего имеются четыре уровня привиле- гий кода, то используются и четыре стека. Сегмент стека, адресуемый регистром
SS, должен иметь тот же уровень привилегий, что и текущий сегмент кода.
1
EPL (effective privilege level) – эффективный уровень привилегий. Значение эффективного уровня привилегий оп- ределяется минимальной привилегией, то есть как максимальное значение из двух: RPL и DPL.

140
Правила для передачи управления, то есть когда осуществляется межсегмент- ный переход с одного сегмента кода на другой сегмент кода, несколько сложнее.
Если для перехода с одного сегмента данных на другой сегмент данных считается допустимым обрабатывать менее привилегированные сегменты, то передача управления из высоко привилегированного кода на менее привилегированный код должна контролироваться дополнительно. Другими словами, код операционной системы не должен доверять коду прикладных задач. И обратно, нельзя просто так давать задачам возможность исполнять высоко привилегированный код, хотя по- требность в этом всегда имеется (ведь многие функции, в том числе и функции ввода/вывода, считаются привилегированными и должны выполняться только са- мой ОС). Для реализации возможностей передачи управления в сегменты кода с иными уровнями привилегий введен механизм шлюзования, который мы вкратце рассмотрим ниже. Итак, если DPL = CPL, то переход в другой сегмент кода возмо- жен. Более подробное рассмотрение затронутых вопросов по замыслу авторов вы- ходит за рамки настоящего учебника (для получения более детальных сведений по этому и некоторым другим вопросам особенностей архитектуры микропроцессоров i80x86 рекомендуется обратиться к материалам [1, 8]). Здесь мы рассмотрим только основные идеи.
Механизм шлюзов для передачи управления на сегменты кода с другими уровнями привилегий
Поскольку межсегментные переходы контролируются с использованием уров- ней привилегий и существует потребность в передаче управления с одного уровня привилегий на другой уровень, в микропроцессорах i80x86 реализован механизм
шлюзов, который мы поясним с помощью рис.3.9. Шлюзование позволяет орга- низовать обращение к так называемым подчинённым сегментам кода, которые вы- полняют часто встречающиеся функции и должны быть доступны многим задачам,
располагающимся на том же или более низком уровне привилегии.
Помимо дескрипторов сегментов системными объектами, с которыми работа- ет микропроцессор, являются специальные системные дескрипторы, названные шлюзами или вентилями. Главное различие между дескриптором сегмента и шлю- зом вызова заключается в том, что содержимое дескриптора указывает на сегмент в


141
памяти, а шлюз обращается к дескриптору. Другими словами, если дескриптор служит механизмом отображения памяти, то шлюз служит механизмом перена- правления.
Для получения доступа к более привилегированному коду задача должна об- ратиться к нему не непосредственно (путем указания дескриптора этого кода), а обращением к шлюзу этого сегмента (рис. 3.10).
В этом дескрипторе вместо адреса сегмента указываются селектор, позволяю- щий найти дескриптор искомого сегмента кода, и адрес (смещение назначения), с которого будет выполняться подчиненный сегмент, то есть полный 32-битный ад- рес. Формат дескриптора шлюза приведен на рис. 3.11. Адресовать шлюз вызова можно с помощью команды CALL
1
. По существу, дескрипторы щлюзов вызова не являются дескрипторами (сегментов), но они могут быть расположены среди обычных дескрипторов в дескрипторных таблицах процесса. Смещение, указывае- мое в команде перехода на другой сегмент (FAR CALL), игнорируется, и фактиче- ски осуществляется переход на команду, адрес которой определяется через смеще- ние из шлюза вызова. Этим гарантируется попадание только на разрешенные точки входа в подчиненные сегменты.
1   ...   8   9   10   11   12   13   14   15   ...   37

Рис. 3.9. Механизм шлюзов для перехода на другой уровень привилегий
1
FAR CALL – межсегментный вызов процедуры.
Адресное пространство программных модулей
Запрашиваемый программный
модуль
Уровень привилегий 0
Уровень привилегий 1
Уровень привилегий 2
Уровень привилегий 3
Адресное пространство
процесса А
шлюз
Адресное пространство
процесса В

142
Введены следующие правила использования шлюзов:
| значение DPL шлюза вызова должно быть больше или равно значению теку- щего уровня привилегий CPL;
| значение DPL шлюза вызова должно быть больше или равно значению поля
RPL селектора шлюза;
| значение DPL шлюза вызова должно быть больше или равно значению DPL
целевого сегмента кода;
| значение DPL целевого сегмента кода должно быть меньше или равно значе- нию текущего уровня привилегий CPL.
Рис.3.10. Переход на сегмент более привилегированного кода
Рис.3.11.Формат дескриптора шлюза
Сегмент Смещение
CALL
Дескриптор шлюза
Дескриптор сегмента кода
Сегмент кода с более
Высоким уровнем привилегий
Смещение назначения (биты 31-16)
P
DPL
0
1100
00
Счётчик
DWORD
Байт прав доступа
Селектор сегмента назначения
Смещение назначения (биты 15-0)
0
7
8
11
12
1
13
14
15
16
31
31
16 15
0
Старшее двойное слово дескриптора
Первое (младшее) двойное слово дескриптора

143
Требование наличия и доступности шлюза вызова для перехода на более при- вилегированный код ограничивает менее привилегированный код заданным набо- ром точек входа в код с большей привилегией. Так как шлюзы вызова являются элементами в дескрипторных таблицах (а мы говорили, что их не только можно, но и желательно там располагать), то менее привилегированная программа не может создать дополнительных (а значит, и неконтролируемых) шлюзов. Таким образом,
рассмотренный механизм шлюзов дает следующие преимущества в организации среды для выполнения надёжных вычислений:
| привилегированный код надёжно защищён и вызывающие его программы не могут его разрушить. Естественно, что такой системный код должен быть особенно тщательно отлаженным, не содержать ошибок, быть максимально эффективным;
| шлюзы межсегментных переходов для вызова системных функций делают эти самые системные функции невидимыми для программных модулей, рас- положенных на внешних (более низких) уровнях привилегий;
| шлюзы межсегментных переходов для вызова системных функций делают эти самые системные функции невидимыми для программных модулей, располо- женных на внешних (более низких) уровнях привилегий;
| поскольку вызывающая программа непосредственно адресует только шлюз вызова, реализуемые вызываемым модулем (сегментным кодом) функции можно изменить или переместить в адресном пространстве, не затрагивая интерфейс со шлюзом;
| программные модули вызываются с более привилегированного уровня.
Изложенный коротко аппаратный механизм защиты по привилегиям оказыва- ется довольно сложным и жёстким. Однако поскольку все практические ситуации учесть в схемах микропроцессора невозможно, то при разработке процедур опе- рационных систем и иного высоко привилегированного кода следует придержи- ваться приведенных ниже рекомендаций, заимствованных из книги [22].
Основной риск связан с передачей управления через шлюз вызова более при- вилегированной процедуре. Нельзя предоставлять вызывающей программе ника-


144
ких преимуществ, вытекающих из-за временного повышения привилегий. Это за- мечание особенно важно для процедур нулевого уровня привилегий (PL0–проце- дур).
Вызывающая программа может нарушить работу процедуры, передавая ей
«плохие» параметры. Поэтому целесообразно как можно раньше проконтролиро- вать передаваемые процедуре параметры. Шлюз вызова сам по себе не проверяет значений параметров, которые копируются в новый стек, поэтому достоверность каждого передаваемого параметра должна контролировать вызванная процедура.
Вот некоторые способы контроля передаваемых параметров.
1 Следует проверять счетчики циклов и повторений на минимальные и макси- мальные значения.
2 Необходимо проверить 8- и 16-битные параметры, передаваемые в 32–бит- ных регистрах. Когда процедуре передаётся короткий параметр, его следует рас- ширить со знаком или нулём для заполнения всего 32-битного регистра.
3 Следует стремиться свести к минимуму время работы процессора с запре- щёнными прерываниями. Если процедуре требуется запрещать прерывания, необ- ходимо, чтобы вызывающая программа не могла влиять на время нахождения про- цессора с запрещенными прерываниями (флажок IF=0).
4 Процедура никогда не должна воспринимать как параметр код или указатель кода.
5 В операциях процессора следует явно задавать состояние флажка направле- ния DF для цепочечных команд.
6 Заключительная команда RET или RETn в процедуре должна точно соответ- ствовать полю счетчика WC шлюза вызова; при этом n = 4x(WC
1
), так как счётчик задает число двойных слов, а n соответствует байтам.
7 Не следует применять шлюзы вызовов для функций, которым передаётся пе- ременное число параметров (см. рекомендацию 6). При необходимости нужно вос- пользоваться счётчиком и указателем параметров.
1
WC (Word Counter) – счётчик слов, см. рис. 3.11.

145 8 Функции не могут возвращать значения в стеке (см. рекомендацию 6), так как после возврата стеки процедуры и вызывающей программы находятся точно в таком состоянии, в каком они были до вызова.
9 В процедуре следует сохранять и восстанавливать все сегментные регистры.
Иначе, если какой-либо сегментный регистр привлекался для адресации данных,
недоступных вызывающей программе, процессор автоматически загрузит в него пустой селектор.
Рекомендуется контролировать все обращения к памяти. Нетрудно предста- вить себе, что РL3-программа передаст PL0-процедуре указатель селектор: смеще- ние и запросит считывание или запись нескольких байтов по этому адресу. Типич- ным примером может служить процедура дискового ввода/вывода, которая вос- принимает как параметр системный номер файла, счётчик байт и адрес, по кото- рому записываются данные с диска. Хотя PL0-процедура имеет привилегии для производства такой операции, но у РL3-программы разрешения на это может не быть.
Система прерываний 32-разрядных микропроцессоров i80x86
В микропроцессорах семейства i80x86 система прерываний построена таким образом, чтобы, с одной стороны, обеспечить возможность создавать эффективные и надёжные мультипрограммные операционные системы, которые должны функ- ционировать в защищённом режиме, а с другой стороны – обеспечить возможность выполнять программы, разработанные для реального режима. Рассмотрим коротко оба режима.
Работа системы прерываний в реальном режиме работы процессора
В реальном режиме работы система прерываний использует понятие вектора
прерывания. Термин «вектор прерываний» используется потому, что для указания адреса используется не одно значение, а два, то есть мы имеем дело не со скаляр- ной величиной, а с «векторной».
Итак, каждый вектор прерываний состоит из 4 байтов или 2 слов; первые два содержат новое значение для регистра IP, а следующие два – новое значение реги- стра CS. Таблица векторов прерываний занимает 1024 байта. Таким образом, в ней


146
может быть задано 256 векторов прерываний. В процессоре i8086 эта таблица рас- полагается на адресах 00000-003FFH. Расположение этой таблицы в процессорах i80286 и старше определяется значением регистра IDTR – Interrupt Descriptor Table
Register. При включении или сбросе процессора i80x86 этот регистр обнуляется.
Однако при необходимости можно в регистре IDTR указать смещение и, таким об- разом, перейти на новую таблицу векторов прерываний.
Таблица векторов прерываний заполняется (инициализируется) при запуске системы, но в принципе может быть изменена или перемещена.
Каждый вектор прерывания имеет свой номер, называемый номером прерыва- ния, который указывает его место в таблице. Этот номер, помноженный на четыре
(сдвиг на два разряда влево и заполнение освободившихся битов нулями), и сло- женный с содержимым регистра IDTR, дает абсолютный адрес первого байта век- тора в оперативной памяти.
Подобно вызову процедуры, прерывание заставляет микропроцессор сохра- нить в стеке информацию для последующего возврата, а затем перейти к группе команд, адрес которых определяется вектором прерывания. Таким образом, преры- вание вызывает косвенный переход к своей подпрограмме обработки за счёт по- лучения её адреса из вектора прерывания.
В IBM PC, как и в других вычислительных системах, прерывания бывают двух видов: внутренние и внешние.
Внутренние прерывания, как мы уже знаем, возникают в результате работы процессора. Они возникают в ситуациях, которые нуждаются в специальном обслу- живании, или при выполнении специальных инструкций – INT или INT0. Это сле- дующие прерывания:
| прерывание при делении на ноль; номер прерывания – 0;
| прерывание по флагу TF (trap flag
1
). В этом случае прерывание обычно ис- пользуется специальными программами отладки типа DEBUG. Номер прерывания
– 1;
1
Trap Flag – специальный бит в регистре PSW (program status word, слово состояния программы), который в случае значения TF=1 вызывает «останов» после каждой команды и генерируется прерывание для организации режима от- ладки с пошаговым выполнением программы. Чаще всего этот регистр в микропроцессорах Intel 80х86 называют
регистром флагов.

147
| инструкции INT (interrupt – выполнить прерывание с соответствующим но- мером) и INT0 (interrupt if overflow – прерывание по переполнению). Эти пре- рывания называются программными.
В качестве операнда команды INT указывается номер прерывания, которое нужно выполнить, например INT 10Н. Программные прерывания как средство пе- рехода на соответствующую процедуру были введены для того, чтобы выполнение этой процедуры осуществлялось в привилегированном режиме, а не в обычном пользовательском.
Внешние прерывания возникают по сигналу какого-нибудь внешнего устрой- ства. Существуют два специальных внешних сигнала среди входных сигналов про- цессора, при помощи которых можно прервать выполнение текущей программы и тем самым переключить работу центрального процессора. Это сигналы NMI (no mask interrupt, немаскируемое прерывание) и INTR (interrupt request, запрос на пре- рывание). Соответственно, внешние прерывания подразделяются на немаскируе- мые и маскируемые.
Маскируемые прерывания генерируются контроллером прерываний по заявке определенных периферийных устройств
2
. Контроллер прерываний (его обозна- чение – i8259A) поддерживает восемь уровней (линий) приоритета; к каждому уровню «привязано» одно периферийное устройство
1
. Маскируемые прерывания часто называют ещё аппаратными прерываниями. В ПК, начиная с IBM PC AT, по- строенных на базе микропроцессора i80286, используются два контроллера преры- ваний i8259A; они соединяются каскадным образом. Схема последовательного со- единения этих контроллеров изображена на рис. 3.12.
Таким образом, на IBM PC AT предусмотрено 15 линий IRQ
2
, часть которых используется внутренними контроллерами системной платы, а остальные заняты стандартными адаптерами либо не используются. Ниже перечислены линии запро- са на прерывание, которые мы приводим потому, что каждый специалист по вы- числительной технике должен знать основные стандарты ПК. Итак, линии IRQ:
0 – системный таймер;
2
Сигнал запроса на прерывание чаще всего является сигналом готовности внешнего устройства (соответствующего контроллера внешнего устройства) на выполнение следующей команды, связанной с управлением операциями вво- да/вывода.
1
В качестве внешнего периферийного устройства, занимающего одну линию запроса на прерывание, может быть использовано специальное управляющее устройство, которое позволяет разделять эту самую линию запроса между несколькими внешними устройствами.
2
IRQ (Interrupt Request) – запрос на прерывание.