PersCom — Компьютерная Энциклопедия Компьютерная Энциклопедия

Память. Верхний уровень

Память. Верхний уровень

Защита

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

Проверки, выполняемые процессором при выполнении команд, можно подразделить на следующие категории:

•Limit checks — проверки превышения границы сегмента;

•Type checks — проверки допустимости типа дескриптора при обращении, возможности чтения или записи в сегмент;

•Privilege level checks — проверки уровня привилегий;

•Restriction of addressable domain — ограничение доступа к отдельным диапазонам адресов;

•Restriction of procedure entry-points — проверки доступности точек входа в процедуры (механизм шлюзования);

•Restriction of instruction set — проверки привилегированных команд.

Рассмотрим более подробно ситуации, в которых возможно срабатывание механизма защиты.

Прежде всего отметим, что в защищенном режиме каждой программе может быть присвоен один из четырех уровней привилегий (0 — наиболее привилегированный, 3 -наименее) — см. рисунок ниже.

Кольца защиты

Операционная система при формировании дескрипторов и заполнении дескрипторной таблицы назначает для каждого сегмента уровень привилегий (обычно 0 — для сегментов операционной системы, 3 — для программ-приложений) и записывает соответствующий код в поле DPL дескриптора.

При загрузке сегмента кода, его DPL помещается в младшие биты регистра CS это значение называется CPL (Current Privilege Level — текущий уровень привилегий), т.е. уровень привилегий выполняемого в данный момент кода.

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

RAID 6: Двумерная четность для обеспечения большей надежности

Этот пункт можно рассмотреть в контексте соотношения отказоустойчивость/пропускная способность. RAID 5 предлагают, по существу, лишь одно измерение дисковой матрицы, вторым измерением которой являются секторы. Теперь рассмотрим объединение дисков в двумерный массив таким образом, чтобы секторы являлись третьим измерением (см. рисунок). Мы можем иметь контроль четности по строкам, как в системах уровня 5, а также по столбцам, которые, в свою очередь, могут расслаиваться для обеспечения возможности параллельной записи. При такой организации можно преодолеть любые отказы двух дисков и многие отказы трех дисков. Однако при выполнении логической записи реально происходит шесть обращений к диску: за старыми данными, за четностью по строкам и по столбцам, а также для записи новых данных и новых значений четности. Для некоторых применений с очень высокими требованиями к отказоустойчивости такая избыточность может оказаться приемлемой, однако для традиционных суперкомпьютеров и для обработки транзакций данный метод не подойдет.

В общем случае, если доминируют короткие записи и считывания, а стоимость емкости памяти не является определяющей, — наилучшую производительность демонстрируют системы RAID уровня 1. Однако если стоимость емкости памяти существенна, либо если можно снизить вероятность появления коротких записей (например, при высоком коэффициенте отношения числа считываний к числу записей, при эффективной буферизации последовательностей считывания-модификации-записи, либо при приведении коротких записей к длинным с использованием стратегии кэширования файлов), RAID уровня 5 могут обеспечить очень высокую производительность, особенно в терминах отношения стоимость/производительность.

 

Байт доступа и типы сегментов. Типы сегментов кода и данных

Поле TYPE байта доступа в дескрипторах кода или данных содержит четыре однобитовых поля:

•Бит11 служит признаком вида сегмента: 0 — сегмент данных, 1 — сегмент кода.

•Бит8 — A-бит обращения (Access). При создании дескрипторов операционная система должна установить значение этого бита для всех сегментов нулевым. При загрузке сегмента в память процессор автоматически устанавливает этот бит в 1, сигнализируя тем самым, что к данному сегменту уже было обращение.

•Биты 9 и 10 имеют разное значение для сегментов данных и кода.

•Для сегмента данных:

Бит9 — W-бит разрешения записи (Write) : 0 — только чтение,
1- чтение/запись. При попытке записи в сегмент "только для чтения" произойдет прерывание по исключительной ситуации.

Бит10 — D-бит (Direction) — направление расширения сегмента. Если этот бит установлен, то сегмент предназначен для стека, который растет в направлении младших адресов. Этот бит влияет на способ контроля процессором превышения размера сегмента.

Для сегмента кода:

Бит9 — R-бит (Read) — разрешение чтения. Если этот бит установлен, то сегмент кода можно читать.

Бит10 — C (Conforming) — бит "подчинения" (будет рассмотрен далее).

Имеется 13 типов системных дескрипторов (см. таблицу ниже).

