Сегмент состояния задачи - Task state segment

В сегмент состояния задачи (TSS) является структурой на x86 -на базе компьютеров, хранящих информацию о задача. Он используется Операционная система ядро для управления задачами. В частности, в TSS хранится следующая информация:

  • Регистр процессора государственный
  • Разрешения порта ввода-вывода
  • Указатели стека внутреннего уровня
  • Предыдущая ссылка на TSS

Вся эта информация должна храниться в определенных местах в пределах TSS, как указано в IA-32 руководства.

Расположение TSS

TSS может находиться где угодно в объем памяти. Сегментный регистр, называемый регистром задач (TR), содержит селектор сегментов который указывает на действительный дескриптор сегмента TSS, который находится в GDT (дескриптор TSS не может находиться в LDT ). Следовательно, чтобы использовать TSS, ядро ​​операционной системы должно выполнить следующие действия:

  1. Создайте запись дескриптора TSS в GDT
  2. Загрузите TR с помощью селектора сегмента для этого сегмента
  3. При необходимости добавьте информацию в TSS в памяти

В целях безопасности TSS следует размещать в памяти, доступной только для ядро.

Реестр задач

Регистр TR - это 16-битный регистр, который содержит селектор сегмента для TSS. Его можно загрузить через LTR инструкция. LTR является привилегированной командой и действует аналогично загрузке других сегментных регистров. Регистр задач состоит из двух частей: видимой и доступной для программиста и невидимой, которая автоматически загружается из дескриптора TSS.

Регистрировать состояния

TSS может содержать сохраненные значения всех x86 регистры. Это используется для переключение задач. В Операционная система может загрузить TSS значениями регистров, которые нужны новой задаче, и после выполнения аппаратного переключения задачи (например, с помощью IRET инструкция) процессор x86 загрузит сохраненные значения из TSS в соответствующие регистры. Обратите внимание, что некоторые современные операционные системы, такие как Windows и Linux[1] не используйте эти поля в TSS, поскольку они реализуют переключение программных задач.

Обратите внимание, что во время переключения аппаратной задачи определенные поля Старый TSS обновляются текущим содержимым регистров ЦП до значений из новый ТСС читаются. Таким образом, некоторые поля TSS доступны для чтения / записи, а другие - только для чтения:

  • Поля чтения / записи: чтение и запись при переключении аппаратных задач.
    • Все регистры общего назначения (EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP);
    • Все сегментные регистры (CS, DS, ES, FS, GS, SS);
    • Текущее состояние выполнения (EIP, EFlags);
    • В Связь поле в новый TSS, если переключение задачи произошло из-за ВЫЗОВ или же INT а не JMP.
  • Поля только для чтения: читать только при необходимости, как указано.
    • Регистр управления 3 (CR3), также известный как базовый регистр каталога страниц (PDBR).
      Чтение во время аппаратного переключения задач.
    • Регистр локальной таблицы дескрипторов (LDTR);
      Чтение во время аппаратного переключения задач.
    • Три пары стека уровней привилегий (SS0: ESP0, SS1: ESP1, SS2: ESP2);
      Читать во время межуровневого ВЫЗОВ или же INT установить новый стек.
    • Указатель Bitmap порта ввода-вывода (IOPB) и собственно битовую карту порта ввода / вывода;
      Читать во время В, ИЗ, INS или же ВЫХОДЫ инструкция, если CPL> IOPL чтобы подтвердить, что инструкция является законной (см. Разрешения порта ввода-вывода ниже).

В 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 CPU будет искать в TSS SS0 и ESP0 и загружать их значения в SS и ESP соответственно. Это позволяет ядру использовать стек, отличный от стека пользовательской программы, а также сделать этот стек уникальным для каждой пользовательской программы.

Новая функция, представленная в AMD64 Расширение называется таблицей стека прерываний (IST), которая также находится в TSS и содержит логические (сегмент + смещение) указатели стека. Если таблица дескрипторов прерываний указывает используемую запись IST (их 8), вместо этого процессор загрузит новый стек из IST. Это позволяет использовать заведомо исправные стеки в случае серьезных ошибок (НМИ или же Двойная ошибка Например). Ранее запись об исключении или прерывании в IDT указывала на шлюз задачи, заставляя процессор переключаться на задачу, на которую указывает шлюз задачи. Исходные значения регистров были сохранены в текущем TSS на момент возникновения прерывания или исключения. Затем процессор устанавливает регистры, включая SS: ESP, на известное значение, указанное в TSS, и сохраняет селектор в предыдущем TSS. Проблема здесь в том, что аппаратное переключение задач не поддерживается на AMD64.

Предыдущая ссылка на TSS

Это 16-битный селектор, который позволяет связать этот TSS с предыдущим. Это используется только для переключения аппаратных задач. Увидеть IA-32 инструкции для деталей.

Использование TSS в Linux

Хотя 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 см. В томе 3a, главе 6 документа IA-32 руководство.[3]

TSS в режиме x86-64

В x86-64 архитектура не поддерживает аппаратные переключатели задач. Однако TSS все еще можно использовать на машине, работающей в 64-битных расширенных режимах. В этих режимах TSS по-прежнему полезен, так как хранит:

  1. Указатель стека обращается для каждого уровня привилегий.
  2. Адреса указателей для таблицы стека прерываний (необходимость в этом обсуждается в разделе указателей стека внутреннего уровня выше).
  3. Адрес смещения битовой карты разрешения ввода-вывода.

Кроме того, в этих режимах регистр задач расширяется, чтобы иметь возможность хранить 64-битный базовый адрес.

Рекомендации

  1. ^ Бове, Даниэль Пьер; Чезати, Марко (2006). Понимание ядра Linux, третье издание. O'Reilly Media. п. 104. ISBN  978-0-596-00565-8. Получено 2009-11-23.
  2. ^ Даниэль П. Бове; Марко Чезати (2006). Понимание ядра Linux. books.google.com. О'Рейли. п. 104. ISBN  9780596554910. Получено 2014-02-25.
  3. ^ "Руководство разработчика программного обеспечения для архитектур Intel 64 и IA-32, том 3a". Получено 21 мая 2012.

внешняя ссылка