Организация мультизадачности в процессорах семейства Х86, страница 3

Предел дескриптора TSS, как уже упоминалось, не может быть меньше 67h, иначе возникает особый случай нарушения защиты. Поле DPL в байте прав доступа не означает уровень привилегий самого сегмента TSS, поскольку никакие задачи обращаться к нему не могут. DPL дескриптора TSS (как и DPL шлюза вызова) просто показывает, какие программы могут обращаться к задаче, которые определяются данным дескриптором TSS. Поскольку дескриптор TSS относится к системным дескрипторам, его бит S в байте прав доступа равен нулю. Бит B (Busy) в поле типа байта прав доступа является битом занятости и, при переключении на данную задачу, устанавливается в состояние 1, т.е. показывает, что задача находится в процессе выполнения, или находится в оперативной памяти и ожидает исполнения (задача «занята»). Бит занятости используется в мультипроцессорных системах для предотвращения выполнения одной и той же задачи несколькими процессорами.

Попытка переключения на задачу, отмеченную как занятая, приводит к особому случаю, уходу процессора на прерывание.

При переключении задачи командой CALL, бит занятости B устанавливается как в дескрипторе выходящей, старой задачи, так и в дескрипторе входящей, новой задачи. Однако, при переключении задачи командой JMP, при котором возвращение к старой задаче не предусматривается, бит занятости устанавливается в 1 только в дескрипторе новой задачи. Бит занятости старой задачи, в этом случае, сбрасывается в нулевое состояние.

При переключении задач с помощью команд CALL или JMP должны выполняться правила доступа, установленные для обращения к сегментам данных, т.е. должно выполняться условие DPL ≥ max{CPL, RPL}. Здесь значение DPL определяется соответствующим полем в байте прав доступа дескриптора сегмента TSS входящей задачи. Следовательно, допускается переключение только на ту задачу, уровень привилегий которой не больше уровня привилегий текущей, выходящей задачи, а также уровня привилегий запроса. Переключение же на задачу с более высоким уровнем привилегий, командой CALL ( но не командой JMP) возможно только через шлюзы задач.

Дескрипторы любого сегмента вызываются через его селектор.  Но если селекторы сегментов кода, данных и стека, передаются в соответствующие сегментные регистры (CS, DS, SS, ES, FS, GS), то селекторы, вызывающие дескрипторы сегментов TSS, засылаются в специальный регистр TR (Task Register) – регистр задач. Загрузку регистра TR можно осуществлять командой LTR. Однако, как правило, команда LTR используется только при инициализации системы. В дальнейшем, в процессе переключения задач, он перезагружается процессором при выполнении программы, по командам JMP, CALL, IRET.  Занесение же  состояния регистра LTR в память, или какой-либо регистр общего назначения осуществляется командой STR. Как и все сегментные регистры, регистр TR имеет свой теневой регистр, в котором запоминается дескриптор TSS на все то время, пока данная задача является процессом, т.е. находится в стадии исполнения. При переключении на новую задачу, операционная система посылает новый селектор в TR и содержимое теневого регистра меняется на дескриптор новой задачи.

                      4. Дескриптор шлюза задачи.

Сегмент состояния задачи TSS при переключении задачи может быть вызван не непосредственно, пересылая селектор из команды в регистр задачи TR, а косвенно, через шлюз задачи, в котором хранится собственно селектор TSS вызываемой задачи. Шлюзы задачи могут размещаться как в глобальной или локальной дескрипторной таблице, так и в дескрипторной таблице прерываний. В GDT и LDT  размещают дескрипторы шлюзов задач при переключении задач с помощью команд CALL и JMP в программах операционной системы а, при переключении задач по запросам на прерывание, дескрипторы шлюзов размещаются  в IDT. Следовательно, дескрипторы шлюзов задач являются единственными дескрипторами, которые могут размещаться во всех этих трех таблицах.

Естественно при этом возникает вопрос о целесообразности такого косвенного способа переключения через шлюзы вызова. Эта целесообразность вызывается тремя причинами.

·  Первой причиной использования шлюзов задач является уже

                     упомянутая необходимость передавать управление на более

                     привилегированные задачи.

·  Кроме того, переключение задач по запросам прерываний, или особых случаев, возможно только через шлюзы задач, размещенных в дескрипторной таблице прерываний  IDT.

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

                          5.   Переключение задач.

Переключение задачи могут вызвать четыре события.

1.  Выходящая задача выполняет команду FAR CALL или FAR JMP, и селектор выбирает дескриптор TSS.

2.  Выходящая задача выполняет команду FAR CALL или FAR JMP, и селектор выбирает дескриптор шлюза задачи.

3.  Возникло аппаратное или программное прерывание и соответствующий элемент дескрипторной таблицы прерывания содержит дескриптор шлюза задачи.

4.  Выходящая задача выполняет команду IRET для возврата в предыдущую задачу. Если при этом, в регистре EFLAGS бит NT (Nested Task) вложенной задачи находился в состоянии 1, то эта команда приводит к переключению задачи. Если же бит NT находился в состоянии 0, то перед этим произошло не переключение задач, а был запрос на обычное прерывание и команда IRET воспринимается как окончание выполнения процедуры обработки прерывания. Поэтому, в этом случае, после появления команды IRET, процессор передает управление на команду программы, следующей за командой CALL.