Для системного дескриптора поле TYPE содержит код типа объекта, описываемого дескриптором, сегментами являются только некоторые из этих объектов. Значения кодов также приведены ниже (см. таблицу ниже).

Привилегированные команды:

1. Нулевого приоритета;

2. Чувствительные команды:

•команды ввода.вывода,
•работы с прерываниями;

3. Команды работы с флагами IOPL IF.

Типы системных дескрипторов

Ряд команд может выполняться только программами, имеющими 0-й уровень приоритета (т.е. операционной системой). Вот эти команды:

•LGDT — Load GDT register;

•LLDT — Load LDT register;

•LTR — Load task register;

LIDT — Load IDT register;

•MOV (control registers) — Load and store control registers;

•LMSW — Load machine status word;

•CLTS — Clear task-switched flag in register CR0;

•MOV (debug registers) — Load and store debug registers;

INVD — Invalidate cache, without writeback;

•WBINVD — Invalidate cache, with writeback;

•INVLPG — Invalidate TLB entry;

•HLT - Halt processor;

•RDMSR — Read Model-Specific Registers;

WRMSR — Write Model-Specific Registers;

•RDPMC — Read Performance-Monitoring Counter;

•RDTSC — Read Time-Stamp Counter.

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

1) CPL — уровень привилегий текущего сегмента кода

2) DPL — уровень привилегий сегмента, к которму происходит обращение

3) RPL — запрашиваемый уровень привилегий; это поле в селекторе операнда программист может установить сам, но не выше CPL, т.е. RPL CPL. Это позволяет понизить уровень привилегий.
Условие доступа: max (CPL, RPL =< DPL).

Загрузка сегмента данных

При обращении за операндами:

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

2) Сравнивается offset и предел сегмента, если превышение — возбуждается исключение.

3) Если команда пытается записать в Read-Only сегмент данных (бит R=1) или в страницу, для которой запрещена запись, — также генерируется исключение.

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

При передаче управления посредством дальнего перехода, дальнего вызова или при программном прерывании адрес перехода задан (в команде или в векторе прерывания) в формате:

селектор_сегмента : смещение.

При этом происходит перезагрузка сегментного регистра CS новым значением селектора. Обычно это возможно только при выполнении условия CPL >=DPL (т.е. переход на более привилегированный сегмент кода невозможен и вызовет исключение). Однако это лишило бы возможности использования прикладной программой с низким уровнем привилегий сервисов ОС, работающих на более высоком уровне привилегий. Для разрешения этого противоречия реализованы два разных механизма.

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

Первый механизм разрешения противоречий

Однако этот способ не всегда годится. Иногда сервису ОС требуется обладать высоким уровнем привилегий, чтобы выполнить требуемую функцию (например, динамически выделить память — это часто означает — создать новый сегмент с заполнением дескрипторной таблицы).

Второй способ (см. рисунок ниже). Такой вызов можно безопасно допустить, если обеспечить возможность входа в вызываемый модуль только в предопределенной точке и при этом контролировать процесс передачи параметров. Это делается путем указания в дальнем адресе вызова не селектора сегмента кода, а селектора так называемого шлюза вызова (Call Gate). При таком переходе указываемое в адресе перехода смещение игнорируется (никак не используется) потому что "настоящие" селектор сегмента, куда будет выполнен вызов, содержатся в дескрипторе шлюза вызова, на который указывает селектор сегмента, заданный в команде call far.

Схема трансляции через шлюз

Функции шлюза (см. рисунок ниже):

1. Определение точки входа в процедуру;

2. Задание уровня привилегированности, требуемого для входа в процедуру;

3. Переключение стеков.

При проверке привилегий анализируются:

1) RPL>=CPL;

2) Текущий уровень привилегий должен позволить обратиться к "шлюзу вызова":

CPL>=CallGate-DPL.

Функции шлюза

Есть четыре разновидности шлюзов:

•Шлюз вызова подпрограммыCall gates;
•Шлюз программного прерывания или исключенияTrap gates;
•Шлюз аппаратного прерыванияInterrupt gates;
•Шлюз задачиTask gates.

Механизмы защиты при срабатывании вызывают исключения защищенного режима:

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

•Проверка при загрузке сегментных регистров:

- Превышение лимита таблицы дескрипторов (13);
- Несуществующий дескриптор сегмента (11 или 12);  — Нарушение привилегий (13).

