Организация памяти в защищенном режиме. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Организация памяти в защищенном режиме.



Что вообще такое защищенный режим и почему он так называется? То, что я сейчас скажу – звучит очень просто, но в то же время – это ОЧЕНЬ ВАЖНО ПОНЯТЬ!

Дело в том, что реальный режим процессора Intel – однозадачная среда, в данный момент времени в ней может выполняться ТОЛЬКО ОДНА, конкретная задача. Безусловно, можно сэмулировать многозадачность и в реальном режиме, но все дело в том, что именно в защищенном режиме вся многозадачность реализована АППАРАТНО, это важный момент, и, по сути, является ЕДИНСВТЕННЫМ принципиальным отличием между режимами. Не правда ли, это шокирует? А ты думал, что PM это монстр с дескрипторами между голов и селекторами вместо рук? Ты правильно думал, но до них дело дойдет, не волнуйся…

Для начала рассмотрим общие положения об организации памяти в PM. В процессорах Intel организацию памяти разделяют на две части: сегментация (segmentation), и страничная организация (paging).

Сегментация позволяет изолировать модули кода, данных, стека и позволяет работать нескольким задачам и программам на одном процессоре (как говорится, multitasking) и не конфликтовать между собой – это и есть по большому счету, вся революция по сравнению с 8086.

Страничная организация памяти, вообще говоря, сложнее и громозще сегментации, поэтому во многой литературе ее просто опускают, но я бы особо хотел обратить твое и свое внимание именно на нее (хотя бы потому, что у такой организации больше возможностей, и именно на ней работает Мастдай).

В процессоре нет такого бита, который бы четко отвечал за переключение между этими двумя режимами. Элементы сегментной организации, в любом случае, присутствуют всегда. А вот уже использовать страничную организацию или нет – выбор за нами (за это отвечает флаг PG, бит 31 регистра CR0). Не пугайся, CR0 – это обычный регистр (такой же, как AX, BP и т.д.), подробнее поговорим о нем чуть позже.

Сегментация – это механизма разделения адресного пространства процессора (по-русски: память, которую «видит» процессор) на отдельные защищенные друг от друга кусочки (сегменты). У новичка сразу возникнет вопрос: а от чего защищать то:)? Очень важный момент, но пока не бери в голову, скоро он отпадет сам собой.

Непосредственно сегмент может содержать в себе код, данные, стек, системные структуры данных (TSS, LDT, но о них позже). Если запущено сразу несколько программ:), то каждой программе принадлежит своя, личная группа сегментов.

Итак, что мы имеем. Память, разделена на группы сегментов, у каждой группы есть свой владелец (программа). Программы вынуждены сидеть в оперативе, прижавшись друг к другу, как цыплята в инкубаторе, вследствии чего они потихоньку друг друга ненавидят и не подпускают чужие проги к сегментам из своей группы. При любой попытке пресечь границы вылазит некое подобие «руки правосудия» и нажимает на кнопку ALARM. Вследствие чего вдруг откуда ни возьмись возникает исключение #GP (General Protection) и все проги падают ниц перед ним, а виновника изгоняют вон:) Но что то я увлекся, все эти прекрасы ждут нас в будущем…

Нет, ну вообще, как ты относишься к изложению в таком духе?

Для того, чтобы обратиться к любому байту в любом сегменте в памяти мы должны сформировать ЛОГИЧЕСКИЙ АДРЕС (aka дальний указатель).

Что же оно из себя такое представляет, этот логический адрес? А представляет оно селектор и смещение, и больше ничего! Селектор – это УНИКАЛЬНЫЙ идентификатор сегмента. У КАЖДОГО СЕГМЕНТА ЕСТЬ СВОЙ СЕЛЕКТОР! Это нужно запомнить раз и навсегда!!! Скажу по секрету, что селектор содержится в сегментом регистре (да да, те самые DS, CS, ES …). Селектору будет посвящена отдельная глава, а пока запомни только то, что «… у каждого сегмента он свой». Зная селектор и зная смещение мы можем получить ЛИНЕЙНЫЙ АДРЕС – место, где РЕАЛЬНО расположен нужный нам байт. Как его получить – пока сказать не могу, потому как придется вплетать еще одно СУПЕРВАЖНОЕ(!) определение – ДЕСКРИПТОР (структура, описывающая сегмент, его паспорт, свидетельство о рождении, водительские права и вообще всю подобную бюрократию).

Существует также такое понятие, как физическое адресное пространство процессора. Не следует на нем особо заострять внимания, скажу только, что физический адрес – это адрес, который проц может выставить на адресную шину, и в случае СЕГМЕНТНОЙ организации памяти (но не СТРАНИЧНОЙ!) СОВПАДАЕТ с линейным адресом! Вот этот момент в литературе всячески перевирается и искажается, но запомни: в случае СЕГМЕНТНОЙ организации памяти ЛИНЕЙНЫЙ адрес ВСЕГДА СОВПАДАЕТ с ФИЗИЧЕСКИМ. Пока больше ничего.

Виды памяти в защищенном режиме

Простая плоская модель

