Вы здесь
UEFI вместо DOS: плюсы и минусы

Новые возможности, которые появились благодаря UEFI, вызывают в памяти аналогии с устаревшей сегодня операционной системой DOS. Это и понятно: в ходе обслуживания и исследования персональных платформ возникает ряд нетривиальных задач, для которых простота и компактность — оптимальные свойства. Использование файловой системы FAT32 в UEFI только усиливает сходство.
Одна из причин появления UEFI как принципиально нового стандарта взаимодействия ОС и firmware как раз и состоит в необходимости создания современного аналога DOS-подобной среды. Таким аналогом стала оболочка UEFI Shell, главные преимущества которой — возможность размещения в ROM платформы и функционирования без дисковых устройств. Время запуска, исчисляемое единицами секунд, и поддержка 64-битного режима процессора делают ее удобной средой для запуска информационно-диагностических утилит и обновления BIOS.
Как принять решение?
В сфере интересов тестовой лаборатории «Компостера» важное место занимает низкоуровневое исследование платформ и задачи, требующие беспрепятственного доступа к привилегированным системным ресурсам. Именно поэтому мы часто запускаем небольшие примеры под DOS. Что даст нам переход на использование UEFI для тех же целей? Удастся ли совместить простоту DOS-среды и преимущества современных протоколов взаимодействия с платформой? Попробуем ответить на эти вопросы, сравнив DOS и UEFI по ряду объективных критериев. Для определенности и компактности изложения, будем рассматривать только 64-битную реализацию UEFI. Также отметим, что рассмотрение технологий безопасной загрузки или Secure Boot, выходит за рамки данного материала.
Компактность — преимущество UEFI
Набор файлов DOS, необходимых для загрузки, в зависимости от версии ОС и конфигурации, занимает около 300-500 килобайт. Типовой размер UEFI Shell 0.9-2.5 Мбайт. Но вспомним, что UEFI Shell может храниться в ROM платформы и не занимать дискового пространства. Применив небольшую хитрость и поместив наше приложение на загрузочном диске под зарезервированным именем \EFI\BOOT\BOOTX64.EFI, мы сможем запустить его без использования UEFI Shell. Но даже в этом случае, набор сервисов, предоставляемых firmware платформы нашему приложению, включает поддержку файловых операций и многие другие функции, отсутствовавшие в Legacy BIOS.
Адресация памяти и системных ресурсов
Работая под DOS, программа запускается в реальном режиме процессора. Для адресации памяти выше 1MB необходимо переключиться в 32-битный защищенный режим. Доступ выше 4GB потребует 64-битного режима или 32-битного с поддержкой PAE (Physical Address Extension). И конечно, необходимо разрешить адресную линию A20. В случае UEFI все это сделано до запуска приложения. В нашем распоряжении процессор, уже работающий в 64-битном режиме, с включенной трансляцией страниц и опцией PAE.
Таблицы страниц, подготовленные UEFI firmware, обеспечивают прозрачную трансляцию, при которой физический адрес численно равен линейному. Напомним, использовать 64-битный режим без включения трансляции страниц нельзя. Итак, в распоряжении нашей программы все адресное пространство, но переключение в защищенный режим произошло до ее запуска, поэтому она не является супервизором.
Снижает ли это наши возможности по доступу к ресурсам платформы? Ответ – не снижает, так как передача управления UEFI-приложению происходит без понижения уровня привилегий. При необходимости, мы можем даже переключиться на использование собственных таблиц дескрипторов сегментов и страниц, но, как правило, это не требуется, ведь контекст, созданный UEFI firmware для нашего приложения, разрешает доступ ко всему адресному пространству.
Использование сервисных процедур
Для ОС и программ, работающих в сеансе ОС, основной формой взаимодействия с UEFI firmware является вызов сервисных процедур, указатели на которые находятся в системных таблицах UEFI. При этом можно выделить два вида процедур:
Процедуры
Функционально-ориентированные процедуры, назначение которых фиксировано и в этом есть их некоторое сходство с процедурами Legacy BIOS. Обычно, они ассоциированы с конкретным аппаратным ресурсом платформы. Например, функция GetTime(), возвращающая системное время и дату, связана с системным таймером и часами реального времени.
UEFI-протоколы
Рассмотрим эту группу подробнее, так как именно здесь новизна и гибкость UEFI проявляются наиболее очевидно. Подход базируется на существовании двух списков: список устройств, в котором каждому устройству присвоен уникальный номер (handle) и список протоколов. Каждый протокол имеет свой идентификатор (GUID). При этом UEFI firmware не накладывает каких-либо ограничений на поддержку заданного протокола заданным устройством. Теоретически, можно с минимальными затратами реализовать любую программную модель, какой бы странной и экзотической она не казалась, например управление контроллером памяти из драйвера мыши. В этой шутке есть доля правды: вспомним, что в свое время перенос контроллера памяти из системной логики в процессор потребовал существенных изменений в структуре Legacy BIOS.
Функция LocateHandle() возвращает список устройств, поддерживающих заданный протокол. Функция OpenProtocol() возвращает таблицу указателей точек входа в сервисные процедуры, обеспечивающие поддержку заданного протокола заданным устройством.
Детектируем протоколы
Построение диалога с пользователем напрямую связано с технологией визуализации, основанной на использовании графических UEFI-протоколов. Современным трендом является применение GOP – Graphics Output Protocol. Ставку на его использование сделала компания Microsoft в операционной системе Windows 8.
Малоизвестный предшественник GOP – протокол UGADraw. Его название расшифровывается как Universal Graphic Adapter.
Хорошо бы знать, какими возможностями в плане вывода графики на экран обладает та или иная персональная платформа. Давайте исследуем этот вопрос на плате ASUS Z87-K, оснащенной системной логикой Intel Z87 для процессоров Socket 1150. На плате установлен процессор Intel Xeon CPU E3-1270 v3 с частотой 3.50GHz. Тестируемая платформа оснащена Aptio IV — UEFI BIOS производства American Megatrends.
Протоколы GOP и UGADraw задекларированы в списке, который можно получить, если выполнить команду GUID в UEFI Shell. Выполняя ее на данной платформе мы можем убедиться в этом:
GraphicsOutput | 9042A9DE-23DC-4A38-96FB-7ADED080516A |
UgaDraw | 982C298B-F4FA-41CB-B838-77AA688FB839 |
Декларация – это замечательно! Можно ли воспользоваться благами GOP и UGADraw? Ответ на этот вопрос должны дать две простенькие тестовые задачи, каждой из которых поручен поиск и детализация возможностей соответствующих протоколов.
Из среды UEFI Shell запускаем ScanUGA_LocateHandle.efi и смотрим, что в результате:
Analysing GUID = 982C298B-F4FA-41CB-B8-38-77-AA-68-8F-B8-39
Aborted with error.
Operation = Locate handle
Status = EFI_NOT_FOUND
А теперь очередь ScanGOP_LocateHandle.efi дать ответ на поставленный вопрос:
Analysing GUID = 9042A9DE-23DC-4A38-96-FB-7A-DE-D0-80-51-6A
Total handles supported = 1
Handles buffer dump:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Index=0
Aborted with error.
Operation = Handle protocol
Status = EFI_INVALID_PARAMETER
По результатам работы наших тестовых примеров мы вынуждены констатировать, что ни протокол Graphics Output, ни UGADraw нам недоступны. Firmware, при попытке обращения к ним, направляет наши запросы на заглушку. В результате список устройств, поддерживающих данный протокол пуст (элементы handles нулевые), несмотря на обещания, декларированные ранее.
Резюме
Как видим, компактность DOS и 64-битный режим процессора – вещи легко совместимые. Безусловно, ложка дегтя – отсутствие в современных реализациях UEFI поддержки тех протоколов, которые могли бы упростить программирование приложений. А очевидная бочка меда – firmware перестало быть вещью в себе.
В наших исследованиях мы использовали UEFI-функцию Locate Handle (получить список устройств, поддерживающих данный протокол). Может быть, недоступность информации о графических протоколах является локальной проблемой этой функции? Об этом в следующих публикациях…