- Загрузка неверного дескриптора или типа сегмента (13);

--загрузка в SS сегмента данных только чтения или сегмента кода,
-- загрузка управляющих дескрипторов в DS, ES или SS,
-- загрузка только исполняемых сегментов в DS, ES или SS,
-- загрузка сегмента данных в CS.

•Проверка ссылок операндов:

- Запись в сегмент кода или сегмент данных только для чтения (13);
- Чтение только из исполняемого сегмента кодов (13);
- Превышение лимита сегмента (12 или 13).

Проверка привилегий инструкций:

- CPL 0 при выполнении инструкций LIDT, LLDT, LGDT, LTR, LMSW, CTS, HLT, операций с регистрами DRn, TRn, CRn (13);
- CPL > IOPL при выполнении инструкций STI, CLI, а для 80286 еще и инструкции LOCK (13);
- CPL > IOPL при выполнении инструкций IN, INS, OUT, OUTS с портами, не разрешенными битовой картой ввода-вывода (13).

При выполнении команд IRET и POPF с недостаточным уровнем привилегий не изменяются биты IF и IOPL в регистре флагов, что не порождает исключений:

-IF не меняется, при CPL>IOPL;
-IOPL не меняется, если CPLO.

•Команды тестирования условий защиты:

Для того чтобы задачи не "нарывались" на срабатывание защиты, в систему команд введены специальные инструкции тестирования указателей. Они позволяют быстро удостовериться в возможности использования селектора или сегмента без риска порождения исключения:

ARPL — выравнивание RPL: он приравнивается максимальному значению из текущего RPL-селектора и поля RPL в указанном регистре. При изменении RPL устанавливается ZF=1;

•VERR — верификация чтения: если сегмент, на который указывает селектор, допускает чтение, устанавливается ZF=1;

•VERW — верификация записи: если сегмент, на который указывает селектор, допускает запись, устанавливается ZF=1;

•LSL — чтение лимита сегмента в регистр, если позволяют привилегии. При успехе устанавливается ZF=1;

LAR — чтение байта доступа дескриптора в регистр, если позволяют привилегии. При успехе устанавливается ZF=1.

Другие уровни

RAID 7

RAID 7 — зарегистрированная торговая марка компании Storage Computer Coraparation, отдельным уровнем RAID не является. Структура массива такова: на n − 1 дисках хранятся данные, один диск используется для складирования блоков чётности. Запись на диски кешируется с использованием оперативной памяти, сам массив требует обязательного ИБП (источник бесперебойного питания); в случае перебоев с питанием происходит повреждение данных.

RAID 10

RAID 10 — зеркалированный массив, данные в котором записываются последовательно на несколько дисков, как в RAID 0. Эта архитектура представляет собой массив типа RAID 0, сегментами которого вместо отдельных дисков являются массивы RAID 1. Соответственно, массив этого уровня должен содержать как минимум 4 диска. RAID 10 объединяет в себе высокую отказоустойчивость и производительность.

Нынешние контроллеры используют этот режим по умолчанию для RAID 1+0. То есть, один диск основной, второй — зеркало, считывание данных производится с них поочередно. Сейчас можно считать, что RAID 10 и RAID 1+0 — это просто разное название одного и того же метода зеркалирования дисков. Утверждение, что RAID 10 является самым надёжным вариантом для хранения данных, ошибочно, т.к., несмотря на то, что для данного уровня RAID возможно сохранение целостности данных при выходе из строя половины дисков, необратимое разрушение массива происходит при выходе из строя уже двух дисков, если они находятся в одной зеркальной паре.

 

Комбинированные уровни

Помимо базовых уровней RAID 0 - RAID 5, описанных в стандарте, существуют комбинированные уровни RAID 1+0, RAID 3+0, RAID 5+0, RAID 1+5, которые различные производители интерпретируют каждый по-своему.

  • RAID 1+0 — это сочетание зеркалирования и чередования (см. выше).
  • RAID 5+0 — это чередование томов 5-го уровня.
  • RAID 1+5 — RAID 5 из зеркалированных пар.

Комбинированные уровни наследуют как преимущества, так и недостатки своих «родителей»: появление чередования в уровне RAID 5+0 нисколько не добавляет ему надёжности, но зато положительно отражается на производительности. Уровень RAID 1+5, наверное, очень надёжный, но не самый быстрый и, к тому же, крайне неэкономичный: полезная ёмкость тома меньше половины суммарной ёмкости дисков…

