Реферат по предмету "Информатика"


Разработка драйвера виртуального жесткого диска

--PAGE_BREAK--Таким образом, виртуальный диск будет храниться в памяти как одномерный массив байт заданного размера. Для чтения данных, информация копируется из области памяти образа диска в буфер инициатора запроса. Для записи — копирование происходит в обратном направлении.
Следующим шагом выберем, каким образом мы зарезервируем память для диска. Для резервирования памяти в режиме ядра Windows предоставляет специальные системные вызовы. Существуют следующие типы резервируемой памяти:
·              Страничная память(Paged memory) – виртуальная память, которая может быть перемещена системой на жесткий диск в любой момент времени. В случае, если приложение обратиться к отсутствующей в физической памяти области своей виртуальной памяти, то возникает исключение по отсутствию страницы в памяти. В результате системный обработчик перехватывает это исключение и загружает в физическую память отсутствующую страницу. Однако при работе в режиме ядра, когда уровень приоритета равен или выше DISPATCH_LEVEL, это исключение создаст ситуацию, когда системный обработчик не может подгрузить страницу т.к. его IRQL меньше текущего.
·              Нестраничная память(Nonpaged memory) – эта память никогда не может быть перемещена системой на жесткий диск и всегда остается в физической оперативной памяти. В результате, обращаться к этой памяти можно при любом уровне IRQL. Объем данной памяти ограничен даже при наличии достаточного объема физической памяти в Windows 2000 660 Мбайтами, а в Windows XP 1300 Мбайтами.
Поскольку обращение к образу диска происходит при уровне привилегий PASSIVE_LEVEL или DISPATCH_LEVEL, но в особых ситуациях этот приоритет может быть выше. Поэтому во избежание возникновения ситуации, когда страница отсутствует в памяти, и мы ее не сможем подгрузить – виртуальный диск будет использовать нестраничную память. Дополнительно мы увеличим быстродействие драйвера, т.к. уже не требуется подгружать отсутствующие страницы с жесткого диска.
2.3 Доступ к передаваемым данным Рассмотрим, каким образом драйвер может получить доступ к передаваемым данным. Пользовательский процесс, вызывая функцию API (например, WriteFile), передаёт ей указатель на буфер, в котором размещается записываемая информация. Однако, передаваемый виртуальный адрес действительно будет указывать на записываемую информацию только в контексте данного процесса. Операции же ввода/вывода в драйвере происходят в контексте произвольного процесса. Из-за смены таблиц страничного преобразования при переключении процессов использовать переданный виртуальный адрес в произвольном контексте совершенно недопустимо.
Для операций ввода/вывода архитектура операционной предусматривает два специальных метода передачи буфера данных, принадлежащего инициатору запроса:
·              Буферизированный (buffered I/O). Драйверу в пакете запроса ввода/вывода передаётся указатель на копию исходного буфера в невыгружаемой памяти (поле AssociatedIrp.SystemBuffer). Подсистема ввода/вывода отвечает за точное соответствие содержимого этого буфера передаваемым данным. Этот метод, в основном, используется для устройств, не предающих больших объёмов данных: манипуляторы, низкоскоростные коммуникационные линии и т. п.
·              Прямой (direct I/O). В этом случае система блокирует страницы пользовательского буфера, чтобы они не были выгружены на диск во время передачи данных. Расположение пользовательского буфера в физической памяти описывается структурой MDL (Memory Descriptor List), доступной в пакете запроса ввода/вывода через поле MdlAddress. По этой структуре необходимо настроить системную таблицу страниц на тот же буфер в физической памяти. Это осуществляется функцией MmGetSystem, которая возвращает виртуальный адрес буфера в системной области памяти. Данный метод эффективен с большими объёмами данных, например, при работе с дисковыми накопителями.
Для драйвера виртуального диска будет использоваться прямой метод, который обеспечивает возможность обмена большими данными и высокую скорость передачи.
2.4 Обработка запросов Plug and Play В процессе работы диспетчер ввода вывода может динамически управлять состоянием устройства: запускать, останавливать и выгружать. Реализация этих функций драйвером устройства хранения обеспечивает при обработке специфичных PnP IRP пакетов. В таблице 2 приведены описания IRP пакетов, которые должны поддерживаться.
Таблица 2
IRP_MN_Xxx
Описание
IRP_MN_START_DEVICE
Инициализация устройства с заданными ресурсами
IRP_MN_QUERY_STOP_DEVICE
Проверка осуществимости остановки устройства для перераспределения ресурсов
IRP_MN_STOP_DEVICE
Остановка устройства с потенциальной возможность. перезапуска или удаления из системы
IRP_MN_CANCEL_STOP_DEVICE
Уведомляет, что предыдущий запрос на остановку не получит дальнейшего развития
IRP_MN_QUERY_REMOVE_DEVICE
Проверка осуществимости безопасного удаления устройства
IRP_MN_REMOVE_DEVICE
Выполнить безопасное удаление устройства
IRP_MN_CANCEL_REMOVE_DEVICE
Уведомляет, что предыдущий запрос на удаление не получит дальнейшего развития
IRP_MN_SURPRISE_REMOVAL
Уведомляет, что устройство было удалено без предварительного предупреждения
Применительно к виртуальному диску большая часть этих сообщений не влечет каких-либо дополнительных действий, т.к. у рамдиска нет дополнительных буферов, данные с которые должны быть записаны на диск при остановке устройства, или поддержки функций управления электропитанием устройства. Поэтому для виртуального диска существует внутренняя переменная, которая хранит текущее состояние устройства.
Основным состоянием диска будет WORKING – когда диск находится в рабочем состоянии. Остальные состояния(приведенные в таблице 3) носят информативный характер, чтобы узнать текущий режим работы диска. При операциях доступа к устройству будет осуществляться проверка состояния WORKING, и только при нем доступ к диску разрешен.
Таблица 3
Состояние
Значение
STOPPED
Устройство остановлено
WORKING
Устройство работает
PENDINGSTOP
Устройство ожидает остановки
PENDINGREMOVE
Устройство ожидает удаления
SURPRISEREMOVED
Устройство удалено без предварительного предупреждения
REMOVED
Устройство удалено
UNKNOWN
Устройство в ошибочном состоянии
2.5 Обработка расширенных запросов Для управления сами устройством диспетчер ввода вывода посылает драйверу пакет с кодом управления вводом/выводом(IOCTL). Какие именно коды управления будет посылаться зависит от типа устройства. О том какие коды должен обязательно поддерживать классовый драйвер точно ничего не сказано. Поэтому приведенный далее список кодов управления был получен в процессе отладки драйвера, когда записывались получаемые драйвером IOCTL и выяснялась их функция.
Список кодов управления:
·              IOCTL_DISK_GET_PARTITION_INFO – сообщить о типе, размере и природе раздела диска.
·              IOCTL_DISK_GET_MEDIA_TYPES,
IOCTL_DISK_GET_DRIVE_GEOMETRY – сообщить о геометрии диска (количество цилиндров, дорожек, секторов)
·              IOCTL_DISK_IS_WRITABLE – проверка можно ли на диск записывать данные
·              IOCTL_DISK_SET_PARTITION_INFO – изменить тип раздела
·              IOCTL_MOUNTMGR_QUERY_POINTS – сообщить о символической ссылке для тома
·              IOCTL_MOUNTDEV_QUERY_DEVICE_NAME – сообщить об имени устройства
·              IOCTL_DISK_FORMAT_TRACKS – форматировать дорожки
·              IOCTL_DISK_MEDIA_REMOVAL – блокировать извлечение носителя
·              IOCTL_DISK_CHECK_VERIFY – проверить, сменился ли носитель (для съемных дисков)
2.6 Расчет геометрии диска При получении расширенного запроса IOCTL_DISK_GET_DRIVE_GEOMETRY или IOCTL_DISK_GET_MEDIA_TYPES требуется инициатору запроса передать информацию о геометрии диска. Драйвер виртуального диска заполняет стандартную структуру Windows DISK_GEOMETRY, где указываются следующие параметры:
Cylinders – количество цилиндров
TracksPerCylinder – количество дорожек на цилиндр
SectorsPerTrack – количество секторов на дорожку
BytesPerSector – размер сектора в байтах
MediaType – тип носителя
Тип носителя для жестких дисков должен быть равен FixedMedia.
Размер сектора примем равным 512 байтам, это стандарт де-факто для почти всех современных дисковых накопителей.
Количество дорожек и секторов будет фиксированным
TracksPerCylinder = 16   SectorsPerTrack = 32
Вычисляем количество цилиндров диска:
Cylinders = DiskSize /(BytesPerSector*SectorsPerTrack* TracksPerCylinder),
где DiskSize – размер диска.
Если количество цилиндров превышает 1023(такое ограничение было введено для совместимости со старыми версиями BIOS), то количество секторов на дорожку увеличивается вдвое и будет равно 64.
Таким образом максимальный размер рамдиска, для которого число цилиндров не превышает 1023 равен:
MaxDiskSize = 1023*16*64*512 = 536346624 байт= 511.5 Мбайт,
что более чем достаточно для нашей версии рамдиска.

