Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Запрос ввода-вывода (IRP). Схема выполнения ввода-вывода в стеке драйверов.




 

При осуществлении операции ввода/вывода диспетчер ввода/вывода создает специальный пакет, описывающий эту операцию - пакет запроса ввода/вывода (I/O Request Packet, IRP). Обработка такого пакета может происходить поэтапно несколькими объектами-устройствами. IRP содержит всю необходимую информацию для полного описания запроса Ввода - вывода Диспетчеру Ввода/вывода и драйверам устройств. IRP описывается стандартной структурой типа "IRP", показанной на рис. 10.

Структура IRP специально разработана для поддержки многоуровневой модели ввода/вывода, при которой запрос ввода/вывода последовательно обрабатывается стеком из нескольких драйверов.

Для обеспечения этого каждый пакет запроса ввода/вывода состоит из двух частей: "фиксированной" части и Стека Ввода/вывода. Фиксированная часть IRP содержит информацию относительно той части запроса, которая или не изменяется от драйвера к драйверу, или которую не надо сохранять при передаче IRP от одного драйвера к другому.

Стек Ввода/вывода содержит набор Стеков Размещения Ввода/вывода, каждый из которых содержит информацию, специфическую для каждого драйвера, который может обрабатывать запрос. В стеке размещения ввода/вывода для каждого устройства, которое должно принимать участие в обработке пакета, содержатся указатели на объект-устройство, которое будет обрабатывать запрос, и на объект-файл, для которого была инициирована операция ввода/вывода. Пакеты IRP всегда выделяются из невыгружаемой системной памяти (nonpaged pool), поэтому к ним может осуществляться обращение из функций, работающих на любом уровне IRQL.

Как уже говорилось, драйверы подразделяются на три класса по их положению в стеке драйверов: драйверы высшего уровня, драйверы промежуточного уровня и драйверы низшего уровня.

Драйвер высшего уровня - это верхний драйвер в стеке драйверов, получающий запросы через Диспетчер ввода/вывода от компонентов прикладного уровня. Драйвер высшего уровня (или, что более правильно, устройство высшего уровня) имеет один или несколько стеков размещения ввода/вывода. Число стеков размещения ввода/вывода устанавливается Диспетчером ввода/вывода в поле StackSize объекта-устройства. По умолчанию это значение равно 1. Присваивание происходит при создании устройства функцией IoCreateDevice(). Если вы создаёте многоуровневый драйвер, вы должны установить StackSize на 1 больше, чем StackSize объекта-устройства, над которым будете размещать свое устройство. В случае, если ваше устройство будет использовать больше одного устройства уровнем ниже, поле StackSize этого устройства должно быть на 1 больше максимального значения StackSize из всех устройств уровнем ниже.

 

40. Структура API ядра ОС Windows: Kernel API, Windowing API, Messaging API. Функции ZwXXX/NtXXX в пользовательском режиме и в режиме ядра.

 

Ядро состоит из следующих компонентов:

· Исполнительная система ( Executive ) - управление памятью, процессами и потоками;

· Ядро ( Kernel ) - планирование потоков, диспетчеризация прерываний и исключений и др. (реализовано в Ntoskrnl . exe);

· Драйверы устройств ( Device Drivers ) - драйверы аппаратных устройств, сетевые драйверы, драйверы файловых систем;

· Уровень абстрагирования от оборудования ( Hardware Abstraction Layer , HAL) - изолирует три вышеперечисленных компонента от различий между аппаратными архитектурами (реализован в Hal.dll);

· Подсистема поддержки окон и графики ( Windowing And Graphics System ) - функции графического пользовательского интерфейса ( Graphic User Interface , GUI) (реализована в Win32k.sys).

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

Исполняющая система ( Executive ), в состав которой входит ядро и уровень аппаратных абстракций HAL, обеспечивает общий сервис системы, который могут использовать все подсистемы среды. Каждая группа сервиса находится под управлением одной из отдельных составляющих исполняющей системы: диспетчера объектов ( Object Manager ) диспетчера виртуальной памяти ( Virtual Memory Manager ); диспетчера процессов ( Process Manager ) средства вызова локальных процедур ( Local Procedure Call Facility ); диспетчера ввода - вывода (E/O Maneger ); мониторы безопасности ( Security Reference Monitor ). Монитор безопасности совместно с процессором входа в сиситему ( Logon ) и защищёнными подсистемами реализует модель безопасности Windows NT. Верхний уровень исполняющей системы называется системным сервисом ( System Services ).