Стоит отметить, что количество жёстких дисков в комбинированных массивах также изменится. Например для RAID 5+0 используют 6 или 8 жёстких дисков, для RAID 1+0 — 4, 6 или 8.

Matrix RAID

Matrix RAID — это технология, реализованная фирмой Intel в своих чипсетах начиная с ICH6R. Строго говоря, эта технология не является новым уровнем RAID (ее аналог существует в аппаратных RAID-контроллерах высокого уровня), она позволяет, используя небольшое количество дисков организовать одновременно один или несколько массивов уровня RAID 1, RAID 0 и RAID 5. Это позволяет за сравнительно небольшие деньги обеспечить для одних данных повышенную надёжность, а для других высокую скорость доступа и производства.

Программный (англ. software) RAID

Для реализации RAID можно применять не только аппаратные средства, но и полностью программные компоненты (драйверы). Например, в системах на ядре Linux существуют специальные модули ядра, а управлять RAID-устройствами можно с помощью утилиты mdadm. Программный RAID имеет свои достоинства и недостатки. С одной стороны, он ничего не стоит (в отличие от аппаратных RAID-контроллеров, цена которых от $250). С другой стороны, программный RAID использует ресурсы центрального процессора, и в моменты пиковой нагрузки на дисковую систему процессор может значительную часть мощности тратить на обслуживание RAID-устройств.

Ядро GNU/Linux 2.6.28 (последнее из вышедших в 2008 году) поддерживает программные RAID следующих уровней: 0, 1, 4, 5, 6, 10. Реализация позволяет создавать RAID на отдельных разделах дисков, что аналогично описанному выше Matrix RAID. Поддерживается загрузка с RAID.

ОС семейства Windows NT, такие как Windows NT 3.1/3.5/3.51/NT4/2000/XP/2003 изначально, с момента проектирования данного семейства, поддерживает программный RAID 0, RAID 1 и RAID 5 (см. Dynamic Disk). Более точно, Windows XP Pro поддерживает RAID 0. Поддержка RAID 1 и RAID 5 заблокирована разработчиками, но, тем не менее, может быть включена, путем редактирования системных бинарных файлов ОС.[1] Windows Server 2003 — 0, 1 и 5. Windows XP Home RAID не поддерживает.

В ОС FreeBSD есть несколько реализаций программного RAID. Так, atacontrol, может как полностью строить программный RAID, так и может поддерживать полуаппаратный RAID на таких чипах как ICH5R. Во FreeBSD, начиная с версии 5.0, дисковая подсистема управляется встроенным в ядро механизмом GEOM. GEOM предоставляет модульную дисковую структуру, благодаря которой родились такие модули как gstripe (RAID 0), gmirror (RAID 1), graid3 (RAID 3), gconcat (объединение нескольких дисков в единый дисковый раздел). Так же существуют устаревшие классы ccd (RAID 0, RAID 1) и gvinum (менеджер логических томов vinum). Начиная с FreeBSD 7.2 поддерживается файловая система ZFS в которой можно собирать следующие уровни RAID: 0, 1, 5, 6, а также комбинируемые уровни.

OpenSolaris и Solaris 10 используют Solaris Volume Manager, который поддерживает RAID-0, RAID-1, RAID-5 и любые их комбинации как 1+0. Поддержка RAID-6 осуществляется в файловой системе ZFS.

Дальнейшее развитие идеи RAID

Идея RAID-массивов — в объединении дисков, каждый из которых рассматривается как набор секторов, и в результате драйвер файловой системы «видит» как бы единый диск и работает с ним, не обращая внимания на его внутреннюю структуру. Однако, можно добиться существенного повышения производительности и надёжности дисковой системы, если драйвер файловой системы будет «знать» о том, что работает не с одним диском, а с набором дисков.

Рассмотрим случай, когда требуется увеличение скорости и размера диска без требования увеличения надёжности — случай, когда используется RAID-0. Если драйвер файловой системы будет знать, что имеет дело с несколькими дисками, он постарается размещать небольшие файлы так, чтобы каждый файл оказался целиком на одном диске — это эквивалентно снижению фрагментированности файловой системы и позволяет существенно ускорить работу.

Более того: при разрушении любого из дисков в составе RAID-0 вся информация в массиве окажется потерянной. Но если драйвер файловой системы разместил каждый файл на одном диске, и при этом правильно организована структура директорий, то при разрушении любого из дисков будут потеряны только файлы, находившиеся на этом диске; а файлы, целиком находящиеся на сохранившихся дисках, останутся доступными.