2.7Структура драйвера
С учетом всего вышеизложенного требуется разработать классовый драйвер, который имеет монолитную структуру. Драйвер будет иметь следующие части:
·               Инициализация драйвера
·               Обработка запросов PnP и управления питанием
·               Обработка запросов записи/чтения данных
·               Обработка расширенных запросов
·               Выгрузка драйвера

3. ТЕХНОЛОГИЧЕСКИЙ РАЗДЕЛ
3.1 Выбор и обоснование языка и среды программирования Для разработки драйвера виртуального диска применялся пакет DDK (Driver Development Kit), который включает в себя все необходимые заголовочные файлы и библиотеки. Пакет DDK ориентирован на язык С. Драйвер разрабатывался на Windows 2003 Server DDK, т.к. она включает в себя как средства для разработки драйверов для Windows 2003 Server, так и последние версии средств для разработки драйверов ОС Windows 2000 и XP.
В качестве интегрированной среды разработки применялся Microsoft Visual C++ 6. Он предоставляет удобный интерфейс для написания программного кода на C, и позволяет компилировать его используя библиотеки пакета DDK.
Для отладки работы драйвера применялись программы DebugView и DriverMonitor из пакета NuMega Driver Studio 2.0, которые позволяют просматривать отладочные сообщения драйвера.
3.2 Структуры данных классового драйвера Параметры диска и его состояние хранятся в расширении устройства — структуре DEVICE_EXTENSION. Она всегда доступная через объект-устройство (DEVICE_OBJECT, поле DeviceExtension), она реализует наиболее удобный и рекомендованный Microsoft способ хранения таких данных. Структуру расширения определяет разработчик драйвера. Мы ее определим так:
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT LowerDeviceObject;
DEVICE_STATE DevState; // Текущее состояние устройство
IO_REMOVE_LOCK RemoveLock; // Блокировка устройства
ULONG Flags; // Флаг устройства
PUCHAR DiskImage; // Указатель на образ диска
DISK_GEOMETRY DiskGeometry; // Параметры геометрии диска
DISK_INFO DiskRegInfo; // Параметры диска из реестра
UNICODE_STRING SymbolicLink; // Символическая ссылка
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
Поля DeviceObject и LowerDeviceObject облегчают доступ к объектам-устройствам из различных участков драйвера. Они потребуются в дальнейшем. Поле RemoveLock служит для блокировки удаления устройства. DiskImage – содержит указатель на одномерный массив – образ диска. Поле DiskGeometry хранит геометрию диска. DevState содержит текущее состояние устройства. SymbolicLink – символическая ссылка, которая служит для обращения к драйверу.
Поле DiskRegInfo описывает параметры, которые расположены в реестре и используются драйвером для создания диска:
typedef struct _DISK_INFO
{
ULONG DiskSize; // Размер диска в байтах
ULONG RootDirEntries; // Количество элементов в корне
ULONG SectorsPerCluster; // Секторов на кластер
UNICODE_STRING DriveLetter; // Буква диска
} DISK_INFO, *PDISK_INFO;

