Новости

30.08.2017

Российская компания Positive Technologies анонсировала ...

  • Все новости (36)
  • Разделы новостей

    Публикации

    Майнеру на заметку

    Утилиты

    Реклама

    Обзоры компьютерных гаджетов, которые должны быть всегда под рукой

        Яндекс.Метрика
    Главная » Статьи » Проблемы текстового режима UEFI

    Проблемы текстового режима UEFI

    В официальной спецификации UEFI 2.5 утверждается, что Simple Text Output и Graphics Output – независимые протоколы. В процессе отладки UEFI-приложений можно встретить ситуацию, когда после переключения в один из графических режимов консольный вывод становится нерабочим. Почему работоспособность процедур вывода текста Simple Text Output Protocol остается под вопросом после установки произвольного видео режима с использованием Graphics Output Protocol?

    За двумя взаимно независимыми абстракциями: GOP и STO, затерялся фундаментальный факт: оба протокола работают в графической среде с одним и тем же физическим ресурсом – видео контроллером. Чисто теоретически существует возможность их совместного использования независимо от текущего видео режима. В отличие от рудиментов CGA/EGA определяющих подходы к визуализации объектов в BIOS/DOS, программная среда UEFI Shell реализована в графическом режиме. В итоге – необходимость формировать («рисовать») символы программно существует не только после включения альтернативного режима, но также и в графической среде, сформированной процедурами инициализации.

    Реализация графического экрана

    Поскольку визуализируемая текстовая строка является результатом графического вывода, то после изменения видеорежима, а, значит, и изменения формата хранения данных в видеопамяти (если не предпринять соответствующих шагов) произойдет ее искажение. Например, в режиме 800x600 адрес пикселя, находящегося на одну позицию ниже равен [текущий адрес] + 800*N, где N=байт на пиксель. Переключившись в режим 1024x768, адрес пикселя на 1 позицию ниже уже равен [текущий адрес] + 1024*N, а пиксель с адресом [текущий адрес] + 800*N находится на 800 пикселей правее в той же 1024-пиксельной строке.

    Целостность графической картинки, даже если она сформирована средствами Simple Text Output, можно сохранить, если firmware озаботится тем, чтобы прочитать содержимое видеопамяти, переформатировать его и сохранить обратно. Таким образом, в UEFI (как и в Legacy BIOS INT10h, а также VESA BIOS Extension) мы не можем ожидать, что построения, выполненные в видеопамяти, сохранят адекватный вид после переключения видео режима: видеопамять нужно очищать и рисовать в новом режиме все заново.

    Технология верификации

    Менее логично другое: в некоторых режимах, отличных от режима по умолчанию, Simple Text Output Protocol просто не работает. Предполагаемая причина – упрощение процедур firmware, в которых отсутствуют необходимые фонты и(или) процедуры пересчета координат знакоместа в адрес видео памяти для всех поддерживаемых графических режимов. Исходя из этого можно сделать несомненный вывод о том, что поддержка Simple Text Output Protocol не гарантируется для каждого видеорежима. Документальное подтверждение этому следует, например, из наличия функции EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode(), на вход которой необходимо передать номер видеорежима. Результатом ее работы будет статус, отражающий возможность вывода текста в данном режиме.

    Расшифровка статуса функции OutputString
    Рис 1. Расшифровка статуса функции OutputString

    Расшифровка статуса для функции QueryMode()
    Рис 2. Расшифровка статуса для функции QueryMode

    Если мы, пользуясь функциями протокола GOP (у которого номенклатура режимов более широкая), включим такой видеорежим, в котором не поддерживается Simple Text Output Protocol, то консоль действительно «испортится». Причина нам уже известна – в каждом видеорежиме своя организация видео памяти, количество байт на строку, базовый адрес буфера, размер фонта. Поэтому поддержку знакогенератора для всех возможных графических режимов разработчики Firmware посчитали излишней.

    Описание процедуры QueryMode() для Simple Text Output Protocol

    Внимательный читатель здесь может возразить, ведь единая нумерация для текстовых и графических режимов не является документированным фактом. Поэтому продолжим наш анализ.

    Читаем спецификацию между строк

    В разделе 11.4 UEFI Specification 2.5 (Simple Text Output Protocol), указано, что одним из элементов таблицы указателей на функции и структуры протокола, является указатель на структуру SIMPLE_TEXT_OUTPUT_MODE. Сама структура описана в документе ниже, в ней есть поле с именем MODE, это текущий видео режим. Комментарий к нему следующий: If the output device is not in a valid text mode at the time of the EFI_BOOT_SERVICES.HandleProtocol() call, the device is to indicate that its CurrentMode is -1. Таким образом, если видеоадаптер переведен в режим, для которого вывод текста не поддерживается, возвращается текущий номер режима равный -1 (FFFFFFFFh), индицирующий ошибку.

    Другое документальное подтверждение того, что вывод текста поддерживается не во всех режимах видео адаптера, это статус после выполнения функции OutputString() текстового протокола. Одна из возможных ошибок обозначена как EFI_UNSUPPORTED и в данном контексте описана так: The output device mode is not currently in a defined text mode, что означает, что режим видео подсистемы не допускает текстовый вывод.

    Очевидно, из указанной расшифровки кода ошибки, следует: спецификация допускает возможность нахождения адаптера в таком состоянии, в котором невозможен вывод текста: устанавливая графический режим, можно «испортить консоль».

    Как решить проблему?

    Теоретически, если вывод текста в данном графическом режиме поддерживается, необходимо вызвать функцию EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset(), для того, чтобы Simple Text Output Protocol адаптировался к новому формату видеопамяти. Вместе с тем, в силу разнообразия реализаций UEFI Firmware такое решение нельзя назвать стабильным. На практике, после включения видео режима, отличного от дефолтного, лучше использовать вывод текста с помощью собственных графических процедур. Кроме того, применяя маскированную запись SSE/MMX-инструкциями, вывод текстовых строк можно ускорить, по сравнению процедурами, реализованными в UEFI.



    24.09.2017