Адресация и многозадачность: Средства поддержки мультизадачности

Печать
Программирование - Архитектура и система команд микропроцессоров x86

 

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

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

Механизм мультизадачности

Механизм поддержки мультизадачности функционирует только в защищенном режиме. Его работа обеспечивается следующими элементами прикладной и системной архитектуры процессора:

 

Регистр задачи хранит селектор TSS текущей задачи. Сам TSS предназначен для хранения полного контекста и состояния задачи и уникален для каждой выполняемой задачи (см. рис. 2.6.).

 

Связь регистра задачи TR и сегмента состояния задачи TSS

Рис. 2.6. Связь регистра задачи TR и сегмента состояния задачи TSS

 

После сброса процессора механизм мультизадачности отключен, для его инициализации необходимо сначала перевести процессор в защищенный режим, затем создать TSS для новой задачи и загрузить командой LTR регистр задачи корректным селектором. Корректное выполнение программ в защищенном режиме возможно только при инициализированной мультизадачности. Даже если предстоит выполнять одну программу, она запускается как одна задача в мультизадачном окружении. Более сложные системы могут использовать развитые возможности процессора по диспетчеризации, сохранению состояния и переключению различных задач.

Типы задач и контекст задачи

Существует несколько типов задач, которые отличаются режимами работы процессора при их выполнении: 32-разрядные задачи, 16-разрядные задачи, задачи V86. Все эти задачи могут попеременно выполняться совершенно независимо друг от друга. Процессор обеспечивает полное переключение контекста и режима при переходе от одной задачи к другой. Переключение задач может осуществляться в следующих случаях:

  • при явном вызове командой CALL;
  • при явном переходе по команде JMP;
  • при неявном вызове (автоматически процессором) задачи обработки прерывания;
  • при неявном вызове задачи обработчика исключения;
  • при возврате из процедуры по команде IRET, когда EFLAGS.NT = 1.

Контекст каждой задачи хранится в соответствующем TSS и включает:

Таким образом, каждая задача может иметь: свое линейное адресное пространство, заданное своей локальной таблицей дескрипторов (LDT), свое физическое адресное пространство, расположенное в любой доступной области и задаваемое страничным механизмом (базовый адрес каталога страниц в CR3), свой протокол защиты, обеспечиваемый указателями на стеки разных уровней привилегий и картой ввода/вывода. Поле селектора TSS предыдущей задачи обеспечивает возможность возврата при последовательном вызове нескольких вложенных задач.

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

Нормальное переключение задач обеспечивается специальными дескрипторами в таблицах дескрипторов LDT, GDT или IDT. Такими дескрипторами являются 16- и 32-разрядные дескрипторы TSS и дескриптор шлюза задачи. Дескриптор шлюза задачи предназначен для перенаправления всех указывающих на него вызовов (CALL), переходов (JMP) и векторов прерываний (особых ситуаций) на обработку в отдельную задачу (рис. 2.7.).

 

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

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

 

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

  1. Получение селектор TSS новой задачи либо как операнда в командах CALL, JMP, либо из дескриптора шлюза задачи, либо из поля LINK сегмента состояния  текущей задачи (если переключение задач инициализировано командой IRET).
  2. Проверка соответствия всех уровней привилегий с целью определения допустимости переключения на новую задачу.
  3. Проверка дескриптора TSS новой задачи (сегмент присутствует и имеет корректный предел, не менее 67h для 32-битного TSS).
  4. Проверка того, что новая задача своботна (CALL, JMP, особая ситуация или прерывание) или занята (IRET).
  5. Проверка того, что TSS текущей (старой) задачи, TSS новой задачи и все дескрипторы, используемые при переключении задач, отображены страничным механизмом на физическую память (т.е. присутствуют в памяти).
  6. Очистка бита занятости задачи в TSS старой задачи, если переключение задач инициировано командами JMP или IRET (для CALL, особой ситуации или прерывания бит занятости остается установленным).
  7. Производится сохранение контекста старой задачи. Процессор определяет базовый адрес TSS текущей задачи по значению в регистре TR и затем последовательно сохраняет дянные из всех регистров общего назначения, селекторы из сегментных регистров, значение регистра EFLAGS (причем, если переключение задач инициировано командой IRET, процессор очищает флаг NT в сохраняемой копии регистра EFLAGS), значение указателя команд EIP и т.д.
    В данной точке процессор осуществляет переключение задачи. Это означает, что если какая-либо ошибка вознкает на шагах с 1 по 7, то переключения задач не происходит и процессор полностью возвращается в состояние, предшествовавшее команде, инициировавшей переключение задач. Но если ошибка происходит на последующих шагах, то процессор заканчивает переключение задач (без некоторых проверок) и генерирует соответствующую ошибку перед началом выполнения новой задачи (в этом случае обработчик ошибки должен сам полностью завершить переключение задач для запуска новой задачи).
  8. Если переключение задач было инициировано командой CALL, прерыванием или особой ситуацией, то процессор копирует селектор TSS старой задачи в поле LINK сегмента TSS новой задачи и устанавливает флаг NT в образе регистра EFLAGS, хранимом в TSS новой задачи.
  9. Если переключение задач было инициировано командами CALL, JMP, прерыванием или особой ситуацией, процессор устанавливает флаг занятости B в дескрипторе TSS новой задачи.
  10. Устанавливается флаг TS в регистре CR0.
  11. Производится запись в регистр TR значений селектора и дескриптора (в скрытую часть) TSS новой задачи.
  12. Производится чтение контекста новой задачи из TSS. Считываются значения всех регистров общего назначения, сегментных регистров, регистра флагов EFLAGSуказателя команд EIP и др. (в т.ч. значения для регистров LDTR, CR3).
  13. Начинается выполнение команд новой задачи.

 

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

