Сегмент состояния задачи ( TSS ) представляет собой структуру , на x86 основанного компьютеров , которые содержат информацию о задаче . Он используется ядром операционной системы для управления задачами. В частности, в TSS хранится следующая информация:
Вся эта информация должна храниться в определенных местах в пределах TSS, как указано в руководствах IA-32 .
TSS может находиться где угодно в памяти . Сегментный регистр, называемый регистром задач (TR), содержит селектор сегмента, который указывает на действительный дескриптор сегмента TSS, который находится в GDT (дескриптор TSS может не находиться в LDT ). Следовательно, чтобы использовать TSS, ядро операционной системы должно выполнить следующие действия:
В целях безопасности TSS следует размещать в памяти, доступной только ядру .
Регистр TR - это 16-битный регистр, который содержит селектор сегмента для TSS. Его можно загрузить с помощью инструкции LTR . LTR является привилегированной инструкцией и действует аналогично загрузке других сегментных регистров. Регистр задач состоит из двух частей: видимой и доступной для программиста и невидимой, которая автоматически загружается из дескриптора TSS.
TSS может содержать сохраненные значения всех регистров x86 . Это используется для переключения задач . Операционная система может загрузить TSS со значениями регистров , что новые потребности и задачи после выполнения аппаратного переключателя задач (например, с IRET инструкцией) х86 CPU загружает сохраненные значения из TSS в соответствующие регистры. Обратите внимание, что некоторые современные операционные системы, такие как Windows и Linux [1] , не используют эти поля в TSS, поскольку они реализуют переключение программных задач.
Обратите внимание, что во время переключения аппаратных задач определенные поля старого TSS обновляются текущим содержимым регистров ЦП до того, как будут считаны значения из нового TSS. Таким образом, некоторые поля TSS доступны для чтения / записи, а другие - только для чтения:
EAX
, EBX
, ECX
, EDX
, ESI
, EDI
, EBP
, ESP
);CS
, DS
, ES
, FS
, GS
, SS
);EIP
, EFlags
);Link
Поле в новом TSS, если переключатель задач был вызван CALL
или , INT
а не JMP
.CR3
), также известный как базовый регистр каталога страниц ( PDBR
).LDTR
);SS0:ESP0
, SS1:ESP1
, SS2:ESP2
);CALL
или INT
устанавливайте новый стек.IOPB
) и собственно Bitmap порта ввода-вывода;IN
, OUT
, INS
или OUTS
инструкции , если CPL > IOPL
для подтверждения инструкции является законной (см I разрешения порта ввода / вывода ниже).PDBR
Поле на самом деле очень первый один считаны из нового TSS: с переключателя задач оборудования также может переключиться на совершенно другое отображение таблицы страниц, все остальные поля (особенно LDTR
) по сравнению с новым отображением.
TSS содержит 16-битный указатель на битовую карту разрешений порта ввода-вывода для текущей задачи . Это растровое изображение, обычно устанавливаемое операционной системой при запуске задачи, указывает отдельные порты, к которым программа должна иметь доступ. Битовая карта ввода-вывода - это битовый массив разрешений на доступ к портам; если у программы есть разрешение на доступ к порту, в соответствующем битовом индексе сохраняется «0», а если у программы нет разрешения, там сохраняется «1». Если предел сегмента TSS меньше, чем полная битовая карта, предполагается, что все недостающие биты равны «1».
Эта функция работает следующим образом: когда программа выдает команду порта ввода-вывода x86, такую как IN или OUT (см. Списки инструкций x86 - и обратите внимание, что существуют версии длиной в байтах, словах и двойных словах), оборудование выполнит Уровень привилегий ввода-вывода (IOPL) проверяет, имеет ли программа доступ ко всем портам ввода-вывода. Если текущий уровень привилегий (CPL)программы численно превышает уровень привилегий ввода-вывода (IOPL) (программа имеет меньшие привилегии, чем указано в IOPL), программа не имеет доступа к портам ввода-вывода для всех портов. Затем оборудование проверит битовую карту разрешений ввода-вывода в TSS, чтобы увидеть, может ли эта программа получить доступ к конкретному порту (портам) в инструкции IN или OUT. Если (все) соответствующие биты в битовой карте разрешений порта ввода-вывода являются очищенными, программе разрешен доступ к порту (портам) и разрешено выполнение инструкции. Если (любой из) соответствующий бит (ы) установлен / установлены - или если (любой из) бит (ы) превышает предел сегмента TSS - программа не имеет доступа, и процессор генерирует общую защиту вина . Эта функция позволяет операционным системам предоставлять выборочный доступ к портам для пользовательских программ.
TSS содержит 6 полей для указания нового указателя стека при изменении уровня привилегий. Поле SS0 содержит селектор сегмента стека для CPL = 0, а поле ESP0 / RSP0 содержит новое значение ESP / RSP для CPL = 0. Когда прерывание происходит в защищенном (32-битном) режиме, процессор x86 будет искать в TSS SS0 и ESP0 и загружать их значения в SS и ESP соответственно. Это позволяет ядру использовать стек, отличный от стека пользовательской программы, а также сделать этот стек уникальным для каждой пользовательской программы.
Новая функция, представленная в расширениях AMD64, называется таблицей стека прерываний (IST), которая также находится в TSS и содержит логические (сегмент + смещение) указатели стека. Если таблица дескрипторов прерываний указывает запись IST для использования (их 8), процессор вместо этого загрузит новый стек из IST. Это позволяет использовать заведомо исправные стеки в случае серьезных ошибок ( NMI или двойная ошибка).Например). Ранее запись об исключении или прерывании в IDT указывала на шлюз задачи, заставляя процессор переключаться на задачу, на которую указывает шлюз задачи. Исходные значения регистров были сохранены в текущем TSS на момент возникновения прерывания или исключения. Затем процессор устанавливает регистры, включая SS: ESP, на известное значение, указанное в TSS, и сохраняет селектор в предыдущем TSS. Проблема здесь в том, что аппаратное переключение задач не поддерживается на AMD64.
Это 16-битный селектор, который позволяет связать этот TSS с предыдущим. Это используется только для переключения аппаратных задач. См. Подробности в руководствах по IA-32 .
Хотя TSS может быть создан для каждой задачи, выполняемой на компьютере, ядро Linux создает только один TSS для каждого процессора и использует их для всех задач. Этот подход был выбран, поскольку он обеспечивает более легкую переносимость на другие архитектуры (например, архитектура AMD64 не поддерживает аппаратные переключатели задач), а также улучшенную производительность и гибкость. Linux использует только битовую карту разрешений порта ввода-вывода и функции внутреннего стека TSS; другие функции необходимы только для аппаратных переключателей задач, которые ядро Linux не использует. [2]
Вектор исключения x86 10 называется недопустимым исключением TSS (#TS). Он выдается процессором, когда что-то идет не так с доступом к TSS. Например, если прерывание происходит в CPL = 3 и передает управление на CPL = 0, TSS используется для извлечения SS0 и ESP0 / RSP0 для коммутатора стека. Если регистр задачи содержит неправильный селектор TSS, будет сгенерирована ошибка #TS. Исключение Invalid TSS никогда не должно происходить во время нормальной работы операционной системы и всегда связано с ошибками ядра или отказом оборудования.
Дополнительные сведения об исключениях TSS см. В главе 6 тома 3a руководства IA-32 . [3]
Архитектура x86-64 не поддерживает аппаратные переключатели задач. Однако TSS все еще можно использовать на машине, работающей в 64-битных расширенных режимах. В этих режимах TSS по-прежнему полезен, поскольку в нем хранятся:
Кроме того, в этих режимах регистр задач расширяется, чтобы иметь возможность хранить 64-битный базовый адрес.