1.Внутреннее устройство Windows (гл. 1-4)
Шрифт:
Другая важная задача ядра — абстрагирование или изоляция исполнительной системы и драйверов устройств от различий между аппаратными архитектурами, поддерживаемыми Windows (т. е. различий в обработке прерываний, диспетчеризации исключений и синхронизации между несколькими процессорами).
Архитектура ядра нацелена на максимальное обобщение кода — даже в случае аппаратно-зависимых функций. Ядро поддерживает набор семантически идентичных и переносимых между архитектурами интерфейсов. Большая часть кода, реализующего переносимые интерфейсы, также идентична для разных архитектур.
Ho
B ядре также содержится небольшая порция кода с х86-специфичными интерфейсами, необходимыми для поддержки старых программ MS-DOS. Эти интерфейсы не являются переносимыми в том смысле, что их нельзя вызывать на машине с другой архитектурой, где они попросту отсутствуют. Этот х86-специфичный код, например, поддерживает манипуляции с GDT (global descriptor tables) и LDT (local descriptor tables) — аппаратными средствами x86.
Другим примером архитектурно-специфичного кода ядра может служить интерфейс, предоставляющий поддержку буфера трансляции и процессорного кэша. Эта поддержка требует разного кода на разных архитектурах, поскольку кэш в них реализуется различным образом.
Еще один пример — переключение контекста. Хотя на высоком уровне для выбора потоков и переключения контекста применяется один и тот же алгоритм (сохраняется контекст предыдущего потока, загружается контекст нового и запускается новый поток), существуют архитектурные различия между его реализациями для разных процессоров. Поскольку контекст описывается состоянием процессора (его регистров и т. д.), сохраняемая и загружаемая информация зависит от архитектуры.
Как отмечалось в начале этой главы, одной из важнейших особенностей архитектуры Windows является переносимость между различными аппаратными платформами. Ключевой компонент, обеспечивающий такую переносимость, — уровень абстрагирования от оборудования (hardware abstraction layer, HAL). HAL — это загружаемый модуль режима ядра (Hal.dll), предоставляющий низкоуровневый интерфейс с аппаратной платформой, на которой выполняется Windows. Он скрывает от операционной системы специфику конкретной аппаратной платформы, в том числе ее интерфейсов ввода-вывода, контроллеров прерываний и механизмов взаимодействия между процессорами, т. е. все функции, зависимые от архитектуры и от конкретной машины.
Когда внутренним компонентам Windows и драйверам устройств нужна платформенно-зависимая информация, они обращаются не к самому оборудованию, а к подпрограммам HAL, что и обеспечивает переносимость этой операционной системы. По этой причине подпрограммы HAL документированы в Windows DDK, где вы найдете более подробные сведения о HAL и о его использовании драйверами.
Хотя в Windows имеется несколько модулей HAL (см. таблицу 2–6), при установке на жесткий диск компьютера копируется только один из них — Hal.dll. (B других операционных системах, например в VMS, нужный модуль HAL выбирается при загрузке системы.) Поскольку для поддержки разных процессоров требуются разные модули HAL, системный диск от одной х86-установки скорее всего не подойдет для загрузки системы с другим процессором.
Таблица 2–6. Список модулей HAL для x86 в \ Windows\Driver\Cache\i386\Driver.cab
ПРИМЕЧАНИЕ B базовой системе Windows Server 2003 нет HAL, специфических для конкретных вендоров.
ЭКСПЕРИМЕНТ: просмотр базовых HAL, включенных в Windows
Для просмотра HAL, включенных в Windows, откройте файл Driver.cab в соответствующем подкаталоге, специфичном для конкретной архитектуры, в каталоге \Windows\Driver Cache. (Например, для систем x86 имя этого файла — \Windows\Driver Cache\i386\Driver.cab.) Прокрутите список до файлов, начинающихся с «Hal», и вы увидите файлы, перечисленные в таблице 2–6.
ЭКСПЕРИМЕНТ: определяем используемый модуль HAL
Определить, какой модуль HAL используется на вашей машине, можно двумя способами.
1. Откройте файл \Windows\Repair\Setup.log, найдите строку с Haldll. Имя файла, стоящее в этой строке после знака равенства, соответствует имени модуля HAL, извлеченного из Driver.cab с дистрибутивного носителя.
2. Откройте Device Manager (Диспетчер устройств): щелкните правой кнопкой мыши значок My Computer (Мой компьютер) на рабочем столе, выберите команду Properties (Свойства), откройте вкладку Hardware (Оборудование) и щелкните кнопку Device Manager (Диспетчер устройств). Проверьте имя «драйвера» для устройства Computer (Компьютер).
ЭКСПЕРИМЕНТ: просмотр зависимостей NTOSKRNL и HAL
Вы можете просмотреть взаимосвязи образов ядра и HAL, изучив их таблицы импорта и экспорта с помощью утилиты Dependency Walker (Depends.exe), которая содержится в Windows Support Tools и Platform SDK. Для исследования файла в Dependency Walker откройте его командой Open из меню File.
Вот пример вывода этой утилиты при просмотре зависимостей в Ntoskrnl.
Обратите внимание, что Ntoskrnl связан с HAL, который в свою очередь связан с Ntoskrnl (оба используют функции друг у друга). Ntoskrnl также связан с Bootvid.dll, видеодрайвером, используемым для вывода заставки при запуске Windows. B Windows XP и выше вы увидите в списке дополнительную DLL, Kdcom.dll. Она содержит код инфраструктуры отладчика ядра, который раньше был частью Ntoskrnl.exe.
Подробное описание информации, выводимой Dependency Walker, см. в справочном файле этой утилиты (Depends.hlp).
Драйверы устройств подробно описываются в главе 9, а здесь мы даем краткий обзор их типов и поясняем, как перечислить установленные драйверы, загруженные в системе.
Драйверы устройств являются загружаемыми модулями режима ядра (как правило, это файлы с расширением. sys); они образуют интерфейс между диспетчером ввода-вывода и соответствующим оборудованием. Эти драйверы выполняются в режиме ядра в одном из трех контекстов: