Lab2. Защищенный режим микропроцессоров Intel x86. Лабораторная работа защищенный режим микропроцессоров intel x86 Основные сведения
Скачать 0.54 Mb.
|
ЛАБОРАТОРНАЯ РАБОТА 2. ЗАЩИЩЕННЫЙ РЕЖИМ МИКРОПРОЦЕССОРОВ INTEL X86 Основные сведения Понятие защиты Микропроцессор 8086, ориентированный на однозадачные системы, как известно, не предлагает никаких средств, позволяющих контролировать поведение выполняющейся в данный момент программы, т.е. программа имеет доступ ко всем имеющимся в системе ресурсам, в том числе и принадлежащим операционной системе. Таким образом, целостность операционной системы может быть нечаянно или умышленно нарушена, и сама система ничем не может защитить себя. Когда начали появляться микропроцессоры со встроенной поддержкой мультизадачности, вопрос обеспечения защиты вышел на первый план. Действительно, когда процессором одновременно выполняются несколько программ, почти всегда необходимо тщательно изолировать их друг от друга и от операционной системы. Тем самым исключается влияние отдельных программ на целостность системы, и аварийное завершение одной задачи не повлияет на устойчивую работу системы в целом. Исходя из всего этого при проектировании процессора 80286 были заложены аппаратные средства защиты в основе которых лежит принцип разделения уровней привилегированности и механизм управления памятью. Механизм защиты распознает четыре уровня привилегий, нумеруемых от 0 до 3. Чем больше номер, тем ниже уровень привилегированности. Поскольку основными системными объектами, которыми оперирует процессор, являются сегменты памяти, то с каждым сегментом кода, данных или стека ассоциируется некий уровень привилегий, и все, что находится внутри этого сегмента, имеет этот уровень привилегий. Поскольку число программ, которые могут выполняться на более высоком уровне привилегий, уменьшается в направлении уровня 0, то уровни привилегий обычно изображают в виде колец защиты (pис. 2.1). Центральное кольцо защиты содержит сегменты, в которых находится наиболее важное программное обеспечение, обычно ядро операционной системы. Прикладным программам, как правило, присваивается низший уровень привилегий и запрещается самостоятельная работа с системными средствами. Промежуточные уровни привилегий обычно присваиваются драйверам периферийных устройств, для того чтобы защитить операционную систему от сбоев в драйверах и одновременно защитить драйверы от прикладных программ. ┌─────────────────────────────────────────────── ────┐ │ Прикладные программы │ │ │ │ ┌────────────────────────────────────┐ │ │ │ Расширения операционной системы │ │ │ │ Системы программирования │ │ │ │ ┌─────────────────────┐ │ │ │ │ │ Сервис ОС │ │ │ │ │ │ Драйверы │ │ │ │ │ │ ┌─────────┐ │ │ │ │ │ │ │ Ядро ОС │ │ │ │ │Уровень │Уровень│Уровень│ Уровень │ │ │ │ │ 3 │ 2 │ 1 │ 0 │ │ │ │ │ │ │ └─────────┘ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─────────────────────┘ │ │ │ └────────────────────────────────────┘ │ └───────────────────────────────────────────────────┘ Рис. 2.1. Уровни привилегий Хотя для отмены механизма защиты никакого управляющего регистра или бита режима не предусмотрено, того же эффекта можно достигнуть путем присвоения всем сегментам уровня привилегий 0. Отметим, что все средства работы с уровнями привилегий доступны только в защищенном режиме, являющемся основным режимом работы новых моделей процессоров. Если защищенный режим выключен, то процессор работает в режиме, который просто реализует возможности обладающего более высоким быстродействием и улучшенного процессора 8086. Организация памяти в защищенном режиме Основой организации памяти в защищенном режиме являются сегментация и подкачка страниц. Сегментация служит для того, чтобы дать каждой программе несколько независимых, защищенных адресных пространств. Подкачка страниц используется для создания среды, в которой большие адресные пространства моделируются на базе сравнительно небольшой области оперативной памяти и некоторого объема дисковой памяти. Подкачка страниц обеспечивает доступ к структурам данных, превышающих по размеру доступное пространство оперативной памяти, благодаря тому, что часть таких структур держится в оперативной памяти, а часть - на диске. Аппаратное обеспечение сегментации транслирует сегментированный (логический) адрес в адрес непрерывного адресного пространства, который называется линейным адресом. Если разрешена подкачка страниц, то аппаратное обеспечение подкачки транслирует линейный адрес в физический. Если подкачка страниц запрещена, то в качестве физического адреса используется линейный адpес. Физический адрес подается на адресную шину процессора. Каждый сегмент памяти в системе характеризуется 8- байтной структурой данных, называемой ДЕСКРИПТОРОМ СЕГМЕНТА, которая сообщает процессору размер и расположение в памяти сегмента, а также управляющую информацию и о состоянии сегмента. Дескрипторы обычно создаются компиляторами, компоновщиками, загрузчиками или операционной системой, но не прикладными программами. На рис 2.2 показан общий формат 32-битного дескриптора для процессора 80386. В процессоре 80286 старшее слово дескриптора не используется (зарезервировано и должно содержать нули). Назначение полей дескриптора: - базовый адрес сегмента определяет расположение сегмента в пределах 4-гигабайтного физического адресного пространства. Занимает байты 2, 3, 4 и 7 дескриптора. При задании нулевого смещения именно этот адрес будет сформирован процессором в качестве линейного; - бит грануляции (G) включает масштабирование поля границы масштабным коэффициентом 4096. Если этот бит очищен, то размер сегмента измеряется в байтах, а если бит G установлен - в страницах (блоках памяти размером 4Кбайт); 2 2 2 2 2 1 1 1 1 1 1 1 31 4 3 2 1 0 9 6 5 4 3 2 1 9 8 7 0 ┌──────────────┬─┬─┬─┬─┬──────┬─┬───┬─┬────┬─┬──────────────┐ │ │ │ │ │A│Грани-│ │ D │ │ │ │ │ │База 31..24 │G│D│0│V│ ца │P│ P │S│TYPE│A│ База 23..16 │ │ │ │ │ │L│19..16│ │ L │ │ │ │ │ └──────────────┴─┴─┴─┴─┴───────┴───┴─┴─────┴─┴──────────────┘ ┌────────────────────────────┬──────────────────────────────┐ │ База 15..00 │ Граница 15..00 │ └────────────────────────────┴──────────────────────────────┘ База - базовый адрес сегмента Граница - граница сегмента DPL - уровень привилегированности дескриптора S - тип сегмента (0=системный; 1=прикладной) G - гpануляция P - присутствие сегмента TYPE - тип сегмента A - бит обращения к сегменту D - размер операции по умолчанию (распознается только в дескрипторах кодового сегмента: 0 = 16-битовый размер; 1 = 32-битовый размер) AVL - доступно для использования системным программным обеспечением Рис. 2.2. Дескриптор сегмента 32-битного процессора х86 - граница сегмента (предел) определяет размер сегмента. Процессор помещает рядом два поля границы сегмента, в совокупности образующих одно 20-разрядное значение. Размер сегмента определяется одним из двух следующих способов, в зависимости от установки бита грануляции: 1. Если бит грануляции очищен, то размер сегмента может принимать значения от 1 байта до 1 Мбайта, с приращениями в один байт. 2. Если бит грануляции установлен, то сегмент может иметь размер от 4 Кбайт до 4 Гбайт, с приращениями в 4 Кбайт. Для большинства сегментов логический адрес может иметь значение смещения в диапазоне от 0 до значения границы. Прочие значения ведут к генерации особых ситуаций. Сегменты с расширением вниз (см. описание поля типа) изменяют смысл поля границы на противоположный: они позволяют адресацию любыми значениями смещения, кроме значений от 0 до значения границы. Такие сегменты обычно используются для хранения стеков; - бит размера по умолчанию (D) указывает длину операндов и исполнительных адресов сегмента по умолчанию. Если D=1, то предполагается режим 32-разрядных операндов и исполнительных адресов. Если этот бит очищен, то предполагается использование 16-разрядных операндов и адресов. Бит D обеспечивает совместимость с процессором 80286; - бит присутствия сегмента (P). Если этот бит очищен, то процессор при загрузке в сегментный регистр селектора данного дескриптора генерирует особую ситуацию 11 ("сегмент не присутствует"). Это свойство используется для обнаружения попыток доступа к сегментам, которые стали недоступными. Операционная система может передавать содержимое некоторых сегментов на диск, если, например, физическая память заполнена. В этом случае, передаваемый на диск сегмент отмечается в своем дескрипторе, как временно не присутствующий. Когда программа обратится к не присутствующему сегменту, возникнет особая ситуация, и система может считать нужный сегмент с диска в память. Сегмент может быть помечен операционной системой как не присутствующий, если его по какой-либо причине необходимо "спрятать"; - поле уровня привилегий (DPL, Descriptor Privilege Level) определяет уровень привилегированности сегмента. Используется для управления доступом к сегменту при помощи механизма защиты; - бит системного сегмента (S). В сегментах кода или данных данный бит всегда установлен в состояние 1, а конкретное назначение сегмента описывается полем TYPE. Если S=0, то дескриптор описывает системный объект, который может и не являться сегментом памяти. Системные дескрипторы будут описаны ниже; - бит обращения к сегменту (A) устанавливается процессором при обращении к сегменту, определяемому данным дескриптором; - поле типа сегмента (TYPE). Интерпретация этого поля зависит от того, относится ли данный дескриптор к прикладному, или же к системному сегменту. Системные сегменты имеют несколько иной формат дескриптора, рассматриваемый ниже. Поле Типа дескриптора памяти задает тип доступа, разрешенного к данному сегменту, а также направление расширения сегмента (табл. 2.1). Таблица 2.1 Типы прикладных сегментов ┌─────────────┬─────────────────────────────┐ │Значение поля │ Тип сегмента │ │ TYPE │ │ ├────────────┼──────────────────────────────┤ │ 000b │ Сегмент данных, разрешено только чтение │ │ 001b │ Сегмент данных, разрешено чтение и запись │ │ 010b │ Сегмент стека, разрешено только чтение │ │ 011b │ Сегмент стека, разрешено чтение и запись │ │ 100b │ Сегмент кода, разрешено только выполнение │ │ 101b │ Сегмент кода, разрешено выполнение и чтение│ │ 100b │ Подчиненный (конформный) сегмент кода, │ │ │ разрешено только выполнение │ │ 100b │ Подчиненный (конформный) сегмент кода, │ │ │ разрешено выполнение и чтение │ ─── ─────┴─────────────────────────────────┘ Поле типа однозначно определяет правила доступа к сегментам. Например, в регистр CS нельзя загружать селекторы сегментов данных, в регистр SS может быть загружен только селектор стекового сегмента, никакая программа не сможет модифицировать данные в сегменте, для которого разрешено только считывание. В случае возникновения такого рода ситуаций генерируется особая ситуация общей защиты (прерывание 13). Кодовые сегменты могут быть либо конформными, либо неконформными. Переход выполнения в более привилегированный конформный сегмент сохраняет текущий уровень привилегированности. Переход выполнения в неконформный сегмент с другим уровнем привилегированности приводит к генерации особой ситуации общей защиты, если не использован шлюз задачи. Байт 5 дескриптора (который содержит поля DPL, S, P и TYPE) называется байтом прав доступа. В системе с процессорами х86 при работе может быть создано довольно много сегментов и описывающих их дескрипторов, поэтому для удобства все дескрипторы объединены вместе в ДЕСКРИПТОРНУЮ ТАБЛИЦУ. Существует три типа дескрипторных таблиц: 1. Глобальная дескрипторная таблица GDT. Она является основной общесистемной таблицей, и при работе ее могут использовать все программы. Первый дескриптор в таблице GDT не используется процессором. Селектор сегмента для данного "пустого дескриптора" пpи загрузке его в сегментный регистр не генерирует особой ситуации, однако особая ситуация генерируется всякий раз при попытке доступа к памяти с использованием такого дескриптора. 2. Локальная дескрипторная таблица LDT. В мультизадачной системе для каждой задачи можно построить свою локальную дескрипторную таблицу, которая определяет сегменты, доступные только этой конкретной задаче. 3. Таблица дескрипторов прерываний IDT. Она также является общесистемной таблицей и содержит дескрипторы специальных системных объектов - шлюзов (gate), которые определяют точки входа процедур обработки прерываний и особых ситуаций. Эта таблица служит заменой таблицы векторов прерываний процессора 8086. Таблицы GDT и LDT имеют переменную длину и могут содержать до 8192 (2^13) дескрипторов. Четыре регистра процессора (pис. 2.3) задают расположение структур данных, которые управляют организацией сегментированной памяти. Для загрузки и сохранения этих регистров имеются специальные команды. В процессоре 80286 регистры GDTR и IDTR имеют длину 5 байт, а старший байт в них не используется, поэтому в них загружается 24-битовый линейный базовый адрес. Регистр таблицы глобальных дескрипторов GDTR. Этот регистр содержит 32-битовый базовый адрес и 16-битовую границу сегмента таблицы глобальных дескрипторов (GDT). При ссылке на данные в памяти для того, чтобы найти дескриптор сегмента в GDT или LDT используется селектор сегмента. Дескриптор сегмента содержит базовый адрес сегмента. 32-битовый линейный базовый адрес Граница 47 16 15 0 ┌─────────────────────────┬─────────────┐ GDTR │ Линейный базовый адрес │ Предел │ ├─────────────────────────┼─────────────┤ IDTR │ Линейный базовый адрес │ Предел │ └─────────────────────────┴─────────────┘ 15 0 ┌────────────┐ LDTR │ Селектор │ ├────────────┤ TR │ Селектор │ └────────────┘ Рис. 2.3. Регистры управления памятью процессора х86 Регистр таблицы локальных дескрипторов LDTR и регистр задачи TR имеют длину 16 бит. Они выполняют функции сегментных регистров, т.к. определяют через таблицу GDT два важнейших сегмента, относящиеся к текущей задаче. Регистр LDTR содержит селектор сегмента локальной дескрипторной таблицы для текущей задачи, а регистр TR определяет текущий сегмент состояния задачи TSS. Использование этих двух регистров будет рассмотрено при описании мультизадачности. Регистр таблицы дескрипторов прерываний IDTR. Он является точной копией регистра GDTR, только адресует в памяти таблицу дескрипторов прерываний. Когда происходит прерывание или особая ситуация, вектор прерывания используется в качестве индекса для получения из данной таблицы дескриптора шлюза. Последний содержит указатель, используемый для запуска обработчика прерывания. Граничное значение (предел) выражается в байтах. Как и для сегментов, оно складывается с базовым адресом для получения адреса последнего допустимого байта. Поскольку дескрипторы всегда имеют размер восемь байтов, то граница всегда должна быть на единицу меньше целочисленного произведения восьми, т.е. 8N-1. Рассмотрим, как процессор использует дескрипторы после их определения. Для доступа к дескриптору служит содержимое сегментного регистра, которое называется СЕЛЕКТОРОМ. Длина сегментного регистра, в целях совместимости с предыдущими процессорами, равна 16 бит, однако его содержимое интерпретируется иначе. Формат селектора сегмента показан на рис. 2.4. 15 3 2 1 0 ┌────────────────────────────┬─┬────┐ │ │T│ │ │ Индекс │I│RPL │ │ │ │ │ └────────────────────────────┴─┴────┘ TI (Table Indicator) - индикатор таблицы (0=GDT, 1=LDT); RPL (Requested Privilege Level) - запрошенный уровень привилегий Рис. 2.4. Селектор сегмента Бит-индикатор таблицы (TI) задает используемую дескрипторную таблицу. Если этот бит очищен, то дескриптор выбирается из таблицы GDT; если же он установлен - то из текущей таблицы LDT. Индекс выбирает один из 8192 дескрипторов в таблице дескрипторов. Индекс умножается на восемь (число байтов в дескрипторе сегмента) и складывается с 32-битным базовым адресом дескрипторной таблицы, который берется из регистра GDTR, либо из регистра LDTR, в зависимости от состояния бита TI. Запрошенный уровень привилегий (RPL): если это поле содержит уровень привилегий с большим значением, чем программа (т.е. привилегированность меньше), то оно переопределяет уровень привилегий программы. Если программа использует менее привилегированный селектор сегмента, то доступ к памяти происходит с меньшим уровнем привилегий. С каждым сегментным регистром, а также с регистрами LDTR и TR ассоциируется "теневой" или кэш-регистр (рис. 2.5). Кэш-регистры невидимы и явно недоступны программам. Когда программа загружает селектор в сегментный регистр, процессор автоматически считывает соответствующий дескриптор в кэш-регистр. После этого процессор уже не обращается к таблицам дескрипторов до тех пор, пока не произойдет загрузка другого селектора сегмента. Частые изменения сегментных регистров в защищенном режиме ухудшают быстродействие программы, поскольку при этом тратится время на обращение к дескрипторным таблицам. 15 0 63 0 ┌──────────┐ ┌─-----------------------------------------─┐ CS │ │ | | | | ├──────────┤ │-------------------------------------------│ SS │ │ | | | | ├──────────┤ │-------------------------------------------│ DS │ │ | | | | ├──────────┤ │-------------------------------------------│ ES │ │ | | | | ├──────────┤ │-------------------------------------------│ FS │ │ | | | | ├──────────┤ │-------------------------------------------│ GS │ │ | | | | ├──────────┤ │-------------------------------------------│ LDTR │ │ | | | | ├──────────┤ │-------------------------------------------│ TR │ │ | | | | └──────────┘ └-------------------------------------------┘ 15 0 63 0 Рис 2.5. Теневые регистры Для поддержки защищенного режима в регистр флагов были введены новые поля: - IOPL (In/Out Privilege Level): уровень привилегий ввода- вывода. Показывает минимальный уровень привилегий выполняющейся задачи, на котором разрешено производить операции ввода/вывода; - NT (Nested Task): вложенная задача. С помощью этого флага организуется цепь вложенных задач, аналогично вложению подпрограмм. Команда IRET проверяет состояние этого флага и при NT=1 происходит переключение задачи, а при NT=0 - обычный возврат из прерывания; - RF (Resume Flag): флаг возобновления. Действует совместно с регистрами отладки. Временно запрещает особые ситуации отладки, для возможности осуществить рестарт команды без немедленного формирования еще одной особой ситуации отладки; - VM (Virtual Mode): виртуальный режим. При V=1 процессор переходит в режим эмуляции 8086 из защищенного режима. Прикладными программами эти флаги должны игнорироваться, а попытки модификации их состояния из прикладных программ недопустимы. В большинстве систем попытка изменения системного флага из прикладной программы приводит к возникновению особой ситуации). |