Native API для Windows NT является средством, которое реализует контролируемый вызов системных сервисов, исполняемых в режиме ядра. Этот интерфейс API является интерфейсом системных вызовов и не предназначается для непосредственного использования пользовательскими программами, кроме того, его документация ограничена. Native API предоставляется коду пользовательского режима библиотекой ntdll.dll. Библиотека ntdll.dll, имеющая точки входа в Native API для кода пользовательского режима, содержит также код загрузки модуля и запуска потока процесса. Однако большинство входов в Native API являются заглушками, которые просто передают управление режиму ядра.

Все функции прикладного уровня, вызывающие это прерывание, сосредоточены в модуле ntdll.dll и имеют в своем названии префикс Nt либо Zw , например, NtCreateFile ()/ ZwCreateFile (). Точка входа для двух таких имен одна. Вызов многих функций различных подсистем рано или поздно приведет к вызову соответствующей функции из ntdll.dll. При этом не все, что есть в ntdll.dll вызывается из подсистемы Win32.

Вызов системных сервисов возможен не только из прикладной программы, но и из ядра ОС, то есть из драйверов. Имена соответствующих функций ядра имеют префикс либо Zw , либо Nt ( ZwCreateFile (), NtCreateFile ()). Функции с префиксом Zw обращаются к сервисам посредством прерывания 2Е, тогда как функции с префиксом Nt являются собственно точками входа стандартных системных сервисов. Из этого следует, что число функций с префиксом Nt неизменно, а множество этих функций является подмножеством функций с префиксом Zw .

 

41. Переход из пользовательского режима в режим ядра. Таблицы описателей функций ОС Windows. Диспетчеризация вызова Kernel API и Windowing+ Messaging API. Понятие UI-потока.

 

Прикладные программы могут переключаться из пользовательского режима в режим ядра, обращаясь к системному сервису. Например, Windows-­функции ReadFile в ходе своего выполнения приходит­ся вызывать внутреннюю подпрограмму Windows — она­ то и считывает дан­ные из файла. Так как эта подпрограмма обращается к внутрисистемным структурам данных, она должна выполняться в режиме ядра. Переключение из пользовательского режима в режим ядра осуществляется специальной командой процессора. Операционная система перехватывает эту команду, обнаруживает запрос системного сервиса, проверяет аргументы, которые поток передал системной функции, и выполняет внутреннюю подпрограм­му. Перед возвратом управления пользовательскому потоку процессор пере­ключается обратно в пользовательский режим. Благодаря этому операцион­ная система защищает себя и свои данные от возможной модификации пользовательскими процессами. Так что ситуация, когда пользовательский поток часть своего времени работает в пользовательском режиме, а часть — в режиме ядра, совершенно нормальна.

Все функции, создающие объекты ядра, возвращают описатели, которые привязаны к конкретному процессу и могут быть использованы в любом потоке данного процесса Значение описателя представляет собой индекс в таблице описателей, принадлежащей процессу, и таким образом идентифицирует место, где хранится информация, связанная с объектом ядра. Всякий раз, когда Вы вызываете функцию, принимающую описатель объекта ядра как аргумент, Вы передаете ей значение, возвращенное одной из Create-функций. При этом функция смотрит в таблицу описателей, принадлежащую Вашему процессу, и считывает адрес нужного объекта ядра. Если Вы передаете неверный индекс (описатель), функция завершается с ошибкой и GetLastError возвращает 6 (ERROR_INVALID_HANDLE). Это связано с тем, что на самом деле описатели представляют собой индексы в таблице, их значения привязаны к конкретному процессу и недейовительны в других процессах.

Потоки пользовательского режима классифицируются в ядре как потоки, имеющие пользовательский интерфейс(UI-потоки) и не имеющие его (non UI-потоки). Non UI-поток становится UI автоматически, как только делает вызов функции Windowing или Messaging API.

UI-потоки:

· Имеют стек > 12 кбайт (увеличение переменной, хранящей максимальный размер стека)

· Драйвер Win32K.sys отслеживает все такие потоки (это драйвер виртуального устройства, видеосистемы)

· Содержат указатели на переменную KeServiceDescripterTableShadow, эта переменная содержит указатель на массив из четырех таблиц указателей на функции обработки сервисов, 2-ой элемент этого массива – таблица дескрипторов, указывающих на функции в библиотеке драйвера Win32k.sys.

 


Поделиться:

Дата добавления: 2015-01-29; просмотров: 89; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты