close

Вход

Забыли?

вход по аккаунту

?

Kychin 0AC163F1B3

код для вставкиСкачать
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное автономное
образовательное учреждение высшего образования
САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ
АППАРАТНЫЕ СРЕДСТВА ПОДДЕРЖКИ
ОПЕРАЦИОННЫХ СИСТЕМ
Методическое пособие
Санкт-Петербург
2015
Составитель – Н. В. Кучин
Рецензенты: профессор А. А. Шалыто, кандидат технических наук,
доцент М. А. Волохов
Содержатся сведения об аппаратной поддержке функционирования операционных систем на примере работы процессоров типа i80х86 в защищенном режиме. Рассматриваются вопросы использования регистров процессора и инструкций, характерных для защищенного режима, организации сегментной и сегментно-страничной памяти, защиты данных и программных
кодов различных уровней доступа. Особо выделены вопросы, связанные с
использованием специальных устройств в составе процессора, предназначенных для повышения быстродействия выполняемых программ. Кроме
того, подробно освещены вопросы, связанные с переключением задач и обработкой прерываний в защищенном режиме.
Отдельное внимание уделено вопросу влияния аппаратуры вычислительных систем на способы проектирования операционных систем.
Публикуется в авторской редакции.
Компьютерная верстка М. И. Дударева
Подписано к печати 09.12.15. Формат 60 × 84 1/16.
Бумага офсетная. Усл. печ. л. 2,5. Тираж 100 экз. Заказ № 512.
Редакционно-издательский центр ГУАП
190000, Санкт-Петербург, Б. Морская ул., 67
© Санкт-Петербургский государственный
университет аэрокосмического
приборостроения, 2015
Введение
Процессоры семейства i80х86, начиная с процессора 80386, способны работать в двух режимах: в режиме реальных адресов (реальный режим) и в режиме защищённой памяти (защищённый
режим). В составе этого процессора имеются различные блоки и
устройства, осуществляющие поддержку функционирования операционных систем.
Основным режимом работы процессора является защищённый
режим, при котором обеспечивается многозадачность, специальный механизм защиты памяти, сегментная или сегментно-страничная организация памяти, кэширование страниц и данных. В защищённом режиме используется 32-х разрядная адресная шина,
поэтому адресуемая физическая память имеет размер 4гб. Дальнейшее изложение материала будет ориентировано на объяснение
механизмов функционирования, характерных для защищенного
режима.
В реальном режиме процессор выполняет шестнадцатиразрядные инструкции (команды) и адресует 1мб. памяти.
3
Регистры процессора i80x86
Набор основных функциональных регистров процессора, в первую очередь, направлен на реализацию основных возможностей защищённого режима (многозадачность, защита памяти и т. д.), а их
содержимое определятся текущей выполняемой задачей.
Регистры общего назначения
Восемь 32-разрядных регистров общего назначения предназначены для хранения данных и адресов и имеют имена EAX , EBX,
ECX, EDX, ESI, EDI, EBP , ESP. Они поддерживают работу с данными разрядностью 1, 8, 16, 32, и 64 бита (см. рис. 1). Младшие 16 разрядов этих регистров доступны отдельно при использовании имён
AX, BX, CX, DX, SI, DI, BP, SP. При операциях с байтами можно
обращаться к старшим и младшим байтам регистров AX, BX, CX,
DX. В этом случае старшие байты будут иметь имена – AH, BH, CH,
DH, а младшие – AL, BL, CL, DL. Программный доступ к отдельным байтам повышает возможности программирования.
Регистры сегментов (селекторы)
С помощью этих шести 16-ти разрядных регистров обеспечивается обращение к текущему сегменту задачи, а в защищённом режиме эти регистры называются селекторами. Кроме того, для целей ускорения определения адресов внутри сегментов, с каждым из
селекторов связан невидимый 8-ми байтовый регистр, назначение
которого будет рассмотрено далее.
CS – хранит указатель на дескриптор кодового сегмента в одной
из таблиц дескрипторов сегментов (GDT или LDT);
31
16
0
AH
AX
AL
BH
BX
BL
CH
CX
CL
DH
DX
DL
SI
DI
BP
SP
Рис. 1
4
15
15 3
Index
TI
2 1
0
RPL
Рис. 2
SS – хранит указатель на дескриптор сегмента стека в одной из
таблиц дескрипторов сегментов;
DS, ES, FS, GS – хранят указатели на дескрипторы сегментов
данных в одной из таблиц дескрипторов сегментов;
Структура селекторов представлена на рис. 2:
Index – индекс (номер) дескриптора в таблице дескрипторов сегмента;
TI – тип таблицы (если TI=0, то GDT, если TI=1, то LDT);
RPL – значение уровня привилегий запроса (от 0 до 3).
Указатели инструкций
EIP – указатель команд, содержит относительный 32-х разрядный адрес текущей инструкции, т. е. смещение относительно базового адреса кодового сегмента. Его содержимое является программно недоступным.
EFLAGS – 32-х разрядный регистр флагов, содержит признаки
результата выполнения текущей команды, используется при обработке исключений и маскируемых прерываний, при определении
последовательности вызываемых задач, при управлении вводом/
выводом и рядом других процедур. В дальнейшем, описание содержимого отдельных полей и битов этого регистра будет осуществляться по мере необходимости.
Управляющие 32-х разрядные регистры
CR0 – его содержимое определяет признаки работы процессора
(признак режима, вкл/выкл сегментно-страничной организации памяти, выполнение команд с плавающей точкой и т.д.). Нас будет, прежде всего, интересовать содержимое младшего бита этого регистра
(PE– protect enable). При PE=0, процессор функционирует в реальном
режиме, а при PE=1, процессор переходит в защищённый режим.
CR1 – не используется (в резерве).
CR2 – для хранения линейного виртуального адреса, вызвавшего страничный отказ. Страничный отказ связан с отсутствием страницы в оперативной памяти в момент адресации к ней.
CR3 – физический адрес таблицы разделов текущей выполняемой задачи, используемой при сегментно-страничной организации
памяти.
5
CR4 – признаки, разрешающие работу архитектурных расширений ( возможность использования страниц размером в 4Мб).
Регистры системных адресов
GDTR – 48-ми разрядный регистр, значение которого определяет характеристики GDT (Global Descriptor Table) – глобальной таблицы дескрипторов сегментов.
IDTR – 48-ми разрядный регистр, значение которого определяет характеристики IDT (Interrupt Descriptor Table) – таблицы дескрипторов прерываний. Структуры этих регистров идентичны и
представлены на рис. 3.
TR – 16-ти разрядный указатель на дескриптор специального сегмента (TSS), входящего GDT. В сегменте TSS (Task State
Segment) хранится контекст текущей выполняемой задачи;
LDTR – 16-ти разрядный указатель на дескриптор в GDT ,
в котором , в свою очередь , хранится адрес LDT (Local Descriptor
Table) – локальной таблицы дескрипторов текущей выполняемой
задачи. Структуры этих регистров идентичны и представлены на
рис.4. Кроме того, с этими регистрами связаны “невидимые” 8-ми
байтовые регистры, используемые для ускорения процесса адресации и переключения задач.
Регистры отладки (DR0, … ,DR7) и регистры тестирования
(TR3, … ,TR7), используемые для проверки корректности работы
внутренних блоков процессора, не являются средствами непосредственной аппаратной поддержки функционирования операционных
систем и подробно рассматриваться не будут.
47
16 15 Адрес GDT
Размер GDT
Адрес IDT
Размер IDT
Рис. 3
15 0
Указатель на дескриптор TSS
Указатель на LDT
Рис. 4
6
0
Новые команды процессора,
используемые в защищённом режиме
Команды общего назначения
bound – проверка индекса массива относительно границ массива.
bsf/bsr – команды сканирования битов.
bt/btc/btr/bts – команды выполнения битовых операций.
enter – создание кадра стека для параметров процедур языка высокого уровня.
imul reg,imm – умножение операнда со знаком на непосредственное значение.
ins/outs – ввод/вывод из порта в строку.
j(cc) – команды условного перехода, допускающие 32-битовое
смещение.
leave – выход из процедуры языка высокого уровня и восстановление регистров, записанных в стек команд enter.
lss/lfs/lgs – команды загрузки сегментных регистров.
mov DRx,reg; reg,TRx – команды обмена данными со специальными регистрами. В качестве источника или приёмника могут
быть использованы регистры CR0…CR3, DR0…DR7, TR3…TR5.
movsx/movzx – знаковое/беззнаковое расширение до размера
приёмника и пересылка.
push imm – запись в стек непосредственного операнда размером
в байт, слово или двойное слово (например push 0FFFFFFFFh).
pusha – запись в стек всех 16-разрядных регистров общего назначения (AX, BX, CX, DX, SP, BP, SI, DI).
popa – извлечение из стека 16-разрядных регистров общего назначения (AX, BX, CX, DX, SP, BP, SI, DI).
pushad – запись в стек всех 32-разрядных регистров общего назначения (EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI).
popad – извлечение из стека всех 32-разрядных регистров общего назначения (EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI).
rcr/rcl/ror/rol reg/mem,imm – циклический сдвиг на непосредственно заданное значение.
sar/sal/shr/shl reg/mem,imm – арифметический сдвиг на непосредственно заданное значение.
shrd/shld – установка байта по условию.
Команды защищённого режима
arpl – корректировка значения поля RPL селектора.
clts – сброс флага переключения задач в регистре CR0.
lar – загрузка байта разрешения доступа.
7
lgdt – загрузка регистра таблицы глобальных дескрипторов
GDTR.
lidt – загрузка регистра таблицы дескрипторов прерываний
IDTR.
lldt – загрузка регистра таблицы локальных дескрипторов
LDTR.
lmsw – загрузка слова состояния.
lsl – загрузка границы сегмента.
ltr – загрузка регистра задачи.
sgdt – сохранение регистра таблицы глобальных дескрипторов
GDTR.
sidt – сохранение регистра таблицы дескрипторов прерываний
IDTR.
sldt – сохранение регистра таблицы локальных дескрипторов
LDTR.
smsw – сохранение слова состояния.
ssl – сохранение границы сегмента.
str – сохранение регистра задачи.
verr – проверка доступности сегмента для чтения на текущем
уровне привилегий.
verw – проверка доступности сегмента для записи на текущем
уровне привилегий.
Примеры использования некоторых перечисленных выше команд покажем в приведённой далее программе.
text segment ‘code’ use16
Assume CS;text, DS;data
begin: mov Ax,data
mov DS,AX
; Основной фрагмент программы
mov EAX, 0FF000000h
mov EBX, 64h
mov CL,0Ah
; Сдвиг содержимого EBX влево на 0Ah
shld EBX,EAX,CL
; бит и объединение его содержимого с ; содержимым EAX. Результат будет в EBX.
; Проверка разрядов в регистре EBX,
bsf AX, EBX
; начиная с младшего, и запись номера
; первого слева разряда, в котором
; Проверка разрядов в регистре EBX,
bsr DX, EBX
; начиная со старшего, и запись
; номера первого справа разряда, в
8
мov dword ptr sum, EBX
; Завершение программы
mov AX, 4C00h
int 21h
text ends
data segment
sum dd
0
data ends
end begin
; котором находится 1, в регистр DX.
; Сохранение суммы
В программе выполняется умножение содержимого регистра
EBX на два в десятой степени. Для этого используется команда сдвига влево на 10 разрядов (0Ah). С помощью этой же команды обеспечивается прибавление к полученному результату числа
3FCh. Слагаемое предварительно записывается в регистр EAX, содержимое которого при выполнении команды побитно перемещается в регистр EBX, начиная со старшего разряда. Поскольку выполняется сдвиг на 10 разрядов, в регистре EAX находится число
0FF000000h.
Следующие две команды вычисляют номера разрядов, в которых находится старший и младший отличные от нуля биты полученного числа. Старший бит определяется командой сканирования, начиная со старшего разряда – bsr и помещается в регистр DX.
Для определения младшего бита используется команда bsl.
9
Дескрипторы сегментов
и виртуальное адресное пространство
При сегментной организации памяти виртуальное адресное пространство определяется всем множеством сегментов. Код и данные
задачи представляют некоторое множество сегментов. Загружаемым в память объектом является сегмент задачи. Каждый сегмент
имеет свой описатель – дескриптор сегмента, в котором хранятся
параметры конкретного сегмента. Значения некоторых параметров
сегмента могут меняться за период выполнения задачи. Структура
такого 8-ми байтового дескриптора имеет следующий вид:
Из рис. 5 видно, что значение размера сегмента сосредоточено
в нулевом, первом и, частично, в шестом байте дескриптора. Значение начального( базового) 32-х разрядного адреса сегмента в памяти распределено между вторым, третьим, четвёртым и седьмым
байтах дескриптора.
Шестой байт дескриптора состоит из нескольких полей, а именно:
битовое поле G( 7-й бит) задаёт значение признака измерения размера сегмента (если G=0 , то в байтах , если G=1 ,то в страницах);
битовое поле D( 6-й бит ) задаёт значение признака размерности
слов, входящих в сегмент (если D=0 ,то 16-ти битные слова, если
D=1 , то 32-ух битные слова).
5-й бит всегда принимает нулевое значение, 4-й бит может принимать любое значение (Х).
Биты с нулевого по третий используются для хранения старших
разрядов значения размера сегмента.
Особую и очень важную роль играет содержимое 5-го байта –
байта “прав доступа”(см.рис. 6).
Битовое поле P(7-й бит) задаёт значение признака присутствия/
отсутствия сегмента в памяти (если P=1, то сегмент в памяти).
3 байт 2 байт 1 байт База (биты 0 – 15)
База
(биты 24–
31)
7 байт G
D
0
X
Размер сегмента (биты 0 – 15)
Размер
(биты
16–19)
6 байт P
DPL
Тип
сегмента и
признаки
доступа
5 байт (права доступа) Рис. 5
10
0 байт
База
(биты
16–23)
4 байт
7
6
P
7
5
DPL
6
P
7
P
DPL
4
S=1
5
DPL
3
2
S=0
5
6
4
4
S=1
1
0
1
0
Тип
3
2
Е=1
С
3
2
E=0
ED
R
A
1
W
0
A
Рис. 6
Поле DPL (Descriptor Privilege Level), состоящее из 2-х бит( 5-й
и 6-й биты) задаёт значение уровня привилегий сегмента, его значение может изменяться от 0 до 3. Значение DPL необходимо при
проверке прав доступа к сегменту.
Остальные пять битов в байте прав доступа используются для
определения типа сегмента (данные, стек, код, системный сегмент)
и способ использования сегмента (читать, писать, выполнять, только читать и т.д.).
Если четвёртый бит S=0, то такие дескрипторы будут называться системными и являться описателями системных или специальных сегментов (TSS). При S=1 дескрипторы являются описателями
кодовых сегментов, сегментов данных или стека задачи.
Если третий бит Е=1, то это дескриптор кодового сегмента, для
которого:
– поле С=1(2-й бит) означает, что соответствующий кодовый сегмент является “подчинённым”, а при C=0 – “неподчинённым”. Понятие подчинённости сегмента будет рассмотрено далее;
– поле R=1(1-й бит) разрешает считывание кодового сегмента, а
при R=0 такое считывание не разрешается;
– поле A(бит обращения)( 0-й бит) устанавливается в единицу
при обращении к сегменту. Для невостребованных сегментов значение этого поля будет равняться нулю. Значение поля A используется при реализации механизма свопинга.
Если третий бит E=0, то речь идёт о дескрипторах сегментов данных и стека. Такие сегменты имеют следующие характерные признаки:
– поле ED (2-й бит) определяет размещение сегмента относительно его базового адреса. При ED=0, данные в сегменте размещаются в направлении возрастания адресов до границы, определяемой
11
размером сегмента. При ED=1 данные в сегменте располагаются
в направлении уменьшения адресов, что характерно для сегментов
стека.
– поле W (1-й бит) используется для сегментов данных. При W=1
разрешается модификация содержимого сегмента( разрешение на
запись), при W=0 разрешается только считывание данных; – поле А( 0-й бит) имеет то же назначение, что и соответствующее поле
в дескрипторе кодового сегмента.
При загрузке задач в оперативную память дескрипторы сегментов
каждой загружаемой задачи объединяются в соответствующие таблицы. Микропроцессор использует три типа таблиц дескрипторов:
GDT – глобальная таблица дескрипторов;
LDT – локальная таблица дескрипторов;
IDT – таблица дескрипторов прерываний.
В GDT содержатся:
– дескрипторы сегментов операционной системы;
– дескрипторы сегментов TSS пользовательских задач;
– специальные дескрипторы (шлюзы), используемые при переключении задач и межзадачного взаимодействия;
– дескрипторы сегментов с указанием на локальные таблицы дескрипторов сегментов пользовательских задач.
Таблица GDT хранится в памяти в одном экземпляре и объединяет в себя дескрипторы сегментов, определяющих общее виртуальное адресное пространство.
В LDT объединяются дескрипторы сегментов конкретной пользовательской задачи. Такие сегменты в совокупности определяют
локальное виртуальное пространство конкретной задачи. Количество в памяти локальных таблиц определяется числом активных
задач.
Максимальное число дескрипторов, находящихся в одной
таблице – 213, следовательно максимальный размер таблицы –
213**2 3=64кб.
Определение линейного исполнительного адреса при сегментной
организации памяти выполняется во время выполнения программы. Доступ к сегменту возможен только при соблюдении соответствующих прав доступа, которые будут рассмотрены далее. Схема
получения линейного адреса, в случае, когда дескриптор адресуемого сегмента находится в глобальной таблице дескрипторов GDT
(в селекторе поле TI=0), выглядит следующим образом (рис. 7).
Линейный адрес определяется в два этапа. На первом этапе
определяется местоположение дескриптора сегмента в таблице
12
Селектор
Index
TI
=0
Смещение
RPL
EIP
GDT
+
GDTR
Сегмент
+
База
Размер
Рис. 7
GDT путём сложения содержимого поля Index селектора и регистра процессора GDTR. На втором этапе базовый адрес сегмента,
извлекаемый из соответствующего дескриптора, складывается со
значением регистра EIP, что даёт значение линейного адреса. При
сегментной организации памяти линейный адрес рассматривается
как физический адрес внутри адресуемого сегмента, не требующий
дальнейших преобразований.
В случае, когда дескриптор адресуемого сегмента находится
в локальной таблице дескрипторов LDT, определение линейного
адреса производится в три этапа (рис.8). На первом этапе определяется местоположение специального дескриптора из состава GDT,
в котором хранится значение базового адреса LDT. Это осуществляется путём сложения значений GDTR и LDTR. На втором этапе
определяется местоположение дескриптора из состава LDT путём
сложения базового адреса LDT и значения поля Index селектора.
На третьем этапе непосредственно определяется линейный адрес
путём сложения базового адреса сегмента и значения EIP.
При обращении к сегменту, который в данный момент отсутствует в оперативной памяти (в байте прав доступа дескриптора
признак P=0), вызывается соответствующее прерывание, обработка которого заключается в вызове процедуры подкачки сегмента из
внешней памяти.
Так как линейный адрес определяется во время выполнения
программы, необходимо чтобы это осуществлялось как можно
быстрее. Поэтому, с каждым из селекторов связан “невидимый”
13
Селектор
Смещение
TI RPL
Index =1
EIP
GDTR
GDT
+
+
База
Сегмент
LDT
База
+
LDTR
Рис. 8.
(скрытый) 8-ми байтовый регистр, в котором хранится дескриптор
текущего адресуемого сегмента. Наличие такого регистра позволяет непосредственно через него адресоваться к сегменту, минуя обращения к таблицам, если это повторные обращения к данному сегменту. Содержимое этих регистров будет меняться только в случае
обращения к новому сегменту. Использование таких “невидимых”
регистров значительно ускоряет процесс определения линейных
адресов сегментов, и является специальным средством кэширования дескрипторов сегментов.
14
Защита данных при сегментной организации памяти
Для защиты информации, хранящейся в сегментах памяти, используется система привилегий, которая регулирует доступ к тому
или иному сегменту в зависимости от уровня его защищённости и
степени важности (привилегированности) запроса. В процессоре
i80х86 установлены четыре уровня привилегий (рис. 9).
0 – ядро операционной системы (максимальная защищённость),
1 – утилиты операционной системы,
2 – служебные программы,
3 – пользовательские программы.
Правила доступа к сегментам основываются на сравнении следующих значений:
RPL – запрашиваемый уровень привилегий (задаётся битами 0
и 1 селектора);
CPL – текущий уровень привилегий выполняемого кода (хранится в селекторе кода CS), т. е. CPL = RPL селектора кода;
EPL – max(CPL,RPL) – эффективный уровень привилегий;
DPL – действительный уровень привилегий сегмента (задаётся
в 5-м байте прав доступа дескриптора сегмента, биты 5 и 6). Наиболее защищённый сегмент имеет значение DPL=0, а наименее защищённый DPL=3.
Доступ к сегментам данных разрешается, если EPL<=DPL. Это
означает, что доступ к сегменту данных возможен как из собствен-
3
2
1
0
Рис. 9
15
ной программы, так и из программного сегмента, имеющего более
высокий уровень привилегий. Нарушение этого правила вызывает
соответствующее прерывание и доступ к сегменту откладывается.
Доступ к сегментам стека разрешается, если DPL=RPL(в селекторе SS)=CPL. Это означает, что доступ к сегменту стека возможен
только из программного сегмента, имеющего тот же уровень привилегий, что и сегмент стека. Кроме того доступ к сегменту стека будет
разрешён, если значение признака W в байте прав доступа дескриптора сегмента будет равно единице. В противном случае, произойдёт
прерывание и в доступе к сегменту стека будет отказано.
Доступ к сегментам кода определяется в зависимости от типа
кодового сегмента, к которому идёт обращение. Кодовые сегменты
могут быть подчинёнными или неподчинёнными. Подчинённый
сегмент хранит код вызываемого программного модуля, вызов к которому имеется в некотором основном программном модуле. Такой
вызов может осуществляться с помощью команд CALL, RET, INT,
IRET. Подчинённый сегмент идентифицируется битом С=1 в байте
прав доступа дескриптора сегмента. Правило доступа к подчинённому сегменту определяется как DPL>= CPL, т. е. к подчинённому
сегменту могут обращаться программы ,имеющие такой же или более высокий уровень привилегий. Схема обращения к подчинённому сегменту выглядит следующим образом (рис. 10):
Значение поля Index селектора определяет местоположение
дескриптора в одной из таблиц дескрипторов. Значение базового
Селектор CS
EIP
GDT или LDT
+
Дескриптор
База Размер С DPL
Рис. 10
16
Сегмент
адреса сегмента, извлекаемое из дескриптора, складывается с содержимым EIP и определяет значение линейного адреса внутри
подчинённого кодового сегмента.
Доступ к неподчинённым сегментам (С=0) ,обычно связан с доступом к более привилегированным сегментам, в частности к кодовым сегментам из состава ядра операционной системы. Такой
доступ осуществляется с помощью специальных дескрипторов, называемых шлюзами (вентилями). Шлюзы содержат указатели на
обычные дескрипторы сегментов, находящиеся в той же таблице
дескрипторов. Структура шлюза представлена на рис. 11.
В байтах 2 и 3 дескриптора шлюза содержится значение селектора вызываемого сегмента программы, а байты 0, 1, 6, 7 задают
относительный адрес процедуры, к которой идёт обращение (точка входа в программу внутри сегмента). Байт прав доступа шлюза
имеет вид (рис. 12):
Поле T (3-й бит) задаёт конкретный тип процессора и определяет
особенности формирования линейного адреса для различных типов
процессора.
Поле WC, состоящее из пяти бит, в четвёртом байте указывает
количество параметров, которые переносятся из стека текущей
программы в стек новой программы, к которой произошло обращение. Число переносимых параметров из старого стека в новый стек
может составлять от 0 до 31.
Правило доступа к неподчинённым сегментам определяется как
CPL<=DPL шлюза. При использовании шлюзов задачи с меньшим
уровнем привилегий могут вызывать более привилегированные за3 байт
2 байт
1 байт Селектор
Относительный адрес (биты 0 – 15)
Относительный адрес
(биты 16–31)
7 байт 0 байт
Р
6 байт
DPL
0
0
0
5 байт (права доступа) WC
(биты
0–4)
4 байт
Рис. 11
7
P
6
DPL
5
4
0
3
2
1
T
1
0
0
0
Рис. 12
17
Index
TI RPL
EIP
Сегмент
GDT или LDT
Шлюз
Селектор Смещение
+
Дескриптор
База
Рис. 13
дачи. Схема обращения к неподчинённому сегменту представлена
на рис. 13.
Из этой схемы видно, что значение поля селектора шлюза используется для определения дескриптора сегмента адресуемой
новой программы (процедуры). Сложение относительного адреса,
извлекаемого из соответствующего поля шлюза, и базового адреса
сегмента, извлекаемого из дескриптора сегмента новой программы, даёт значение начального адреса новой программы (процедуры) относительно начала сегмента. Значение регистра EIP в формировании линейного адреса не используется.
В защищённом режиме работы процессора i80х86 модули, входящие в ядро операционной системы и имеющие высший уровень
привилегий, могут содержать в своём коде привилегированные команды. К таким командам относятся:
– команды для работы с управляющими регистрами CRn, а также для загрузки системных адресов GDTR, LDTR, IDTR, и TR;
– команда останова процессора HALT;
– команды запрета/разрешения маскируемых прерываний
CLI/SLI;
– команды ввода-вывода IN, INS, OUT, OUTS.
Первые две группы команд могут выполняться только при самом
высшем уровне привилегий кода, то есть при CPL=0. Для двух последних групп команд их выполнение будет разрешаться, если CPL
<= IOPL, где IOPL – значение уровня привилегий ввода-вывода.
18
Сегментно-страничная организация памяти
Признаком сегментно-страничной организации памяти является значение PG=1 (31бит в регистре CR0). В этом случае линейный
адрес, получаемый при сегментной организации памяти, считается
виртуальным и требует своего дальнейшего преобразования с целью
определения исполнительного физического адреса внутри страницы.
Сегмент разбивается на отдельные разделы, максимальное число которых для одного сегмента может достигать 210, а каждый
раздел может состоять из 210 страниц. Размер каждой страницы –
2–20 байт. Поэтому линейный адрес рассматривается как элемент,
состоящий из трёх полей: table – младшие 10 бит указателя на дескриптор текущей используемой таблицы страниц , page – младшие
10 бит указателя на дескриптор текущей используемой страницы,
byte – младшие 12 бит исполнительного адреса внутри страницы.
Физическая память рассматривается как множество физических
станиц, имеющих размер в 4Кб, причём, границы физических
страниц жёстко фиксированы.
Процессор для каждого адресуемого сегмента создаёт в памяти
каталог разделов, а для каждого каталога таблицу страниц. Элементами, как каталога разделов, так и таблицы страниц являются
4-х байтные дескрипторы. Регистр CR3 используется для хранения
значения старших 20-ти байт начального адреса каталога разделов
текущего адресуемого сегмента. Схема получения исполнительного адреса выглядит следующим образом (рис. 14):
31
table
22 21
page
Каталог
разделов
+
Дескриптор
таблицы
страниц
12 11
byte
Таблица
страниц
+
Дескриптор
страницы
0
Страница
+
CR3(31–12б)
Рис. 14
19
Исполнительный адрес внутри страницы определяется за три
обращения к памяти – к каталогу разделов, к таблице страниц и
непосредственно к самой странице. Адреса внутри таблиц и исполнительный адрес определяются путём логического сложения старших бит базовых адресов (12–31), хранящихся в CR3 и в дескрипторах, и соответствующих полей исполнительного адреса.
Дескрипторы таблицы страниц и дескрипторы страниц имеют
идентичную структуру, представленную на рис. 15:
P – бит присутствия, если P=1, то таблица страниц или сама
страница находится в памяти. Если же P=0, то обращение к соответствующему разделу или странице запрещено и попытка их использования вызовет соответствующее прерывание;
R/W – определяет права доступа к странице со стороны программ пользователя (уровень привилегий равён трём);
U/S – определяет возможность доступа к странице, если U/S=0 доступ запрещается, если U/S=1 и R/W=1 разрешается чтение и запись;
PWT – определяет метод обновления внешней кэш-памяти, при
PWT=1– с и сквозная запись (одновременное обновление основной
и кэш-памяти), при PWT=0 – обратная запись;
PCD – разрешение/запрет кэширования во внутренней памяти
процессора, при PCD=1 запрещается загрузка страницы во внутреннюю кэш-память;
A – автоматически устанавливается в 1 при обращении к данной
таблице страниц или странице;
D – признак модификации страницы, если D=1 – в страницу
осуществлялась запись. Для указателей таблиц страниц, значение
бита D является неопределённым.
Биты A и D используются операционной системой, поддерживающей виртуальную память, для определения в оперативной памяти разделов и страниц, которые подлежат замене и откачке во
внешнюю память (механизм свопинга). Проверку и сброс этих битов осуществляет операционная система.
Биты 9–11 дескриптора зарезервированы для операционной системы, которая может использовать их для своих потребностей. Напри31
Базовый адрес
12 11–9 8–7
6
5
Резерв 0 0
D
A
Рис. 15
20
4
3
2
1
PCD PWT U/S R/W
0
P
мер, в этих битах может размещаться информация о времени последнего обращения к разделу или странице. Такая информация может
использоваться для определения разделов и страниц, подлежащих
замене в оперативной памяти при реализации механизма свопинга.
Сегментно-страничная организация памяти требует дополнительных затрат для преобразования линейного адреса в физический
исполнительный адрес внутри страницы, причём эти затраты могут
быть весьма значительными и отрицательно влиять на производительность вычислительной системы. Существенное сокращение времени преобразования адресов достигается путём использования специального устройства в составе процессора – буфера ассоциативной
трансляции (TLB – Translation Look aside Buffer).
Буфер ассоциативной трансляции и кэширование памяти.
Буфер ассоциативной трансляции (TLB) является памятью с ассоциативной выборкой.
TLB состоит из 8-ми наборов (рис. 16). В каждый набор входят –
четыре семнадцатиразрядных тега, логика обслуживания и четыре
регистра для хранения дескрипторов страниц. Логика обслуживания базируется на трёх битах обращения (b0, b1, b2) и четырёх битах действительности (v0, v1, v2, v3).
31
тег
15 14
12 11 Смещение
Дескрипторы
страниц
Набор № 0
Теги
0
b0
v0
b1
v1
v2
b2
v3
Набор № 7
Рис. 16
21
При использовании TLB линейный адрес рассматривается как совокупность трёх полей – поле тега (ключа), поле индекса и поле, в котором хранится значение смещения относительно начала страницы.
При обращении к TLB ассоциативная процедура поиска состоит
в следующем:
– значение индекса в соответствующем поле линейного адреса
определяет номер набора в TLB;
– параллельное сравнение значения ключа (в линейном адресе)
со значениями тегов в наборе, и в случае равенства, последующее
определение наличия дескриптора в регистре хранения (соответствующее значение бита действительности должно быть установлено в единицу).
В случае “кэш-попадания” происходит сложение старших битов, хранящихся в дескрипторе, со смещением в линейном адресе,
что даёт значение исполнительного адреса внутри страницы.
В случае “кэш-промаха” реализуется многоступенчатая процедура определения исполнительного адреса, описанная выше (рис. 14).
Одновременно происходит запись в соответствующий набор TLB значения дескриптора адресуемой страницы, с установкой одного из битов действительности в единицу. Это необходимо для последующих
обращений к данной странице. Запись дескриптора страницы осуществляется в первую свободную строку набора. Если же все строки
заняты, то запись осуществляется в строку, к которой дольше всего
не обращались, а старое значение дескриптора считается на данный
момент “ненужным”.
Биты обращения используются при реализации замещения
“ненужных ” дескрипторов страниц. Такое замещение производится в соответствии с упрощённой дисциплиной PseudoLRU
(Pseudo Least Recently Used). Установка же значений битов обращений b0, b1, b2 осуществляется по специальному алгоритму
в зависимости от значений строк набора L0, L1, L2, L3 и сводится
к следующему:
1. Проверка– последнее обращение было к паре L0, L1? Если да,
то b0=1, если нет b0=0;
2. При b0=1 проверка – последнее обращение к L0? Если да, то
b1=1, если нет b1=0, конец;
3. При b0=0 проверка – последнее обращение к L2? Если да, то
b2=1, если нет b2=0, конец.
Данная процедура не всегда приводит к выбору строки, к которой
дольше всех не было обращения. Но в большинстве случаев этот алгоритм даёт результат, совпадающий с оптимальным результатом.
22
В TLB кэшируются дескрипторы страниц, количество которых
может достигать 32-х. Следовательно, объём кэшируемой с помощью TLB памяти составляет 32*4кб=128кб. При использовании
TLB количество “кэш-попаданий” достигает 98%, что значительно
ускоряет получение исполнительного адреса.
Кроме того, в составе процессора i80х86 имеется кэш-память
первого уровня, в которой кэшируются данные. Эта память организована аналогично TLB и позволяет кэшировать объём до 16 Кбайт.
В такой кэш-памяти единицей хранения является байт данных.
Обновление данных в кэше происходит блоками по 16 байт. В случае использования кэш-памяти первого уровня уже известный
физический адрес рассматривается как совокупность трёх полей –
младшие 4 бита как смещение в блоке, следующие 8 бит как индекс
указывающий на номер набора, а старшие биты как значение тега
(ключа), указывающее на номер блока. Для хранения блоков данных в кэше отводятся строки, имеющие объём 16 байт. Структура
кэш-памяти первого уровня представлена на рис. 17.
Также как и TLB, выбор строки в наборе осуществляется на
основе анализа битов действительности v0, v1, v2, v4 и битов обращения b0, b1, b2 по алгоритму PseudoLRU. Блок данных заносится в строку кэш-памяти вместе с тегом – старшими разрядами
основной памяти, а бит действительности устанавливается в 1. При
возникновении запроса на чтение из основной памяти сначала делается попытка найти данные к кэш-памяти. По индексу, извлечённому из адреса запроса, определяется номер набора, в котором
могут быть искомые данные. Затем для строк из данного набора,
содержимое которых действительно (биты действительности установлены в 1), выполняется ассоциативный поиск путём сравнения
старших разрядов адреса со значениями тегов набора. При совпадении этих значений (кэш-попадание) из соответствующей строки
извлекается байт, смещение которого относительно начала строки
определяется значением поля смещения в задаваемом адресе.
Для согласования данных в кэш-памяти первого уровня используется метод сквозной записи, т. е. при возникновении запроса на
запись обновляется как содержимое соответствующей ячейки основной памяти так её копии в кэш-памяти, если она там находится.
При кэш-промахе запрос на запись не вызывает обновление кэшпамяти.
При обработке запроса к основной памяти могут использоваться
разные виды кэш-памяти. Прежде всего, будет сделана попытка использования невидимого регистра при соответствующем селекторе
23
31
тег
12 11
Теги
Индекс
Набор № 0
4 3 Смещение 0
Блок данных
b0
v0
b1
v1
b2
v2
v3
Набор № 256
Рис. 17
с целью получения дескриптора адресуемого сегмента. Затем будет
использоваться буфер ассоциативной трансляции TLB, в котором
кэшируются дескрипторы страниц. Использование TLB позволяет
достичь очень высокого процента кэш-попаданий. Далее, при известном физическом адресе, искомый операнд может быть обнаружен в кэш-памяти первого уровня.
24
Многозадачность. Переключение задач
При переключении задач используются специальные сегменты – TSS (Task State Segment). Сегменты TSS поддерживаются процессором i80х86 в защищённом режиме, и создаются в оперативной памяти при её активизации. По своему функциональному назначению сегмент TSS представляет собой описатель контекста задачи. Дескриптор, указывающий на TSS, всегда находится в GDT.
Структура TSS представлена на рис 18.
Битовая карта ввода-вывода (БККВ)
Дополнительная информация ОС
Относительный адрес БККВ
0…0
| T
0…0
Селектор LDT
0…0
GS
0…0
FS
0…0
DS
0…0
SS
0…0
0…0
CS
ES
EDI
ESI
EBP
ESP
EBX
EDX
ECD
EAX
EFLAGS
EIP
CR3
0...0
SS уровня 2
ESP2
0...0
SS уровня 1
ESP1
0...0
SS уровня 0
ESP0
0...0
Селектор TSS возврата
Рис. 18
25
Сегмент TSS имеет фиксированные поля, отведённые для хранения содержимого регистров процессора, как универсальных, так и
некоторых управляющих (например, CR3).
Для доступа задачи к портам ввода-вывода процессор использует в защищённом режиме поле IOPL (Input/Output Privilege Level)
в своём регистре EFLAGS и карту битовых полей доступа к портам в сегменте TSS. Чтобы выполнять команды ввода-вывода значение текущего CPL не выше, чем уровень привилегий операций
ввода-вывода, задаваемый значением поля IOPL в регистре флагов
EFLAGS, т. е. CPL<= IOPL. Если же это условие не соблюдается, то
возможность доступа к порту с конкретным адресом определяется
значением соответствующего бита в карте ввода-вывода сегмента
TSS (карта состоит из 8Кбайт для описания доступа к 65536 портам) – значение 0 разрешает операцию ввода-вывода с данным номером порта.
Кроме того сегмент TSS может включать дополнительную информацию, необходимую для работы задачи и зависящую от конкретной операционной системы.
Поле селектора возврата в составе TSS используется для хранения значения CS ранее выполняемой задачи. Контекст задачи представляет собой набор значений регистров процессора, необходимых
для начала выполнения задачи. БКВВ – битовая карта ввода/вывода, используется для указания внешних устройств, необходимых
для выполнения задачи.
Переключение задач осуществляется с помощью ассемблерной
команды CALL с указанием пары значений CS:EIP. Порядок переключения задач следующий:
1. Сохраняются значения всех рабочих регистров процессора
в текущем сегменте TSS. Для этого используется регистр TR, указывающий на дескриптор TSS в составе GDT.
2. Происходит обращение к TSS новой задачи по следующей схеме (рис. 19):
3. В TR загружается новое значение, соответствующее значению
CS или значению поля селектора в шлюзе.
4. Из нового TSS в регистр LDTR переносится значение селектора таблицы LDT в таблице GDT задачи.
5. В регистры процессора загружаются соответствующие значения из соответствующих полей TSS новой задачи.
6. В поле селектора возврата нового TSS загружается значение
CS старой задачи.
7. Начало выполнения новой задачи.
26
CALL CS : EIP
LDT
GDT
Шлюз
Дескриптор
TSS
Селектор
TSS
Адрес Граница
Рис. 19
Из вышесказанного следует, что переключение задач является
довольно сложной процедурой. Поэтому, при её реализации, активно используются невидимые регистры при селекторах, что позволяет ускорить процесс переключения задач.
27
Обработка прерываний
При обработке прерываний в защищённом режиме используется таблица IDT (Interrupt Descriptor Table) , поддерживаемая
процессором i80х86. Составляющими элементами IDT являются
8-ми байтовые дескрипторы обработчиков прерываний, которые
по своей структуре представляют собой шлюзы и называются коммутаторами.
В регистре IDTR хранится начальный адрес IDT, а номер прерывания, который указывается в соответствующих запросах при
обращении к обработчикам прерываний, показывает местоположение коммутатора в IDT относительно начального адреса.
Коммутаторы могут быть 3-х типов:
1. коммутатор прерываний (interrupt gate),
2. коммутатор перехвата (trap gate),
3. коммутатор задачи (task gate).
Первые два типа коммутаторов вызывают переход на выполнение соответствующих сегментов кода, принадлежащих виртуальному адресному пространству текущего вычислительного процесса. Другими словами, обработка прерываний при использовании
этих коммутаторов осуществляется под контролем текущей задачи
и смены контекста не происходит. Обращение к сегменту кода, содержащего обработчик прерывания, в этом случае, производится
по следующей схеме (рис. 20):
№ прерывания
+
IDT
GDT
Коммутатор
прерывания
Дескриптор
Сегмента
Селект. Смещен.
Адрес Граница
IDTR
Рис. 20
28
+
Сегмент
с кодом
обработчика
прерываний
По номеру прерывания ищется соответствующий коммутатор из
IDT. Далее определяется тип прерывания путём анализа содержимого байта прав доступа коммутатора.
Если его тип соответствует коммутатору interrupt gate или trap
gate, то выполняются следующие действия.
В стек на уровне привилегий текущего сегмента кода помещаются:
1. значения SS и SP, если уровень привилегий в коммутаторе
выше уровня привилегий ранее исполнявшегося кода;
2. значение регистра флагов EFLAGS;
3. значения регистров CS и EIP.
Отличие в использовании коммутаторов прерываний и коммутаторов перехвата состоит в том, что при использовании первых
запрещается обработка новых прерываний на период обработки текущего прерывания (устанавливается флаг IF=0 в регистре
EFLAGS).
Использование коммутаторов задачи вызывает переключение
процессора на новую задачу, представляющую собой обработчик
прерываний. При этом происходит смена контекста задачи. Обращение к новой задаче производится по следующей схеме (рис. 21):
Последовательность действий в этом случае следующая:
1. Сохраняются все рабочие регистры процессора в текущем сегменте TSS, базовый адрес которого берётся из “невидимого” регистра при TR.
2. Текущая задача отмечается как занятая.
№
прерывания
IDT
+
GDT
Коммутатор
задачи
TSS
Дескриптор TSS
Адрес
селектор
IDTR
Рис. 21
29
3. По селектору из Task Gate выбирается новый TSS (поле селектора помещается в регистр TR) и загружается контекст новой задачи. Загрузка контекста новой задачи означает загрузку значений
LDTR, EFLAGS, восемь регистров общего назначения, EIP и шесть
сегментных регистров (селекторов).
4. Устанавливается бит NT (next task).
5. В поле обратной связи TSS помещается значение селектора
прерванной задачи.
6. Значения CS:EIP, взятые из нового TSS, позволяют определить и выполнить первую команду обработчика прерываний.
Достоинством использования коммутаторов task gate является
то, что сохраняются значения всех регистров процессора при обращении к обработчику прерываний. Тогда как при использовании
коммутаторов типа interrupt gate и trap gate сохраняется содержимое только регистров EFLAGS, CS, EIP.
Использование коммутаторов задачи task gate при обработке
прерываний связано с большими временными затратами. Поэтому,
при создании соответствующих программ программисты стараются использовать обработчики прерываний, выполняемые в контексте исполняемой задачи без переключения на новую задачу.
30
Влияние аппаратных средств на
организацию операционных систем
Многие операционные системы успешно работают на различных
аппаратных платформах без существенных изменений в своем составе. Во многом это объясняется тем, что, несмотря на различия
в деталях, средства аппаратной поддержки ОС большинства компьютеров приобрели сегодня много типовых черт, а именно эти
средства в первую очередь влияют на работу компонентов операционной системы. В результате в ОС можно выделить достаточно компактный слой машинно-зависимых компонентов ядра и сделать
остальные слои ОС общими для разных аппаратных платформ.
Четкой границы между программной и аппаратной реализацией функций ОС не существует – решение о том, какие функции ОС
будут выполняться программно, а какие аппаратно, принимается
разработчиками аппаратного и программного обеспечения компьютера. Тем не менее практически все современные аппаратные
платформы имеют некоторый типичный набор средств аппаратной
поддержки ОС, в который входят следующие компоненты:
– средства поддержки привилегированного режима;
– средства трансляции адресов;
– средства переключения процессов;
– система прерываний;
– системный таймер;
– средства защиты областей памяти.
Средства поддержки привилегированного режима обычно основаны на системном регистре процессора, часто называемом «словом состояния» машины или процессора. Этот регистр содержит
некоторые признаки, определяющие режимы работы процессора,
в том числе и признак текущего режима привилегий. Смена режима привилегий выполняется за счет изменения слова состояния машины в результате прерывания или выполнения привилегированной команды. Число градаций привилегированности может быть
разным у разных типов процессоров, наиболее часто используются
два уровня (ядро-пользователь) или четыре (например, ядро– супервизор– выполнение– пользователь у платформы VAX или 0–12–3 у процессоров i80 x86). В обязанности средств поддержки привилегированного режима входит выполнение проверки допустимости выполнения активной программой инструкций процессора при
текущем уровне привилегированности.
Средства трансляции адресов выполняют операции преобразования виртуальных адресов, которые содержатся в кодах процесса,
31
в адреса физической памяти. Таблицы, предназначенные при трансляции адресов, обычно имеют большой объем, поэтому для их хранения используются области оперативной памяти, а аппаратура
процессора содержит только указатели на эти области. Средства
трансляции адресов используют данные указатели для доступа
к элементам таблиц и аппаратного выполнения алгоритма преобразования адреса, что значительно ускоряет процедуру трансляции
по сравнению с ее чисто программной реализацией.
Средства переключения процессов предназначены для быстрого сохранения контекста приостанавливаемого процесса и восстановления контекста процесса, который становится активным. Содержимое контекста обычно включает содержимое всех регистров
общего назначения процессора, регистра флагов операций (то есть
флагов нуля, переноса, переполнения и т. п.), а также тех системных регистров и указателей, которые связаны с отдельным процессом, а не операционной системой, например указателя на таблицу
трансляции адресов процесса. Для хранения контекстов приостановленных процессов обычно используются области оперативной
памяти, которые поддерживаются указателями процессора.
Переключение контекста выполняется по определенным командам процессора, например по команде перехода на новую задачу.
Такая команда вызывает автоматическую загрузку данных из сохраненного контекста в регистры процессора, после чего процесс
продолжается с прерванного ранее места.
Система прерываний позволяет компьютеру реагировать на
внешние события, синхронизировать выполнение процессов и работу устройств ввода-вывода, быстро переходить с одной программы на
другую. Механизм прерываний нужен для того, чтобы оповестить
процессор о возникновении в вычислительной системе некоторого
непредсказуемого события или события, которое не синхронизировано с циклом работы процессора. Примерами таких событий могут
служить завершение операции ввода-вывода внешним устройством
(например, запись блока данных контроллером диска), некорректное завершение арифметической операции (например, переполнение регистра), истечение интервала астрономического времени.
При возникновении условий прерывания его источник (контроллер
внешнего устройства, таймер, арифметический блок процессора и
т. п.) выставляет определенный электрический сигнал. Этот сигнал
прерывает выполнение процессором последовательности команд,
задаваемой исполняемым кодом, и вызывает автоматический переход на заранее определенную процедуру, называемую процедурой
32
обработки прерываний. В большинстве моделей процессоров отрабатываемый аппаратурой переход на процедуру обработки прерываний сопровождается заменой слова состояния машины (или даже
всего контекста процесса), что позволяет одновременно с переходом по нужному адресу выполнить переход в привилегированный
режим. После завершения обработки прерывания обычно происходит возврат к исполнению прерванного кода.
Прерывания играют важнейшую роль в работе любой операционной системы, являясь ее движущей силой. Действительно, большая часть действий ОС инициируется прерываниями различного
типа. Даже системные вызовы от приложений выполняются на
многих аппаратных платформах с помощью специальной инструкции прерывания, вызывающей переход к выполнению соответствующих процедур ядра (например, инструкция int в процессорах
Intel или SVC в мэйнфреймах IBM).
Системный таймер, часто реализуемый в виде быстродействующего регистра-счетчика, необходим операционной системе для
выдержки интервалов времени. Для этого в регистр таймера программно загружается значение требуемого интервала в условных
единицах, из которого затем автоматически с определенной частотой начинает вычитаться по единице. Частота «тиков» таймера,
как правило, тесно связана с частотой тактового генератора процессора. (Не следует путать таймер ни с тактовым генератором,
который вырабатывает сигналы, синхронизирующие все операции
в компьютере, ни с системными часами – работающей на батареях
электронной схеме, – которые ведут независимый отсчет времени и
календарной даты.) При достижении нулевого значения счетчика
таймер инициирует прерывание, которое обрабатывается процедурой операционной системы. Прерывания от системного таймера
используются ОС в первую очередь для слежения за тем, как отдельные процессы расходуют время процессора. Например, в системе разделения времени при обработке очередного прерывания
от таймера планировщик процессов может принудительно передать управление другому процессу, если данный процесс исчерпал
выделенный ему квант времени.
Средства защиты областей памяти обеспечивают на аппаратном уровне проверку возможности программного кода осуществлять с данными определенной области памяти такие операции,
как чтение, запись или выполнение (при передачах управления).
Если аппаратура компьютера поддерживает механизм трансляции
адресов, то средства защиты областей памяти встраиваются в этот
33
механизм. Функции аппаратуры по защите памяти обычно состоят
в сравнении уровней привилегий текущего кода процессора и сегмента памяти, к которому производится обращение.
Одна и та же операционная система не может без каких-либо изменений устанавливаться на компьютерах, отличающихся типом
процессора или/и способом организации всей аппаратуры. В модулях ядра ОС не могут не отразиться такие особенности аппаратной
платформы, как количество типов прерываний и формат таблицы
ссылок на процедуры обработки прерываний, состав регистров
общего назначения и системных регистров, состояние которых
нужно сохранять в контексте процесса, особенности подключения
внешних устройств и многие другие.
Однако опыт разработки операционных систем показывает:
ядро можно спроектировать таким образом, что только часть модулей будут машинно-зависимыми, а остальные не будут зависеть от
особенностей аппаратной платформы. В хорошо структурированном ядре машинно-зависимые модули локализованы и образуют
программный слой, естественно примыкающий к слою аппаратуры. Такая локализация машинно-зависимых модулей существенно упрощает перенос операционной системы на другую аппаратную
платформу.
Объем машинно-зависимых компонентов ОС зависит от того, насколько велики отличия в аппаратных платформах, для которых
разрабатывается ОС. Например, ОС, построенная на 32-битовых
адресах, для переноса на машину с 16-битовыми адресами должна
быть практически переписана заново. Одно из наиболее очевидных
отличий – несовпадение системы команд процессоров – преодолевается достаточно просто. Операционная система программируется
на языке высокого уровня, а затем соответствующим компилятором
вырабатывается код для конкретного типа процессора. Однако во
многих случаях различия в организации аппаратуры компьютера
лежат гораздо глубже и преодолеть их таким образом не удается. Например, однопроцессорный и двухпроцессорный компьютеры требуют применения в ОС совершенно разных алгоритмов распределения
процессорного времени. Аналогично отсутствие аппаратной поддержки виртуальной памяти приводит к принципиальному различию в реализации подсистемы управления памятью. В таких случаях не обойтись без внесения в код операционной системы специфики
аппаратной платформы, для которой эта ОС предназначается.
Для уменьшения количества машинно-зависимых модулей
производители операционных систем обычно ограничивают уни34
версальность машинно-независимых модулей. Это означает, что
их независимость носит условный характер и распространяется
только на несколько типов процессоров и созданных на основе этих
процессоров аппаратных платформ. По этому пути пошли, например, разработчики ОС Windows NT, ограничив количество типов
процессоров для своей системы четырьмя и поставляя различные
варианты кодов ядра для однопроцессорных и многопроцессорных
компьютеров.
Особое место среди модулей ядра занимают низкоуровневые
драйверы внешних устройств. С одной стороны эти драйверы, как
и высокоуровневые драйверы, входят в состав менеджера вводавывода, то есть принадлежат слою ядра, занимающему достаточно
высокое место в иерархии слоев. С другой стороны, низкоуровневые драйверы отражают все особенности управляемых внешних
устройств, поэтому их можно отнести и к слою машинно-зависимых модулей. Такая двойственность низкоуровневых драйверов
еще раз подтверждает схематичность модели ядра со строгой иерархией слоев.
Для компьютеров на основе процессоров i80 x86 разработка
экранирующего машинно-зависимого слоя ОС несколько упрощается за счет встроенной в постоянную память компьютера базовой
системы ввода-вывода – BIOS. BIOS содержит драйверы для всех
устройств, входящих в базовую конфигурацию компьютера: жестких и гибких дисков, клавиатуры, дисплея и т. д. Эти драйверы выполняют весьма примитивные операции с управляемыми устройствами, например чтение группы секторов данных с определенной
дорожки диска, но за счет этих операций экранируются различия
аппаратных платформ персональных компьютеров и серверов на
процессорах Intel разных производителей. Разработчики операционной системы могут пользоваться слоем драйверов BIOS как
частью машинно-зависимого слоя ОС, а могут и заменить все или
часть драйверов BIOS компонентами ОС.
Если код операционной системы может быть сравнительно легко перенесен с процессора одного типа на процессор другого типа
и с аппаратной платформы одного типа на аппаратную платформу
другого типа, то такую ОС называют переносимой (portable), или
мобильной.
Хотя ОС часто описываются либо как переносимые, либо как
непереносимые, мобильность – это не бинарное состояние, а понятие степени. Вопрос не в том, может ли быть система перенесена, а
в том, насколько легко можно это сделать. Для того чтобы обеспе35
чить свойство мобильности ОС, разработчики должны следовать
следующим правилам.
Большая часть кода должна быть написана на языке, трансляторы которого имеются на всех машинах, куда предполагается переносить систему. Такими языками являются стандартизованные языки
высокого уровня. Большинство переносимых ОС написано на языке С, который имеет много особенностей, полезных для разработки
кодов операционной системы, и компиляторы которого широко доступны. Программа, написанная на ассемблере, является переносимой только в тех случаях, когда перенос операционной системы
планируется на компьютер, обладающий той же системой команд.
В остальных случаях ассемблер используется только для тех непереносимых частей системы, которые должны непосредственно взаимодействовать с аппаратурой (например, обработчик прерываний), или
для частей, которые требуют максимальной скорости (например,
целочисленная арифметика повышенной точности).
Объем машинно-зависимых частей кода, которые непосредственно взаимодействуют с аппаратными средствами, должен быть
по возможности минимизирован. Так, например, следует всячески
избегать прямого манипулирования регистрами и другими аппаратными средствами процессора. Для уменьшения аппаратной
зависимости разработчики ОС должны также исключить возможность использования по умолчанию стандартных конфигураций
аппаратуры или их характеристик. Аппаратно-зависимые параметры можно «спрятать» в программно– задаваемые данные абстрактного типа. Для осуществления всех необходимых действий
по управлению аппаратурой, представленной этими параметрами, должен быть написан набор аппаратно-зависимых функций.
Каждый раз, когда какому-либо модулю ОС требуется выполнить
некоторое действие, связанное с аппаратурой, он манипулирует
абстрактными данными, используя соответствующую функцию из
имеющегося набора. Когда ОС переносится, то изменяются только
эти данные и функции, которые ими манипулируют. Например,
в ОС Windows NT диспетчер прерываний преобразует аппаратные
уровни прерываний конкретного типа процессора в стандартный набор уровней прерываний IRQL, с которыми работают остальные модули операционной системы. Поэтому при переносе Windows NT на
новую платформу нужно переписать, в частности, те коды диспетчера
прерываний, которые занимаются отображением уровней прерывания на абстрактные уровни IRQL, а те модули ОС, которые пользуются этими абстрактными уровнями, изменений не потребуют.
36
Аппаратно-зависимый код должен быть надежно изолирован
в нескольких модулях, а не быть распределен по всей системе. Изоляции подлежат все части ОС, которые отражают специфику как
процессора, так и аппаратной платформы в целом. Низкоуровневые компоненты ОС, имеющие доступ к процессорно – зависимым
структурам данных и регистрам, должны быть оформлены в виде
компактных модулей, которые могут быть заменены аналогичными модулями для других процессоров. Для снятия платформенной
зависимости, возникающей из-за различий между компьютерами
разных производителей, построенными на одном и том же процессоре (например, MIPS R4000), должен быть введен хорошо локализованный программный слой машинно-зависимых функций.
В идеале слой машинно-зависимых компонентов ядра полностью экранирует остальную часть ОС от конкретных деталей аппаратной платформы (кэши, контроллеры прерываний ввода-вывода и т. п.), по крайней мере для того набора платформ, который
поддерживает данная ОС. В результате происходит подмена реальной аппаратуры некой унифицированной виртуальной машиной,
одинаковой для всех вариантов аппаратной платформы. Все слои
операционной системы, которые лежат выше слоя машинно-зависимых компонентов, могут быть написаны для управления именно
этой виртуальной аппаратурой. Таким образом, у разработчиков
появляется возможность создавать один вариант машинно-независимой части ОС (включая компоненты ядра, утилиты, системные
обрабатывающие программы) для всего набора поддерживаемых
платформ.
37
Выводы
– Процессоры i80х86, начиная с процессора 80486, обладают
развитыми средствами, необходимыми для функционирования
операционных систем, поддерживающих мультипрограммный
режим:
– сегментный и сегментно-страничный механизм виртуальной
памяти;
– средства защиты сегментов кодов и данных на основе четырёх
уровней привилегий;
– набор привилегированных команд, используемых только в системных модулях;
– встроенная кэш-память, используемая на различных этапах
определения исполнительных адресов кода и данных;
– механизм переключения задач с сохранением их контекста;
– система обработки прерываний, позволяющая обрабатывать прерывания различных типов (interrupt gate, trap gate, task gate).
– Процессор поддерживает два типа таблиц: глобальную таблицу дескрипторов GDT, в которой хранятся значения параметров системных сегментов и разделяемых сегментов пользовательских задач, и локальные таблицы дескрипторов LDT, каждая из которых
содержит дескрипторы сегментов отдельной задачи.
– Каждый сегмент виртуального адресного пространства описывается дескриптором, который содержит базовый адрес, размер
сегмента, а также ряд признаков, в том числе уровень привилегий
сегмента DPL, определяющий права доступа к нему.
– При сегментном режиме работы виртуальное адресное пространство состоит из 16 Кбайт сегментов по 4 Гбайт каждый – всего
64 Тбайт, а при сегментно-страничном режиме работы все сегменты
отображаются в общий диапазон адресов 4 Гбайт.
– Процессор поддерживает несколько способов обращения к сегментам кода в зависимости от типа таких сегментов (подчинённыё,
неподчинённые), а также содержит средства переключения задач
с сохранением контекстов этих задач.
– В процессоре активно используются механизмы кэширования, позволяющие значительно ускорить выполнение задач, а также смену задач при их переключении: кэширование дескрипторов
сегментов в скрытых регистрах процессора, кэширование дескрипторов страниц в буфере ассоциативной трансляции TLB, кэширование данных и команд в кэш-памяти первого уровня.
– Процессор предоставляет широкие возможности для организации обработки прерываний различного типа в защищённом
38
режиме на основе использования таблицы прерываний IDT. При
этом, прерывания могут являться как внутренними (исключения)
так и внешними (от устройств ввода-вывода), а также программными прерываниями, обработка которых инициируется с помощью
команды INT.
– Объём машинно-зависимых модулей из состава ядра операционной системы должен быть как можно меньше, что упрощает их
перенос на различные аппаратные платформы.
39
Контрольные вопросы
1. Содержимое каких регистров процессора i80х86 в защищённом режиме указывает на дескрипторы сегментов? Как эти регистры называются?
2. Какое назначение имеют регистры процессора LDTR и TR?
3. Опишите структуру дескриптора сегмента. Что такое байт
прав доступа в дескрипторе сегмента? Объясните содержимое отдельных полей байта прав доступа.
4. Как определяется максимальное число дескрипторов в таблице и её максимальный размер в байтах?
5. Чем отличаются механизм доступа к дескрипторам сегментов
из GDT от механизма доступа к дескрипторам сегментов, входящих
в LDT?
6. Для чего нужны невидимые (скрытые) 8-ми байтовые регистры при селекторах?
7. Что означает понятие – линейный адрес? В каком случае этот
адрес является конечным физическим адресом, а в каком случае он
рассматривается как виртуальный адрес, и требуется его дальнейшее преобразование?
8. Объясните понятие “уровень привилегий”, какие значения
может принимать уровень привилегий в процессоре i80х86?
9. Что такое текущий и эффективный уровень привилегий?
10. Объясните правила доступа к сегментам данных и стека на
основе уровней привилегий.
11. Что такое подчинённый и неподчинённый кодовые сегменты?
Что такое “шлюз” и какова его структура? Чем отличаются механизмы доступа к подчинённым и неподчинённым кодовым сегментам на
основе уровней привилегий?
12. Какие новые таблицы поддерживает процессор i80х86 при
сегментно-страничной организации оперативной памяти?
13. Как определяется исполнительный адрес при сегментностраничной организации памяти, и какой недостаток у этого механизма?
14. Какова цель использования буфера ассоциативной трансляции TLB?
15. Какие объекты кэшируются с помощью TLB и чему равен
максимальный кэшируемый объём памяти?
16. Сколько уровней встроенной кэш-памяти имеет процессор
i80х86?
17. Объясните назначение сегмента TSS? Что такое контекст
задачи?
40
18. В чём состоит механизм переключения задач?
19. Как называются дескрипторы, входящие в таблицу IDT, и каков их тип?
20. Какие прерывания вызывают выполнение обработчика, входящего в виртуальное адресное пространство текущей задачи?
21. Какие прерывания вызывают переключение процессора на
выполнение программы обработки новой задачи?
41
Рекомендуемая литература
1. Гордеев А. В. Операционные системы: учебник. СПб.:Питер,
2004. 416с.
2. Гордеев А. В., Молчанов А. Ю. Системное программное обеспечение: учебник. СПб.:Питер, 2002. 736 с.
3. Олифер Н. А., Олифер В. Г. Сетевые операционные системы:
учебник. СПб.: Питер, 2001. 544 с.
4. Соловьёв Г. Н., Никитин В. Д. Операционные системы ЭВМ:
учеб. пособие . М.: Высшая школа, 1989. 255с.
5. Иртегов Д. В. Введение в операционные системы. Разработка
и реализация. 2 изд. Спб. 2007 г.
42
Содержание
Введение...................................................................................
3
Регистры процессора i80x86........................................................
4
Новые команды процессора,
используемые в защищённом режиме...........................................
7
Дескрипторы сегментов
и виртуальное адресное пространство............................................
10
Защита данных при сегментной организации памяти......................
15
Сегментно-страничная организация памяти..................................
19
Многозадачность. Переключение задач.........................................
25
Обработка прерываний...............................................................
28
Влияние аппаратных средств
на организацию операционных систем..........................................
31
Выводы....................................................................................
38
Контрольные вопросы.................................................................
40
Рекомендуемая литература.........................................................
42
43
Документ
Категория
Без категории
Просмотров
0
Размер файла
1 743 Кб
Теги
0ac163f1b3, kychin
1/--страниц
Пожаловаться на содержимое документа