Сегодня мы еще немного поговорим про защищенный режим и про микроядерные
системы.
Исключения защищенного режима.
Я уже неоднократно упоминал это слово в предидущих выпусках. Но думаю что
не всем было понятно что это такое. Сейчас мы рассмотрим это поподробнее.
Исключения или системные прерывания существовали еще в самых первых моделях
процессоров от Intel. Вот их список:
Division by zero (деление на ноль или переполнение при делении);
Single step (пошаговая отладка);
Breakpoint;
Overflow (срабатывает при команде into в случае установленного флага overflow в регистре flags);
Invalid opcode (i286+);
No math chip;
Исключения располагаются в начале таблицы прерываний. В реальном режиме
занимают 8 первых векторов прерываний.
Введение защищенного режима потребовало введения дополнительных исключений.
В защищенном режиме первые 32 вектора прерываний зарезервированы для
исключений. Не все они используются в существующих процессорах, в будующем
возможно их будет больше. Системные прерывания в защищенном режиме делятся
на три типа: нарушения (fault), ловушки (trap) и аварии (abort). Итак в
защищенном режиме у нас существуют следующие исключения:
Divide error (fault);
Debug (fault/trap);
Breakpoint (trap);
Overflow (trap);
Bounds check (fault);
Invalid opcode (fault);
Coprocessor not available (fault);
Double fault (abort);
Coprocessor segment overrun (fault);
Invalid tss (fault);
Segment not present (fault);
Stack fault (fault);
General protection fault (fault);
Page fault (fault);
Coprocessor error (fault);
Alignument check (fault) (i486+);
Hardware check (abort) (Pentium+);
SIMD (fault) (Pentium III+).
Нарушения возникают вследствии несанкционированных или неправильных действий
программы, предполагается, что ошибки можно исправить и продолжить
выполнение программы с инструкции, которая вызвала ошибку.
Ловушки возникают после выполнения инструкции, но тоже подразумевают
исправление ошибочной ситуации и дальнейшую работу программы.
Аварии возникают в случае критических нарушений, после этого программа уже
не может быть перезапущена и должна быть закрыта.
Но иногда в случае ошибки или ловушки программа тем не менее не может
продолжить свое выполнение. Это зависит от тяжести нарушения и от
организации операционной системы, которая обрабатывает исключения. И если
ошибка или ловушка не может быть исправлена, программу так же следует
закрыть.
При возникновении исключения процессор иногда помещает в стек код ошибки,
по которому обработчик исключения может проанализировать и, возможно,
исправить возникшую ошибку.
Все исключения обрабатываются операционной системой. В случае микроядерных
систем этим занимается микроядро. Вот о микроядрах мы и поведем наш
дальнейший разговор.
Микроядерные системы.
В первых выпусках я уже касался этой темы, но тогда я ограничился буквально
несколькими словами. Но теперь мы решили двигаться именно в сторону
микроядерности, значит стоит поподробнее рассказать, что это такое.
Принцип микроядерности заключается в том, что ядро практически не выполняет
операций, связанных с обслуживанием внешних устройств. Эту функцию выполняют
специальные программы-сервера. Ядро лишь предоставляет им возможность
обращаться к устройствам. Помимо этого ядро обеспечивает многозадачность
(параллельное выполнение программных потоков), межпроцессное взаимодействие
и менеджмент памяти.
Приложения (как и сервера) у нас работают на третьем, непривилегированном
кольце и не могут свободно обращаться к портам ввода/вывода или dma памяти.
Тем более не могут сами устанавливать свои обработчики прерываний. Для
использования ресурсов процессы обращаются к ядру с просьбой выделить
необходимые ресурсы в их распоряжение. Осуществляется это следующим
образом:
Для обеспечения доступа к портам ввода/вывода используются возможности
процессоров, впервые появившиеся intel 80386. У каждой задачи (в сегменте
состояния задачи (TSS)) существует карта доступности портов ввода/вывода.
Приложение обращается к ядру с "просьбой" зарегистрировать для нее диапазон
портов. Если эти порты до тех пор никем не были заняты, то ядро
предоставляет их в распоряжение процесса, помечая их как доступные в карте
доступности ввода/вывода этого процесса.
DMA память, опять таки после запроса у ядра, с помощью страничного
преобразования подключается к адресному пространству процесса. Настройка
каналов осуществляется ядром по "просьбе" процесса.
Доступ к аппаратным прерываниям (IRQ) осуществляется сложнее. Для этого
процесс порождает в себе поток (thread), и сообщает ядру, что этот поток
будет обрабатывать какое-то IRQ. При возникновении аппаратного прерывания,
которое обрабатывает всетаки ядро, данный процесс выходит из состояния
спячки, в котором он находился в ожидании прерывания, и ставится в очередь
к менеджеру процессов. Такие потоки должны иметь более высокий приоритет,
чем все остальные, дабы вызываться как можно скорее.
Но, как я говорил, ядро выполняет еще некоторые функции, немаловажная из
которых - это межпроцессное взаимодействие. Оно представляет из себя
возможность процессов обмениваться сообщениями между собой. В отличии от
монолитных систем в микроядерных системах межпроцессное взаимодействие
(Inter Process Communication или IPC) это едва ли не основное средство
общения между процессами, и поскольку все драйвера у нас такие же процессы,
микроядерное IPC должно быть очень быстрым. Быстродействие IPC достигается
за счет передачи сообщений без промежуточного буферизирования в ядре. Либо
непосредственным переписыванием процессу-получателю, либо с помощью маппинга
страниц (если сообщения большого размера).
Менеджер памяти имеет как бы две стороны. Первая сторона - внутренняя,
распределение памяти между приложениями, организация свопинга (который тоже
осуществляется не ядром непосредственно, а специальной программой-сервером)
никаким образом не интересует остальные программы. Но другая сторона -
внешняя служит именно для них. Программы могут запросить у ядра во временное
пользование некоторое количество памяти, которое ядро им обязательно
предоставит (в разумных пределах... гигабайта два... не больше... :). Или
же программы могут запросить у ядра какой-то определенный участок памяти.
Это бывает необходимо программам-серверам. И это требование ядром также
вполне может быть удовлетворено при условии, что никакая другая программа
до того не забронировала этот участок памяти для себя.
На этом я заканчиваю сегодняшний выпуск. Если вам что-то не понятно,
задавайте вопросы, адрес моей электронной почты вы всегда можете найти
внизу выпуска.
(C)Москва, 2001. Авторское право принадлежит Валяеву А.Ю. Публичное размещение материала из рассылки, а также его использование полностью или частично в коммерческих или иных подобных целях без письменного согласия автора влечет ответственность за нарушение авторских прав.