Как сделать скриншот в UEFI?

Как сделать скриншот в UEFI?

Слухи про универсальность UEFI сильно преувеличены! В этом может убедиться каж­дый, кто захочет сделать скриншот Setup-меню, зайдя в настройки современного BIOS. Причин для сохранения образа экрана тысячи: от элементарного любопытства и по­пыт­ки запомнить начальные установки системы до подготовки графических объектов для интернет-публикаций.

Как сделать скриншот в UEFI?

Итак, исходная позиция такова, что в общем случае снимок экрана не обеспечивается функциональностью интерфейса. В некоторых случаях, которые правильно считать частными, PrintScreen выполняется по клавише F12, но это, по большей части, заслуга кастомизаторов. Как быть разработчика программного обеспечения под UEFI, которые и могут при благоприятном стечении обстоятельств оказаться этими самыми ка­сто­ми­за­то­ра­ми?

Вариант 1. Низкоуровневое программирование

Задача сохранить содержимое экрана в bitmap-файл успешно решена и на языке ассемблера. Рассмотрим процедуру Save_Screen_to_BMP, исходный код которой доступен в файле LIB_SBMP.INC. Ее вызов выполняется из тела утилиты UEFIMark и не требует подготовки специальных параметров. Сама же процедура формирования скриншота заботится о достоверности контекста, сохраняя и восстанавливая содержимое регистров центрального процессора.

Для кодирования цветов экрана используется 24 бита, по 8 бит на каждый цвет: Red, Green, Blue. Полученный файл сохраняется на носителе с исполняемым модулем. Процедура самостоятельно заботится о генерировании имен BMP-файлов в виде PICTxxxx.BMP, где цифровая часть xxxx формируется с автоинкрементом.

К особенностям предлагаемого примера реализации относится вывод в диагностической порт контрольных точек вызова процедуры Save_Screen_to_BMP, и ее завершения. По умолчанию вывод осуществляется в 80-й порт персональной платформы, но этот выбор может быть кастомизирован по желанию программиста. Начало формирования скриншота отмечается появлением кода 0xF4, а завершение — кода 0xF7 в диагностическом порту. Для трассировки и отладки программного обеспечения рекомендуется использовать диагностическую POST-карту IC80 v5.0.

Вариант 2. Высокоуровневое программирование

В некоторых случаях полезной может быть рекомендация Курта Цзяо (Kurt Qiao), изложенная им в своем блоге:

  • Сохраняем данные из видеопамяти в рабочий массив, где они их можно обрабатывать как растровую информацию;
  • Создаем заголовок и корректируем информацию согласно спецификации на bit-map изображения для формирования bmp-файла.

Для 24-битного изображения, например, заголовок BMP-файла будет состоять из 54 байт (включая 14 байт собственно заголовка и 40 байт описания растровой информации), Google формат 24bit файл BMP на себя, чтобы получить больше информации.

Для осуществления задуманного можно воспользоваться EFI_GRAPHICS_OUTPUT_PROTOCOL, используя метод blt() с параметром BltOperation равным 'EfiBltVideoToBltBuffer'.

Типичное решение в данном случае будет выгядеть так:

typedef
EFI_STATUS
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta OPTIONAL
);

Теги