Проверяемое условие

Исклю-чение

Код ошибки

Селектор TSS указывает на GDT и попадает в ее пределы

#GP

Селектор TSS новой задачи

Дескриптор TSS присутствует в памяти

#NP

Селектор TSS новой задачи

Дескриптор TSS отмечен как занятый (для команд CALL, JMP, исключений ипрерываний)

#GP

Селектор TSS предыдущей задачи из поля LINK сегмента TSS новой задачи

Дескриптор TSS не отмечен как занятый (для команды IRET)

#TS

Селектор TSS новой задачи

Предел сегмента TSS не меньше 67h для 32-битного TSS или 2Bh для16-битного TSS

#TS

Селектор TSS новой задачи

Проверки, осуществляемые после загрузки регистров из TSS новой задачи

Селектор LDT новой задачи в регистре LDTRкорректен (указывает на корректный дескриптор в таблице GDT)

#TS

Селектор LDT новой задачи

RPL (запрашиваемый уровень привилегий) селектора кодового сегмента соответствует DPL (уровень привилегий сегмента) кодового сегмента

#TS

Селектор сегмента кода новой задачи

Селектор стекового сегмента в регистре SS корректен (указывает на корректный дескриптор в таблице LDT или GDT)

#TS

Селектор сегмента стека новой задачи

Стековый сегмент присутствует в памяти

#SS

Селектор сегмента стека новой задачи

Уровень привилегий (DPL) стекового сегмента соответствует текущему уровню привилегий (CPL)

#TS

Селектор сегмента стека новой задачи

LDT новой задачи присутствует в памяти

#TS

Селектор LDT новой задачи

Селектор кодового сегмента в регистре CS корректен (указывает на корректный дескриптор)

#TS

Селектор сегмента кода новой задачи

Кодовый сегмент присутствует в памяти

#NP

Селектор сегмента кода новой задачи

Уровень привилегий (DPL) стекового сегмента соответствует запрашиваемому уровню привилегий (RPL) селектора сегмента

#TS

Селектор сегмента стека новой задачи

Селекторы в регистрах DS, ES, FS и GS корректны (указывают на корректные дескрипторы в таблицах LDT или GDT)

#TS

Селектор ошибочного сегмента

Сегменты, заданные селекторами в DS, ES, FS и GS, определены как читаемые

#TS

Селектор ошибочного сегмента

Сегменты, заданные селекторами в DS, ES, FS и GS, присутствуют в памяти

#NP

Селектор ошибочного сегмента

Уровень привилегий (DPL) сегментов, заданных селекторами в DS, ES, FS и GS соответствует текущему уровню привилегий (CPL)

#TS

Селектор ошибочного сегмента

 

Вложенные задачи

Для отслеживания цепочек последовательных вызовов задач предназначено поле LINK в сегменте TSS и флаг NT регистра EFLAGS. При вызове (командой CALL, прерыванием или особой ситуацией) новой задачи из кода другой задачи (напрямую или через дескриптор шлюза задачи) для индикации того, что новая задача является вложенной, устанавливается флаг NT.EFLAGS, а селектор TSS старой задачи помещается в поле обратной связи LINK сегмента TSS новой задачи. Указанные действия повторяются, если вложенная задача сама вызывает еще одну задачу и т.д. (см. рис. 2.8.).

При приходе команды IRET процессор производит возврат к задаче более высокого уровня. При этом поле LINK сегмента TSS закрываемой задачи используется для получения селектора TSS задачи, к которой производится возврат, флаг NT.EFLAGS после возврата устанавливается в значение, которое было сохранено в TSS перед вызовом вложенной задачи.

 

