Все сервисы работают в изолированных адресных пространствах. Если им что-нибудь надо, то они обращаются к микроядру.
Интерфейс заключается в пересечении границы. Одна граница – один интерфейс.
Если ЦП поддерживает всего два кольца защиты, то Супервизор тоже запихивают в KernelRing.
Итак, есть два интерфейса: Kernel|Supervisorи Supervisor|User. В супервизоре все процессы работают в своих адресных пространствах. Все проверки безопасности – на уровне супервизора.
В Windows2000 это сделано так.
|
Каждый модуль (FS, менеджер управления память, менеджер управления объектами и т.д.) запущен как отдельный поток со своим контекстом.
Драйвер может сам генерировать потоки, но его базовый поток – поток ядра.
GDI находится в супервизоре только с Win2000, раньше он был в Win32.exe. Без Win32.exe ни одно Win32-приложение работать не будет.
Синхронизация запросов ввода/вывода в ядре
У любого объекта Windows есть заголовок синхронизации, их можно ставить в очередь событий.
Процесс блокируется в ожидании некоторого события, которое ставится в очередь событий.
Теперь, выполнив запрос, драйвер говорит, что событие произошло и процесс продолжает работу. Иногда, выдав запрос, нужно параллельно с его обработкой выполнять другие действия.
Запросы делятся на:
- блокирующие
- неблокирующие
В системах, поддерживающих неблокирующие запросы ввода/вывода, есть модификатор команд:
IO$READ + NoWait
Теперь возникает другая проблема – неблокирующий запрос выполнен, а как узнать, успешно ли он завершен? Это знает только драйвер.
Решение – в контексте задачи создается буфер IOSB (InputOutputStatusBlock), в который драйвер помещает результаты выполнения операции. Это же происходит и при блокирующий запросах, но все это делается неявно.
Итак, для выполнения операции нужно следующее:
1. Запрос (код операции, параметры)
2. Координаты запроса (FCB, #LBN, длина)
3. Адрес буфера
4. IOSB
5. Объект синхронизации.
IORP – структура для хранения параметров запроса ввода-вывода. ОС копирует в этот пакет параметры из запроса QIO, которые хранятся в системе. Т.е. параметры в системном пуле и не […..]. Этими параметрами можно пользоваться. Если параметры типа указатель, то они имеют смысл только в контексте задачи. Если на процессоре наша задача, то в CR3 нужное страничное преобразование. Если на CR3 адрес ТСП другого приложения, то указатель будет неправильным. Поэтому драйвер не сможет выполнить обмен с буфером. Надо драйверу передать корректный указатель. Указатель должен существовать в контексте драйвера. Нужно получить новый логический адрес – в контексте драйвера. Нужно выяснить физический адрес буфера, полностью преобразовать его в логический адрес в контексте драйвера.
У драйвера контекст является контекстом, который совпадает с физической памятью. Т.е. там физический адрес совпадает с линейным. И этот адрес кладем в IORP. Поэтому нужно запретить перемещение и выгрузку – зафиксировать страницу. Также нужно запретить свопинг задач (выгрузка задачи полностью на диск).
Если таких задач много (зафиксировавшихся), то система начинает тормозить, и, в конце концов, падает.
Поэтому обмен между драйвером и буфером нужно делать через специальную область памяти – неперемещаемую.
Буферизованный обмен – это обмен через специальную область памяти – неперемещаемую. На самом деле при таком обмене существуют 2 буфера – один в неперемещаемой области памяти, второй в области приложения.
Запись: ОС заводит системный буфер, копирует туда буфер задачи, драйвер читает из буфера.
Чтение: ОС заводит буфер, драйвер пишет туда, ОС копирует из системного буфера в буфер приложения.
Это позволяет не ограничивать функции задачи.
Проблемы здесь в размерах. Например, по кластерам 128кБ на кластер.
Буферизованный обмен – для медленных, с небольшими буферами [устройств].
Небуферизованный – для быстрых и с большими буферами.
Ничего нет.
На примере MS-DOS (система с начальной настройкой)
PnP – аппаратный интерфейс, служащий для динамической конфигурации и реконфигурации системы.
Этот механизм предполагает:
1. сигнализацию о вставлении/удалении устройства
2. идентификацию устройств.
PnP не может осуществлять динамическую реконфигурацию самой ОС, а только внешних устройств.
Драйверы надо писать если:
- данный ресурс будет разделяемым
- данным устройством можно управлять только из контекста ядра.
Второе условие означает, что прикладная программа может не успевать обрабатывать данные.
Синхронные запросы: полученные с их помощью данные потерять нельзя. Такими устройствами можно управлять из прикладной задачи (это обычно специализированные устройства). Драйвер писать неэффективно.
Если устройство не генерирует прерывание, то точка входа драйвера по прерыванию цепляется к таймеру (для опроса) – polling.
Если READY = 1, то операция, запрошенная у ВУ завершена. Этот бит постоянно опрашивается (программно).
Если работаем в ВУ на прикладном уровне, то придется самим опрашивать регистры ВУ. В серьезных ОС прерывания на прикладном уровне недопустимы.
Файловая система – это набор правил хранения и обработки информации.
Файловый процессор – программа, которая выполняет эти правила.
|
В правилах есть постоянные и переменные параметры. Переменные параметры должны быть определены в метке тома. Ее положение – жестко заданная константа в любой ФС. Том – накопитель ФС.
Задачи ФС:
1. Оптимально разместить данные на носителе
2. Найти потом эти данные.
Необходимо присвоить каждому набору данных имя и дать возможность:
1. автору определить это имя
2. по имени найти набор данных
Файлы хранятся непрерывными сегментами, следовательно, каждый файл характеризуют два числа – номер начального сектора и длина. Так как файлы – непрерывны, то для последующего увеличения их размера резервируется несколько секторов.
Каталог – массив записей фиксированного размера. Сам каталог имеет фиксированную, заранее определенную длину. Эта константа хранится в метке тома. Формат записей заранее определен. Это набор полей, одно из которых – имя, а остальные – сведения, необходимые для нахождения файла на диске.
Размер записи определяется количеством кластеров, так, чтобы можно было описать кластер с наибольшим номером.
Вместо индексного файла теперь индексные узлы – inode, размером в один сектор. Место выделяется блоками, их описание хранится в индексном файле. Метка тома теперь называется Суперблок. Создается связанный список свободных блоков. Нельзя сделать undelete, т.к. список портится.
Введены множественные битовые карты.
|
Если произойдет сбой во время модификации суперблока (там лежит ссылка на первую карту свободных блоков), то диск почти не восстановим.
Выделение логическими блоками. Идеологически – почти HPFS.
Индекс файла строится следующим образом:
По мере роста размера файла, сначала применяется непосредственные ссылки на блоки, далее одноуровневые, затем двухуровневые, а потом и трехуровневые ссылки на подындексы.
Но остается основная проблема – надо сделать индексный файл переменной длинны, следовательно, он теряет свойство непрерывности. Это означает, что он должен быть файлом и где-то надо хранить информацию о нем.
С появлением сетей, единицей учета становится уже группа файлов, а не один файл.
Нельзя ставить на диски меньше 100 МБ. Эффективно работает с дисками в несколько ГБ.
Вся информация, в т.ч. и для файлового процессора, становится файлом. Пропадает служебная информация.
MFT2 – копия MFT сразу после форматирования.
Индекс уже описывает не файл, а некий набор данных, причем набор данных является множеством атрибутов. Каждый атрибут имеет имя и содержимое.
В одном индексе может описываться не один файл, а набор файлов. Файлы называются потоками – name : stream, где name – имя набора, stream – имя файла в наборе.