Программирование драйверов Windows

в работе системы, разработчики NT


Для достижения устойчивости в работе системы, разработчики NT выбрали для построения ядра так называемую 'архитектуру клиент-сервер'. В данном случае, пользовательское приложение и является клиентом служб операционной системы.

Пользовательское приложение функционирует в специальном режиме (относительно аппаратного обеспечения), называемом 'user mode' — пользовательский режим. В пределах этого режима, код приложения ограничен выполнением "безвредных" инструкций. Например, через реализацию "таинственного" маппинга (mapping, отображение) виртуальной памяти (страничное представление виртуальной памяти) пользовательский код лишается возможности доступа к виртуальной памяти, предоставленной другим приложениям (за исключением случаев обоюдного согласия, что реализуется специально предназначенными на тот случай методами). Инструкции аппаратного ввода/вывода также не могут быть выполнены кодом пользовательского режима. Целый класс инструкций центрального процессора (называемых привилегированными) запрещен в Windows NT для выполнения кодом пользовательского режима, как, например, команды процессора IN, OUT (результат таких попыток запечатлен на рисунке 1.1). Если вдруг приложению потребуется выполнить что-нибудь из числа таких запрещенных для нее действий, оно должно запросить соответствующую службу операционной системы.

Код самой операционной системы выполняется в так называемом 'kernel mode' — режиме ядра (режиме уровня ядра). Код режима ядра вправе выполнить любую процессорную инструкцию, не исключая инструкций ввода/вывода. Память, принадлежащая любому приложению, может быть доступна коду режима ядра, конечно, если страничная память приложения в данный момент не сброшена на жесткий диск.

Современные процессоры реализуют несколько форм привилегированного режима в отличие от непривилегированного. Код режима ядра выполняется в привилегированном контексте, в то время как пользовательский код выполняется в непривилегированной среде. Так как разные процессоры (и платформы на их основе) реализуют привилегированные режимы по-разному, то, для обеспечения переносимости, разработчики операционной системы ввели особые абстрактные элементы программирования, которые позволяют разграничивать пользовательский режим и режим ядра. Код операционной системы использует их для переключения привилегированного/непривилегированного контекста, следовательно, при перенесении операционной системы только лишь код этих дополнительных элементов необходимо "портировать" (переписывать конкретно под специфику новой аппаратной платформы). На платформе Intel пользовательский режим реализуется из набора инструкций Ring 3 (Кольца 3), в то время как режим ядра реализован с использованием Ring 0 (Кольца 0).

Драйверы уровня ядра (режима ядра) работают в привилегированном контексте. Соответственно, плохо написанный драйверный код может оказаться вредоносным для операционной системы. Разработчик должен с особым вниманием относиться к создаваемому коду, чтобы не обрушить все здание операционной системы. Фирма Microsoft пытается решить проблему надежности драйверов, поставляемых в составе дистрибутива Windows, через механизм тестирования и подписания драйверов.


Содержание раздела