Таблица 12.8. Заголовок модуля дополнительного ПЗУ
Смещение Длина Назначение 0 2 Сигнатура (признак начала модуля): байт 0=55h, байт 1=AAh 2 1 Длина, указанная в блоках по 512 байт 3 3 Точка входа процедуры инициализации, заканчивающейся дальним возвратом Ret Far (вызывается инструкцией Far Call во время POST). Обычно здесь располагается трехбайтная инструкция JMP, указывающая на начало процедуры 6-17h Резерв 18h 2 Указатель на структуру данных PCI (только для карт PCI), см. ниже п. 12.9.1 1Ah 2 Указатель на структуру расширенного заголовка карт ISA PnP, см. ниже п. 12.9.2
В традиционном заголовке присутствовали только первые 3 поля, указатели на структуры PCI и ISA PnP ввели позже. Корректным считается модуль, начинающийся с признака AA55h (значения слова с учетом порядка байтов) и нулевой суммой (по модулю 256) всех байтов в объявленной области (реальная длина модуля может превышать объявленную, но байт контрольной суммы, естественно, должен входить в объявленную область).
В случае обнаружения корректного модуля POST дальним вызовом (Call Far) вызывает процедуру инициализации модуля, начинающуюся с 3-го адреса заголовка модуля. Ответственность за ее корректность полностью ложится на разработчика. Процедура может переопределять векторы прерываний, обслуживаемых BIOS. Переопределив на себя Bootstrap (Int 19h), можно получить управление при загрузке, что и используется, например, для удаленной загрузки компьютеров через локальную сеть (Remote Boot Reset). Если стандартное продолжение процедуры загрузки не требуется, а дополнительный модуль представляет собой(например, управляющую программу для какого-либо оборудования, вместо процедуры инициализации в ПЗУ может находиться и основная программа, не возвращающая управление системной последовательности POST.
Процедура инициализации и программная поддержка устройства в ПЗУ должны быть написаны таким образом, чтобы им были безразличны абсолютные адреса, по которым они размещаются в пространстве памяти. На картах расширения, как правило, имеются аппаратные средства изменения базового адреса, а иногда и размера ПЗУ (джамперы или программно-управляемые переключатели). Это позволяет бесконфликтно разместить модули ПЗУ нескольких установленных карт.
По сравнению с традиционным способом использования ПЗУ, когда оно, будучи разрешенным, постоянно присутствует в области памяти, имеется более рациональный способ подключения расширений ROM BIOS, основанный на модели DDIM (Device Driver Initialization Model — модель инициализации драйвера устройств). POST определяет наличие ПЗУ по найденному заголовку и копирует его содержимое (по объявленной длине) в свободное пространство верхней памяти (ОЗУ), оставляя разрешенной запись в эту область. Далее в этой копии (в ОЗУ) вызывается процедура инициализации (по адресу 3). Эта процедура, написанная в соответствии с моделью DDIM, должна определить, каким образом ее запустили: традиционным (в ПЗУ) или в соответствии с DDIM (в ОЗУ). Определить это она может просто — попыткой модификации области ее «тела», которая в ПЗУ, естественно, не приведет к изменению содержимого памяти. Обнаружив режим DDIM (память модифицируема), процедура выполняет все необходимые действия по инициализации. Далее она определяет, какую часть копии (начиная от начала заголовка) требуется оставить в памяти на время загрузки и регулярной работы системы, отсекая не нужное в дальнейшем тело процедуры инициализации. Попутно она может в оставляемом модуле установить какие-либо параметры, требуемые для работы драйвера устройства. Наконец, она модифицирует поле длины в заголовке и контрольную сумму так, чтобы фрагмент модуля оставался корректным, и дальним возвратом отдает управление тесту POST. Теперь POST снова анализирует заголовок (но уже копии в ОЗУ) и запрещает запись в область ОЗУ (страницу с размером, кратным 4 К), которую «попросила» оставить процедура инициализации. Далее POST, по возможности, запрещает работу (отображение в область UMA) исходного модуля ПЗУ и продолжает свой путь к вызову процедуры начальной загрузки. Основное преимущество данного метода — возможность более рационального использования памяти в UMA (обычные ПЗУ «висят» в ней в полном объеме, невзирая на реальные потребности). Второе преимущество — возможность сохранения параметров, вычисляемых процедурой инициализации (она может задействовать параметры, полученные в процессе выполнения теста POST), в «замораживаемой» области памяти. Кроме того, как правило, медленные микросхемы ПЗУ на все время исполнения подменяются быстрым системным ОЗУ (не используя впрямую механизма теневой памяти). Процедура инициализации ПЗУ карт ISA с моделью DDIM должна проверять окружение, в котором она работает (см. выше); безусловная работа DDIM гарантируется только для карт PCI.
Для более эффективной работы DDIM желательно использовать не только стандартную, но и расширенную память (за пределами первого мегабайта), в то время как POST работает в реальном режиме процессора. Решить эту проблему помогает режим «Big Real Mode», который поддерживают все 32-разрядные процессоры (см. п. 12.3.1). Специально для предоставления доступа ко всей памяти процедурами инициализации фирмы Phoenics и Intel разработали спецификацию PMM (POST Memory Manager Specification), версия 1.01 была опубликована в конце 1997 г. Эта спецификация определяет несколько дополнительных сервисов BIOS, позволяющих выделять, находить и освобождать блоки в любой, в том числе и расширенной памяти. Клиенты этого сервиса запрашивают блок памяти требуемого размера, a BIOS возвращает физический 32-разрядный адрес начала выделяемого блока (если она способна его выделить). Клиент помечает свой блок 32-битным индексом (handle), по которому его в дальнейшем можно найти функцией поиска. Анонимный блок (индекс FFFFFFFFh) поиску не поддается. Этими сервисами можно пользоваться только до начала процедуры начальной загрузки (Int 19h), работу с вентилем Gate A20 они берут на себя. Перед начальной загрузкой BIOS освобождает и обнуляет все блоки расширенной памяти, занятые с помощью этих сервисов. Сервисами PMM могут пользоваться процедуры инициализации карт расширения, а также процедуры BCV, описанные в заголовке ПЗУ карт PnP (см. ниже). Процедуры, на которые указывает BEV, ими пользоваться не могут, поскольку вызываются после входа в Int 19h. Наличие сервисов PMM определяется по контрольной структуре, начинающейся со строки-сигнатуры $PMM и расположенной на границе параграфа в области E0000-FFFF0h. Программный интерфейс можно найти в вышеуказанном документе, который доступен на сайте http://www.phoenix.com/techs.
12.9.1. ROM BIOS карт ISA PnP
Для поддержки технологии PnP и расширения возможностей управления начальной загрузкой в спецификации PnP BIOS ввели дополнительный указатель на структуру расширенного заголовка (Expansion Header Structure). Расширенный заголовок имеет формат, приведенный в табл. 12.9. В одном ПЗУ может находиться несколько расширенных заголовков (это требуется для многофункциональных карт расширения), связанных в цепочку. В каждом расширенном заголовке может указываться смещение следующего заголовка относительно начала стандартного заголовка. Наличие и действительность расширенного заголовка проверяется по его сигнатуре и контрольной сумме. Сумма всех байтов расширенного заголовка, включая байт контрольной суммы, должна быть нулевой.
Таблица 12.9. Расширенный заголовок ROM BIOS карт ISA PnP
Смещение Длина Назначение 0h 4 байта Сигнатура, строка $PnP (символы ASCII) 04h байт Версия структуры (01h) 05h байт Длина (в параграфах по 16 байт) 06h слово Смещение следующего заголовка (0000h, если нет больше) 08h байт Резерв(0) 09h байт Контрольная сумма 0Ah двойное слово Идентификатор устройства PnP 0Eh слово Указатель на строку идентификатора производителя (0, если нет) 10h слово Указатель на строку названия продукта (0, если нет) 12h 3 байт Код типа устройства 15h байт Индикаторы устройства 16h слово Вектор подключения BCV (Boot Connection Vector) — 0, если нет 18h слово Вектор отключения (Disconnect Vector) — 0, если нет 1Ah слово Точка входа для загрузки BEV (Bootstrap Entry Point) — 0, если нет 1Ch слово Резерв (0) 1Eh слово Вектор получения информации о статических ресурсах (Static Resource Information Vector) — Real/Protected mode (0 если нет)
Расширенный заголовок позволяет определить идентификатор устройства PnP, его название и код производителя. Код типа состоит из байта общего типа, байта подтипа и байта идентификатора программного интерфейса, по которым система может узнать знакомые устройства.