3.3 Блокировка выгрузки устройства Когда система производит удаление нижестоящего устройства, она посылает ему PnP-запрос с функцией IRP_MN_REMOVE_DEVICE. Если же в этот момент драйвер чем-то занят, то он должен защитить своё устройство от преждевременной выгрузки из памяти. Для этого в системе предусмотрен объект «блокировка выгрузки» (remove lock). Он может быть «захвачен» и «освобождён». Внутри этого объекта имеется счётчик. Этот счётчик устанавливается в ноль при инициализации объекта (функция IoInitializeRemoveLock). Счётчик увеличивается на единицу при захвате объекта (IoAcquireRemoveLock) перед обработкой запроса и уменьшается при освобождении (IoReleaseRemoveLock).
Обработчик PnP-запроса с функцией IRP_MN_REMOVE_DEVICE гарантированно исполняется в контексте системного процесса. В этом обработчике перед удалением объекта-устройства над блокировкой выполняется действие «освободить и ждать» (IoReleaseRemoveLockAndWait). Оно уменьшает счётчик на единицу и блокирует системный процесс, пока счётчик не станет равным нулю. Следовательно, пока драйвер обрабатывает хотя бы один запрос к устройству, это устройство не будет удалено.
3.4 Процедуры драйвера виртуального диска   3.4.1 Инициализация драйвера Начнём с процедуры, вызываемой при инициализации драйвера — DriverEntry. Она определяется следующим образом:
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)

