Сегодня мы еще немного поговорим про защищенный режим и про микроядерные
системы.
Я уже неоднократно упоминал это слово в предидущих выпусках. Но думаю что не
всем было понятно что это такое. Сейчас мы рассмотрим это поподробнее.
Исключения или системные прерывания существовали еще в самых первых моделях
процессоров от Intel. Вот их список:
Исключения располагаются в начале таблицы прерываний. В реальном режиме
занимают 8 первых векторов прерываний.
Введение защищенного режима потребовало введения дополнительных исключений. В
защищенном режиме первые 32 вектора прерываний зарезервированы для исключений.
Не все они используются в существующих процессорах, в будующем возможно их будет
больше. Системные прерывания в защищенном режиме делятся на три типа: нарушения
(fault), ловушки (trap) и аварии (abort). Итак в защищенном режиме у нас
существуют следующие исключения:
Нарушения возникают вследствии несанкционированных или неправильных действий
программы, предполагается, что ошибки можно исправить и продолжить выполнение
программы с инструкции, которая вызвала ошибку.
Ловушки возникают после выполнения инструкции, но тоже подразумевают
исправление ошибочной ситуации и дальнейшую работу программы.
Аварии возникают в случае критических нарушений, после этого программа уже не
может быть перезапущена и должна быть закрыта.
Но иногда в случае ошибки или ловушки программа тем не менее не может
продолжить свое выполнение. Это зависит от тяжести нарушения и от организации
операционной системы, которая обрабатывает исключения. И если ошибка или ловушка
не может быть исправлена, программу так же следует закрыть.
При возникновении исключения процессор иногда помещает в стек код ошибки, по
которому обработчик исключения может проанализировать и, возможно, исправить
возникшую ошибку.
Все исключения обрабатываются операционной системой. В случае микроядерных
систем этим занимается микроядро. Вот о микроядрах мы и поведем наш дальнейший
разговор.
В первых выпусках я уже касался этой темы, но тогда я ограничился буквально
несколькими словами. Но теперь мы решили двигаться именно в сторону
микроядерности, значит стоит поподробнее рассказать, что это такое.
Принцип микроядерности заключается в том, что ядро практически не выполняет
операций, связанных с обслуживанием внешних устройств. Эту функцию выполняют
специальные программы-сервера. Ядро лишь предоставляет им возможность обращаться
к устройствам. Помимо этого ядро обеспечивает многозадачность (параллельное
выполнение программных потоков), межпроцессное взаимодействие и менеджмент
памяти.
Приложения (как и сервера) у нас работают на третьем, непривилегированном
кольце и не могут свободно обращаться к портам ввода/вывода или dma памяти. Тем
более не могут сами устанавливать свои обработчики прерываний. Для использования
ресурсов процессы обращаются к ядру с просьбой выделить необходимые ресурсы в их
распоряжение. Осуществляется это следующим образом:
Для обеспечения доступа к портам ввода/вывода используются возможности
процессоров, впервые появившиеся intel 80386. У каждой задачи (в сегменте
состояния задачи (TSS)) существует карта доступности портов ввода/вывода.
Приложение обращается к ядру с "просьбой" зарегистрировать для нее диапазон
портов. Если эти порты до тех пор никем не были заняты, то ядро предоставляет их
в распоряжение процесса, помечая их как доступные в карте доступности
ввода/вывода этого процесса.
DMA память, опять таки после запроса у ядра, с помощью страничного
преобразования подключается к адресному пространству процесса. Настройка каналов
осуществляется ядром по "просьбе" процесса.
Доступ к аппаратным прерываниям (IRQ) осуществляется сложнее. Для этого
процесс порождает в себе поток (thread), и сообщает ядру, что этот поток будет
обрабатывать какое-то IRQ. При возникновении аппаратного прерывания, которое
обрабатывает всетаки ядро, данный процесс выходит из состояния спячки, в котором
он находился в ожидании прерывания, и ставится в очередь к менеджеру процессов.
Такие потоки должны иметь более высокий приоритет, чем все остальные, дабы
вызываться как можно скорее.
Но, как я говорил, ядро выполняет еще некоторые функции, немаловажная из
которых - это межпроцессное взаимодействие. Оно представляет из себя возможность
процессов обмениваться сообщениями между собой. В отличии от монолитных систем в
микроядерных системах межпроцессное взаимодействие (Inter Process Communication
или IPC) это едва ли не основное средство общения между процессами, и поскольку
все драйвера у нас такие же процессы, микроядерное IPC должно быть очень
быстрым. Быстродействие IPC достигается за счет передачи сообщений без
промежуточного буферизирования в ядре. Либо непосредственным переписыванием
процессу-получателю, либо с помощью маппинга страниц (если сообщения большого
размера).
Менеджер памяти имеет как бы две стороны. Первая сторона - внутренняя,
распределение памяти между приложениями, организация свопинга (который тоже
осуществляется не ядром непосредственно, а специальной программой-сервером)
никаким образом не интересует остальные программы. Но другая сторона - внешняя
служит именно для них. Программы могут запросить у ядра во временное пользование
некоторое количество памяти, которое ядро им обязательно предоставит (в разумных
пределах... гигабайта два... не больше... :). Или же программы могут запросить у
ядра какой-то определенный участок памяти. Это бывает необходимо
программам-серверам. И это требование ядром также вполне может быть
удовлетворено при условии, что никакая другая программа до того не забронировала
этот участок памяти для себя.
Отправлено 2001-08-17 для 3870 подписчиков.
ведущий рассылки Dron
Сайт проекта
Архив
Рассылки
При поддержке Kalashnikoff.ru