Связь между вложенными задачами

Рис. 2.8. Связь между вложенными задачами

 

В случае, если обращение к новой задаче производится командой JMP, новая задача не считается вложенной, флаг NT не устанавливается и поле LINK не используется.

Во всех случаях и для всех типов описываемых процессоров рекурсивный вызов задач невозможен. Процессор автоматически предотвращает такую возможность опираясь на значение флага B (занятость) в дескрипторе TSS вызываемой задачи.

 

Таблица 2.4. Влияние различных способов переключения задач на флаги EFLAGS.NT, CR0.TS, поле занятости дескриптора B, поле обратной связи LINK

Флаг или поле

Команда JMP

Команда CALL или прерывание

Команда IRET

Поле B (Busy) дескриптора TSS новой задачи

Флаг устанавливается (должен находится в сброшенном состоянии перед выполнением команды)

Флаг устанавливается (должен находится в сброшенном состоянии перед выполнением команды)

Флаг сбрасывается (должен находится в установленном состоянии перед выполнением команды)

Поле B (Busy) дескриптора TSS старой задачи

Флаг сбрасывается

Без изменений (флаг уже находится в установленном состоянии)

Флаг сбрасывается

Флаг NT новой задачи

Без изменений

Флаг устанавливается

Устанавливается в значение, считываемой из TSS новой задачи

Флаг NT старой задачи

Без изменений

Без изменений

Флаг сбрасывается

Поле LINK в TSS новой задачи

Без изменений

Загружается значением селектора TSS старой задачи

Без изменений

Поле LINK в TSS старой задачи

Без изменений

Без изменений

Без изменений

Флаг CR0.TS

Флаг устанавливается

Флаг устанавливается

Флаг устанавливается

 

 

Особенности переключения задач в программах, использующих FPU и расширенные системы команд MMX, 3DNow!, SIMD

При переключении задач процессор не производит автоматического переключения контекста для FPU/MMX/SIMD. Программа должна самостоятельно позаботится о том, чтобы значения в соответствующих FPU/MMX/SIMD-регистрах соответствовали текущей выполняемой задаче. Однако ввиду того, что в мультизадачных операционных системах переключение задач может происходить в случайные моменты времени (например, ввиду генерации внешнего прерывания) в процессор введен специальный механизм для поддержки переключения контекста FPU/MMX/SIMD. Работа этого механизма обуславливается наличием специального флага индикации переключения задач CR0.TS, который устанавливается во всех без исключения случаях переключения задач.

В нормальном режиме флаг CR0.TS сброшен и все команды FPU/MMX/SIMD выполняются в обычном режиме. После того, как произошло переключение задач CR0.TS автоматически устанавливается. Теперь любая команда FPU/MMX/SIMD (в т.ч. и все 3DNow! команды) перед своим исполнением вызовет генерацию особой ситуации #NM (Сопроцессор отсутствует).

Многозадачные операционные системы должны содержать в себе специальную программу обработчик прерывания #NM, которая обеспечит соответствие контекста FPU/MMX/SIMD текущей задаче. Т.е. этот обработчик при получении управления должен: сбросить флаг CR0.TS; проверить, соответствует ли текущий контекст FPU/MMX/SIMD текущей выполняемой задаче, если соответствует — управление возвращается к прерванной команде, если нет — обработчик должен сохранить значения всех регистров FPU/MMX/SIMD в специальной области памяти, загрузить из другой специальной области памяти значения всех этих регистров для новой задачи и затем передать управление прерванной команде. Естественно в обработчик должен быть заложен механизм слежения за текущими задачами для гарантии полного соответствия всех сохраняемых и загружаемых контекстов своим задачам.

Для сохранения контекста FPU/MMX/SIMD могут применяться различные команды и последовательности команд. Это вызвано прежде всего тем, что с развитием архитектуры процессоров старые команды для сохранения совместимости оставлялись без изменений, а новые команды вводились для обеспечения работы появившихся расширений.

 

Таблица 2.5. Команды, применяемые для сохранения/восстановления контекста FPU/MMX/SIMD

Контекст FPU/MMX (в т.ч. 3DNow!)

FSAVE/FNSAVE, FRSTOR

Контекст FPU/MMX/SIMD

FXSAVE, FXRSTOR

 

Специальный флаг CR4.OSFXSR введен для индикации операционной системой того, осуществляет ли она переключение контекста FPU командами FXSAVE и FXRSTOR, обеспечивая таким образом переключение контекста SIMD.