Действительно, самая простая модель: вся память представляет одно ОГРОМНОЕ адресное пространство, никакого механизма распределения, никаких сегментов, ничего нет! Пустыня! Нет, не совсем конечно… Должно быть МИНИМУМ два дескриптора (черт! Опять эти дескрипторы…Это сильно усложняет мне задачу… ладно, продолжим дальше, прими во внимание только то определение которое я давал про дескрипторы выше, и еще дополнительно – в дескрипторе есть поля, в которых указаны начало и конец сегмента). Один из этих дескрипторов ДОЛЖЕН описывать сегмент кода (с началом в 0 и лимитом в 4 Гб), второй – сегмент данных (также с началом в 0 и лимитом в 4 Гб!!!). Как же так? Они же «накладываются друг на друга»? Ну вот так вот, говорю же, никакой защиты, ничего не застраховано, «рука правосудия» спит в гробу.

Защищенная плоская модель

Все отличие от предыдущей модели – база и лимит кода и данных уже не совпадают, и здесь уже #GP может проявить себя в самом разцвете… Более того! Если включить флажочек PG (страничная адресация), мы получим ту самую модель памяти, в которой работает всеми нами любимый мастдай – защищенная плоская модель с страничной адресацией. Но здесь нам уже понадобиться минимум 4 сегмента: для кода и данных на уровне привилегий 3, + для кода и данных на уровне 0 (многие из вас слышали, что мастдай использует только эти два уровня привилегий, оставляя 3 для пользовательских прог, а 0 – для ядра и особ, «особо приближенных к императору»).

Мульти-сегментная модель

Данная модель использует все возможности проца «на полную катушку», позволяет аппаратно защищать код, структуры данных, задачи и программы друг от друга.

Процессор Intel в защищенном режиме #2

В предыдущем выпуске ты в самом первом приближении ознакомился с видами организации памяти в защищенном режиме. Напомню, что существует всего 2 вида: сегментная (segment) и страничная (paging) модели. Также я обещал в этом выпуске более подробно остановиться на страничной организации. На самом деле еще рановато… Давай лучше до конца разберемся с сегментной организацией, потом будет намного проще разобраться со страничной…

Итак, что мы имеем: программа (вернее, программы) загружены в оперативную память, каждая программа владеет группой сегментов (данные, код, стек). Теперь возникает вопрос: откуда же процессор знает, где какой сегмент? Где начало сегмента? И где его конец? И что это за сегмент: данных? кода? А может быть, стека? Или, может быть, всего разом? Ответить на этот вопрос может только одна структура данных: ДЕСКРИПТОР. Повторите это слово про себя несколько раз, запомните его. Напишите на бумажке 10 раз:). ДЕСКРИПТОР – это структура, ОПИСЫВАЮЩАЯ сегмент. Если человек – это сегмент, то паспорт – это его дескриптор. У каждого человека он свой собственный. И разница лишь в том, что человеку паспорт (дескриптор) выдается с 16 лет (на Украине), а у сегмента он с момента рождения.

Сегментный дескриптор

Вот он, наш красавец! Посмотри на него повнимательнее, включи зрительную память на максимум… Я его вообще около получаса вымалевывал, и вот какой он получился ненаглядный!

Теперь распишу во всех пикантных подробностях значения полей дескриптора (хочется тебе или нет, но без этого, к сожалению, НИКУДА дальше не уедешь, придется тебе их всех запомнить):

(Смотри одним глазом на фиолетовые слова, другим – ищи их на картинке:))

Адрес базы: адрес нулевого байта описываемого сегмента в 4 Гб линейном адресном пространстве (т.е. адрес, с которого начинается сегмент). Процессор собирает в кучу три поля зеленого цвета:) и образует единый 32-х битный адрес. Почему так убого? Потому что вообще говоря, процессор Интел представляет собой штопанно-перелатанного уродца (достаточно взглянуть на дескриптор). И этому есть несколько причин. Единственное, что могу добавить – это не самое ужасное. Что еще хотелось бы отметить по поводу адреса базы сегмента – желательно он должен быть кратен 16 (так проц при обращении к описываемому сегменту и формировании адреса будет быстрее соображать).

Лимит сегмента: определяет размер сегмента. Опять же, проц собирает в кучу поля красного цвета, и формирует конечный, 20- битовый адрес. Реальный лимит сегмента зависит от бита гранулярности (G-granularity);
- если бит гранулярности сброшен (0), то 20-битное значение и будет тем самым лимитом сегмента
- если бит гранулярности установлен (1), то всё 20-битное значение автоматически увеличивается в 1000h раз, т.е. если при G=0 мы измеряем размер в байтах, то при G=1 – в 4Кб единицах, (см. мультфильм «48 попугаев»).

Например, если G=1 и поле «Лимит сегмента» = 0000Fh (15 байт), то реальный лимит (читай – размер) данного сегмента равен 0Fh*1000h=0F000h (около 61 тысячи байт!).

Следует отметить, что если поле «Лимит сегмента» содержит значение равное 0, то это значит, что описуемый сегмент имеет размер в 1 байт (а не ноль!) при G=0, и размер в 4Кб при G=1. Т.е. сегмент никак не может иметь нулевую длину, минимум – 1 байт, максимум – 0хFFFFFh * 4Кб = 4 Гб.

Есть еще один бит, от которого зависит смысловое значение этого поля. Бит направления роста сегмента (B-big));
- если этот бит сброшен (0), то разрешены все смещения от 0 до лимита
- если установлен (1) – то все, кроме от 0 до лимита Но этот бит B несколько затуманивает понятие лимита, поэтому пока не бери в голову:)

В противном случае (если мы попытаемся обратится за пределы лимита) – возникнет исключение главной защиты (#GP) – страшная вещь! Вообще говоря, лимиты для этой цели и придуманы – отслеживать обращения в недоступные адресные пространства.

Еще один момент, который нигде в документации явно не указан. Лимит сегмента отсчитывается ОТ БАЗЫ СЕГМЕНТА, а не от нуля!!! Это совсем не ОЧЕВИДНО! (по крайней мере, я долго заблуждался…)

Тип:
Определяет тип сегмента (или шлюза, что такое шлюз – узнаете потом), определяет права доступа к сегменту и направление роста сегмента (помните бит B). Значение этого поля зависит от значения поля «Тип дескриптора» (S-descriptor type). Значение этого поля различно для разных типов сегментов (кода, данных и системного)

S (descriptor type) – флаг «тип дескриптора»:
Означает только одно: если сброшен (0), то описуемый сегмент – системный, если установлен (1) – это сегмент данных или кода. Подробности – в след. выпуске. И вообще привыкай: если что то непонятно – узнаешь об этом в следующем выпуске 100%. Или если не можешь спокойно спать – пиши мне (см. мыло винзу).

DPL (descriptor privilege level) – уровень привилегий дескриптора:
Определяет уровень привилегий сегмента. Т.к. это поле – двухразрядное, то соответственно может принимать только четыре различных значения (от 0 до 3). Самый крутой – нулевой уровень привилегий (ядро ОС). Это поле нужно для контроля за доступом к сегменту. Во всех подробностях распишу его назначение в последующих главах рассылки. Пока забудь о нем.

P (segment present flag) – флаг присутствия сегмента:
Если установлен, значит сегмент присутствует непосредственно в памяти; если сброшен – сами догадайтесь. Зачем оно нада: все видели и трогали мастдай, все знают что такое своп-файл. Вообщем, этот флаг предназначен для организации работы при использовании страничной адресации (дело в том, что когда в сегментный регистр грузят селектор на дескриптор, в котором сброшен этот бит – возникает исключение #NP (segment-not- present exeption)), поэтому, если отлавливать это самое #NP можно вовремя подгрузить новую страницу в ОП из файла подкачки. Страничная адресация ждет нас впереди!

G (Granularity) – флаг «гранулярности»:
См. «Лимит сегмента». Еще раз повторю - этот флаг влияет на лимит сегмента: если сброшен – лимит измеряется в байтах, если установлен – в 4 Кб единицах. Еще что запомни раз и навсегда: на адрес базы этот флаг НИКАКИМ БОКОМ НЕ ВЛИЯЕТ! Только на лимит! База ВСЕГДА измеряется в байтах! Clear?)

AVL (Available and reserved bits) – зарезервировано:
Это два битика (21-20 во втором двойном слове). Они вообще не стоят того, чтобы на них заострять внимание, но все же может кому и пригодиться: битик 20 может использоваться как угодно по вашему усмотрению:), битик 21 ВСЕГДА ДОЛЖЕН БЫТЬ РАВЕН НУЛЮ! ИНАЧЕ ГОВРОЯ - РУКАМИ НЕ ТРОГАТЬ!

Остался последний битик. Двадцать второй. D/B. Довольно мутный. Зависит от типа сегмента (в зависимости от этого он называется либо D, либо B). Учитывая то, что про него уже было сказано при описании лимита сегмента, следует отметить еще вот что:

Определяет разрядность сегмента. Если установлен – значит сегмент 32-х разрядный, если сброшен – 16-ти. Это общий случай. Теперь частные:

- Сегмент кода. Для сегмента кода данный флаг называется D и устанавливает длину по умолчанию для эффективных адресов и операндов в сегменте. Если установлен – то в сегменте допустимы 32-х битные адреса и 32-х битные ИЛИ 8-ми битные операнды; Если сброшен – 16-битные адреса и 16-битные ИЛИ 8-ми битные операнды. Но никто не мешает нам использовать префикс 66h (для изменения разрядности операндов) и префикс 67h (для изменения разрядности адресов).

- Сегмент стека. Для сегмента стека данный флаг называется B (big) флаг и устанавливает длину УКАЗАТЕЛЯ СТЕКА (регистр ESP) для команд push, pop и call. Если установлен – используется 32-х разрядный указатель стека (т.е. регистр ESP использован по максимуму), если сброшен – то используется только 16 бит (регистр SP, уже без буковки E).



Поделиться:


Последнее изменение этой страницы: 2016-06-22; просмотров: 644; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.222.163.31 (0.011 с.)