Тип NTSATUS, соответствующий возвращаемому значению, определяет тип ошибки. Многие функции драйвера возвращают значение этого типа. Если работа проходит успешно, результат принимает значение STATUS_SUCCESS.
В данной процедуре необходимо сообщить системе остальные процедуры обработки пакетов IRP:
Поскольку нам нужно сохранить параметры о пути реестра и признак того, что инициализировалось ли само устройство, то в структуре расширения драйвера заведем следующие поля:
DriverObject->MajorFunction[IRP_MJ_CREATE] = RamDskCreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = RamDskCreateClose; DriverObject->MajorFunction[IRP_MJ_READ] = RamDskReadWrite; DriverObject->MajorFunction[IRP_MJ_WRITE] = RamDskReadWrite; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RamDskIOCtl; DriverObject->MajorFunction[IRP_MJ_PNP] = RamDskDispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = RamDskDispatchPower; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = RamDskDispatchSystemControl; DriverObject->DriverExtension->AddDevice = RamDskAddDevice;  DriverObject->DriverUnload = RamDskUnload;
Массив MajorFunction устанавливает соответствие между кодом типа запроса IRP_MJ_NNN и диспетчерской функцией, которая его обрабатывает. Наш драйвер обрабатывает запросы на открытие и закрытие устройства (RamDskCreateClose), чтение и запись (RamDskReadWrite), расширенные запросы обработки IOCTL(RamDskIOCtl), запросы Plug and Play (RamDskDispatchPnp), функции управления питанием (RamDskDispatchPower), запросы от подсистемы инструментария Windows (RamDskDispatchSystemControl).
    продолжение
--PAGE_BREAK--


Не сдавайте скачаную работу преподавателю!
Данный реферат Вы можете использовать для подготовки курсовых проектов.

Поделись с друзьями, за репост + 100 мильонов к студенческой карме :

Пишем реферат самостоятельно:
! Как писать рефераты
Практические рекомендации по написанию студенческих рефератов.
! План реферата Краткий список разделов, отражающий структура и порядок работы над будующим рефератом.
! Введение реферата Вводная часть работы, в которой отражается цель и обозначается список задач.
! Заключение реферата В заключении подводятся итоги, описывается была ли достигнута поставленная цель, каковы результаты.
! Оформление рефератов Методические рекомендации по грамотному оформлению работы по ГОСТ.

Читайте также:
Виды рефератов Какими бывают рефераты по своему назначению и структуре.