Поддержка многозадачности в защищенном режиме процесоров 386+

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

Далее перечислены эти структуры, а также регистры процессора, поддерживающие многозадачность:

1) Сегменты состояния задачи (Task State Segment TSS);
2) Дескрипторы сегмента состояния задачи;
3) Дескрипторы шлюзов вызова задачи;
4) Регистр задач.

Рассмотрим эти элементы подробнее.

Сегмент состояния задачи TSS

Его структура изображена на рисунке (см. рисунок ниже). Каждая задача имеет собственный TSS.

Поля TSS можно разделить на две категории:

•Динамические. Процессор обновляет их значения при каждом переключении данной задачи. В эту категорию входят следующие поля:

- регистры общего назначения EAX, ECX, EDX, EBX, ESP, EBP, ESI и EDI;
- сегментные регистры ES, CS, SS, DS, FS и GS;
- регистр флагов EFLAGS;
- счетчик команд IP;
- селектор сегмента TSS предыдущей задачи.

Формат сегмента TSS

•Статические. При переключении задачи процессор только читает, но не обновляет эти поля. Их значения устанавливаются операционной системой при создании задачи. К этим полям относятся следующие:

- Селектор локальной дескрипторной таблицы задачи (каждая задача может иметь одну собственную LDT, но может и не иметь);

- Управляющий регистр CR3 (это BDPR — регистр базового адреса таблицы каталогов страниц;

- Логические адреса стеков для уровней привилегий 0, 1 и 2;

- Значение T-бита (включения режима пошаговой отладки);

-Базовый адрес карты разрешения портов ввода/вывода и карты переназначения прерываний (необязательные элементы). Если эти элементы присутствуют, то они сохраняются в верхних адресах TSS.

Дескриптор TSS

Сегмент состояния задачи, подобно другим сегментам, описывается дескриптором, имеющим следующий формат (см. рисунок ниже):

Формат дескриптора TSS

Рассмотрим особенности полей дескриптора. Поля базы, предела и DPL имеют то же назначение, что и для сегментов данных. Предел сегмента TSS должен быть равен или больше величины 67h (на 1 меньше минимального размера TSS — 68h). Размер TSS может быть и больше, при этом добавочное пространство может быть использовано операционной системой по своему усмотрению).

Задача не реентерабельна (т.е. не допускает рекурсивных вызовов). Для выявления попыток рекурсивного вызова служит бит занятости B (Busy Bit). Если задача была вызвана (и затем, возможно, прервана, например, вызовом друтой задачи), бит занятости устанавливается и остается установленным, что и будет признаком рекурсивного вызова при попытке вызвать эту задачу.

Переключение задачи происходит вследствие передачи управления через дескриптор TSS командами JMP или CALL, а также при прерываниях или исключениях через этот дескриптор.

Регистр задачи

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

Привилегированные команды LTR и STR позволяют читать и писать этот регистр.

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

Дескриптор TSS обычно имеет высокий уровень привилегий, что исключает его использование "обычной" программой. Для обеспечения защищенного доступа к задаче используется шлюз задачи — дескриптор, имеющий низкий уровень привилегий, но обеспечивающий "косвенный" вызов на дескриптор TSS с высоким уровнем привилегий (см. рисунок ниже).

Формат шлюза TSS

Обратите внимание, что при использовании шлюза задачи защита анализирует DPL дескриптора шлюза, а не DPL дескриптора TSS.

Схема переключения задачи

Рисунок ниже иллюстрирует схему переключения задачи.

Процессор передает управление другой задаче в одном из четырех случаев:

1) Текущая задача выполняет JMP или CALL на дескриптор TSS.
2) Текущая задача выполняет JMP или CALL на шлюз задачи.
3) Прерывание или исключение происходит через шлюз задачи, находящийся в IDT.
4) Текущая задача выполняет команду IRET при установленном флаге NT (в CR0).

Схема переключения задачи

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

При переключении задачи в ее TSS происходит заполнение ссылки на TSS предыдущей задачи. Эта информация используется для возврата на прерванную задачу после окончания задачи, ее прервавшей. Операционная система может модифицировать эти связи, изменяя записи в TSS. Каждая задача может иметь собственную LDT и систему трансляции страниц. Регистр PDBR (Page Directory Base Register) (CR3) загружается новым значением из TSS при переключении задачи.