В последней части цикла я постараюсь рассказать о новшествах стандарта UEFI 2.5, первые реализации которого должны появиться примерно через полгода на новых платах с процессорами Intel Skylake и AMD R-Series. В первой и второй частях речь шла о более низкоуровневых (и потому менее интересных неспециалистам) стандартах PI 1.4 и ACPI 6.0, здесь же поговорим об изменениях, напрямую влияющих на работу ОС и возможности загрузки по сети. Если вы хотите узнать, что нового в UEFI 2.5, почему PXE уходит в прошлое и зачем UEFI поддержка WiFi и Bluetooth — искренне прошу под кат.

В отличие от своих низкоуровневых собратьев, стандарт UEFI развивается в очень высоком темпе, и с момента выпуска предыдущей версии 2.4 Errata C не успело пройти и полугода. Изменений масса, поэтому я постараюсь отфильтровать мелкие и не слишком важные, вроде исправлений опечаток и правок некоторых частей текста, допускавшего двоякое толкование. Если вас это не устраивает и вам нужны все изменения до последней запятой — оригинал документа к вашим услугам.

Как и в предыдущей части, я разделил изменения на группы, чтобы не описывать каждый новый протокол по нескольку раз. Поехали!

ESRT и новый способ обновления прошивки

В UEFI 2.5 вводится новая необязательная таблица ESRT, при помощи которой UEFI может сообщить операционной системе типы и версии имеющихся компонентов прошивки, а также статус их последнего обновления.
С использованием этой таблицы ОС может инициировать обновление не только всей прошивки целиком (как это было практически на всех произведенных материнских платах с UEFI), но и конкретных независимых друг от друга компонентов, таких как VBIOS/GOP-драйвер, Raid-драйвер, UNDI-драйвер и т.п. Для инициации обновления будет использован стандартный механизм UEFI Capsule Update, а само обновление будет произведено при следующей загрузке. Файлы с обновлениями компонентов защищены от модификации ЭЦП на основе RSA2048/SHA256 и могут быть выпущены только обладателями закрытого ключа, поэтому прошивать модифицированные образы (и не важно, выполнена ли модификация злобным вирусом или опытным пользователем) с помощью Capsule Update не выйдет, так что программатор по прежнему наше всё.
ESRT также будет использоваться для доставки обновлений через подсистему обновления компонентов ОС (т.е. Windows Update для Win10 и fwupd для Linux).

SysPrep, OS Recovery и Platform Recovery

Изначально в фазе BDS можно было запустить только один тип EFI-приложений — bootloader, он же EFI-загрузчик. Порядок загрузки задается в переменной BootOrder, а путь и параметры загрузчика сохраняются в переменных Boot####, начиная с Boot0000 и заканчивая BootFFFF. В UEFI 2.3 был добавлен еще один тип — DXE-драйвер, который будет запущен диспетчером BDS до запуска любых загрузчиков из Boot####, и вместе с типом добавились соответствующие переменные DriverOrder и Driver####. В версии 2.4 добавили возможность привязать к EFI-загрузчику из Boot#### горячую клавишу, которая хранится в переменной Key####. В текущей версии и этого оказалось мало, и были добавлены сразу 3 новых типа приложений: SysPrep, OsRecovery и PlatformRecovery.

SysPrep
Иногда получалось, что запускать какой-либо код из Driver#### слишком рано (к примеру, нужна консоль или полностью инициализированное железо), а из Boot#### — слишком поздно (BS-переменные уже недоступны, приходится шаманить с BootOrder'ом, чтобы гарантированно запускаться первым, и есть риск сломать загрузку совсем). Чтобы решить эту проблему, предложен третий тип приложений — System Preparation Application. Такие приложения запускаются после драйверов, но до загрузчиков и имеют доступ к консоли и графическому режиму. К приложениям такого типа могут относиться шифровальщики дисков, эмуляторы IPMI, системы адаптированного UI для людей с ограниченными возможностями и т.п. На SysPrep-приложения распространяются те же ограничения, что и на загрузчики, т.е. для использования их вместе с SecureBoot они должны быть подписаны подходящей ЭЦП.
Возможно выглядит весьма полезной, осталось дождаться реализации и попробовать в деле.

OS Recovery
Если ни один из загрузчиков не смог запустить ОС, то ОС может инициировать восстановление загрузчика, для чего используются переменные OsRecoveryOrder и OsRecovery####. Эта возможность доступна только системам с поддержкой SecureBoot и для её использования SecureBoot должен быть активирован. При ее использовании приложения из SysPrep и PlatfromRecovery загружаться не будут.

Platform Recovery
Если ни один из загрузчиков не смог запустить ОС, то UEFI тоже может инициировать восстановление загрузчика, используя данные из PlatfromRecoveryOrder и PlatfromRecovery####. Обе эти переменные недоступны для модификации из ОС, и будут использованы только в случае, когда OS Recovery недоступен. Одна из переменных PlatfromRecovery#### может быть помечена флагом Default Boot Behavior, т.е. именно указанное в ней приложение будет запущено в случае, если ничего другого запустить не удалось.
Если обе вышеперечисленные возможности производители прошивок реализуют правильно, то о проблемах вроде этой можно будет наконец забыть.

Безопасность

В новом стандарте появилось несколько новых протоколов, которые предлагается использовать для контроля целостности компонентов прошивки и шифрования. Протокол EFI_PKCS7_VERIFY_PROTOCOL с двумя функциями VerufySignature и VerifyBuffer позволяет проверить целостность как самой ЭЦП (в формате PKCS7 binary DER), как и подписанных ей данных. Протокол EFI_HASH2_PROTOCOL добавляет к уже имеющейся возможности посчитать хеш-сумму от непрерывного буфера заранее заданного размера тройку функций HashInit, HashUpdate и HashFinal, которые позволяют вычислять хеш от потока данных или нескольких буферов на разных концах доступной памяти. Протокол EFI_BLOCK_IO_CRYPTO_PROTOCOL добавляет возможность чтения/записи данных с шифрованием «на лету»
Также в стандарт добавлена поддержка использования NX-бита для защиты буферов и областей с данными от исполнения.

NVM

Как и в стандарты более низкого уровня, в UEFI 2.5 добавлена поддержка NVDIMM и других типов Persistent Memory. В основном это разного рода определения в заголовочных файлах, но нашлось место и новому протоколу — EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL, используя который можно общаться с NVMe-устройствами напрямую, передавая «сырые» команды обнаруженным NVMe-устройствам и обрабатывая ответы от них.

Сетевой стек и загрузка по сети

Загрузка по HTTP
Основным новшеством стандарта UEFI 2.5 является добавление загрузки по HTTP в качестве альтернативы уже имевшейся реализации UEFI PXE с использованием протокола TFTP. Для этого понадобилось добавление поддержки протоколов DNSv4, DNSv6 и самого HTTP, поддержки IPv6 драйвером UNDI, предложены изменения для корпоративных DHCP-серверов и некоторые другие улучшения. Окончательная схема загрузки по HTTP по стандарту выглядит вот так:

Загрузчик — обычное UEFI-приложение (чтобы отличать удаленные загрузчики от локальных, в стандарте их обозвали NBP), которые для использование совместно с SecureBoot требуется подписать подходящей ЭЦП. NBP может использовать сетевой стек для загрузки следующих стадий, так что написание многостадийных загрузчиков теперь небольшая проблема, в отличие от PXE.

Поддержка WiFi и Bluetooth
Также в новом стандарте появилась поддержка VLAN, WIFI и Bluetooth как компонентов сетевого стека. Вместе с ней появился целый ворох новых протоколов вроде EFI_WIRELESS_MAC_CONNECTION_PROTOCOL или EFI_BLUETOOTH_HC_PROTOCOL, которые, при наличии драйвера для аппаратной части, позволят получить доступ к беспроводным сетям из UEFI-драйверов и приложений.
В итоге с прошивкой на базе UEFI 2.5 можно загрузить ОС ноутбука по WiFi с удаленного HTTP(S)-сервера без слишком уж сильного колдунства. Не могу сказать, что мне это очень нужно или меня это сильно радует, мой внутренний параноик немного ворчит, но если сетевая инфраструктура не нужна — ее можно отключить (и проконтролировать, что она действительно отключена) или выпилить совсем, это тоже не очень сложно.

Остальное

Осталась еще масса мелких изменений, о которых почти нечего рассказывать: поддержка устройств чтения смарт-карт, которые могут быть использованы как источники данных для различного-рода криптографии, новый протокол EFI_USBFN_IO_PROTOCOL для низкоуровневого общения с USB-устройствами, новые протокол EFI_REGULAR_EXPRESSION_PROTOCOL и HII-опкод EFI_IFR_MATCH2, который это самый RegExp-протокол будет использовать, несколько новых типов DevicePath-нод — BMC, SD-карта, RAM-диск, и так далее, всего не перечислить.

Заключение

Мое общее впечатление от новых версий UEFI-стандартов — скорее положительное. Не могу сказать, что все изменения ожидаемы или очень нужны простому пользователю, часть сможет «выстрелить» только при грамотной реализации стандарта со стороны разработчиков UEFI-платформ (т.е. AMI, Insyde, Phoenix и т.д.), а некоторые очень понравятся разработчикам (ASL 2.0 FTW!), но в конечном итоге мой вердикт — пойдет. Посмотрим, конечно, получится ли реализовать все, что гладко выглядит на бумаге, но я надеюсь, что через полгода мне не придется писать статью вроде «почему не работает UEFI HTTP Boot и как с этим бороться».
Спасибо читателю за потраченное время, и удачных вам прошивок.

Комментарии (13)


  1. Security_Lab
    11.07.2015 04:17
    +1

    CodeRush, спасибо дружище, Отличная статья!
    Продолжай писать в том же духе


    1. CodeRush Автор
      11.07.2015 08:28
      +4

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


  1. amarao
    11.07.2015 07:03

    Спасибо.

    Не могу отделаться от ощущения, что головную боль одних (создателей ОС/загрузчиков/БИОСов) вывалили на других (пользователей). По сумме вроде бы, как боли стало меньше, но пользователь озадачено чешет болезненное место. Раньше не болело, теперь стало — а умные дяди говорят, что так и должно быть.


    1. CodeRush Автор
      11.07.2015 08:08
      +2

      С моей точки зрения пользователю тоже стало чуть проще, хоть и немного непривычно, но это ощущение может быть вызвано банальной профдеформацией.
      Если не лезть под капот, то UEFI для пользователя отличается тем, что там GPT/ESP вместо MBR, загрузчик больше не 16-битный, нет 2Тб-ограничения на размер дисков и Setup выглядит более модным. Пользователи чуть продвинутее замечают, что настройки из CMOS memory теперь дополнены громандым куском NVRAM, порядок загрузки устройств теперь задать сложнее и загрузка по типу (т.е. не «вот это загрузчик», а «USB HDD») теперь не доступна по умолчанию (эта фича старых БИОСов оказалась настолько полезна клиентам, что нам пришлось реализовать ее еще в 2011 году, а в 2014 я переписывал реализацию с нуля, т.к. в UEFI 2.4 старый подход перестал работать). Плюс проблема root-of-trust более или менее решилась, а на замену древнего DOS для прямого доступа к системе пришел UEFI Shell. Стало ли все это усложнением для пользователя — возможно, я не знаю. Но усложнив в одном месте, сильно упростили в другом, и теперь не нужно править MBR, чтобы новый загрузчик на диск дописать, или устраивать ресет ОС выводом в порт клавиатуры, которого давно уже на самом деле нет, но БИОС вынужден был его эмулировать.


  1. googol
    11.07.2015 07:33

    Может кто-либо объяснить чем этот раздутый и чрезмерно усложненный стандарт разработки firmware лучше чем тот же Coreboot?


    1. CodeRush Автор
      11.07.2015 08:25
      +2

      Сложно сравнивать, это проекты разных весовых категорий. С одной стороны у нас UEFI Forum из Intel/AMD/MS/HP/Dell/etc., а с другой — небольшая группа энтузиастов и примкнувший к ним Google, использующий coreboot на Chromebook. Для UEFI есть «раздутый и чрезмерно усложненный», но открытый стандарт, документация, бесплатные инструменты для проверки на соответсвие реализации стандарту, открытый SDK и т.п., для coreboot есть только код, немного документации, немного вики-страниц с coreboot.org и громадный mailing list. Более того, coreboot, по сути, отвечает только за очень раннюю инициализацию системы, это аналог PEI в UEFI, а все остальное предлагается делать через payload, которым может быть либо ядро ОС (как у Google, если нужен single OS PC — самое то), либо «эмулятор» легаси БИОСа SeaBIOS, либо даже реализация UEFI из TianoCore.
      Я не работал с coreboot напрямую, но участвовал на правах «мимокрокодила» в проекте проходящего у нас практику студента, который занимался адаптацией coreboot под наши платы. За 8 месяцев работы по 4-5 часов в день у него получилось загрузить Linux в качестве payload на 3 платах из 5, Windows 7 через SeaBIOS на тех же трех, но работала ОС нестабильно, а на двух оставшихся платах coreboot так и не смог инициализировать DRAM правильно, несмотря на все танцы с бубном и помощь двух не самых глупых инженеров. И наблюдений я делаю вывод, что coreboot в данный момент хорошо подходит для какого-то вполне опредленного нишевого железа (как хромобуки или индустриальные ПК), но со всеми проблемами с инициализацией, стартом и работой системы придется разбираться самому, поддержка сообщества быстро сведется к shut up and hack. Пока Google не начнет продавать support plan'ы для coreboot, нам делать на нем что-то — слишком большой риск, есть шанс не вылезти из отладки.


      1. googol
        11.07.2015 18:59

        > а на двух оставшихся платах coreboot так и не смог инициализировать DRAM правильно, несмотря на все танцы с бубном

        А если не секрет почему эти проблемы возникли только на Coreboot, но с UEFI все работало нормально? Ведь согласно вашему утверждению PEI и Coreboot выполняют одну и ту же функцию а значит инициализация должна быть одинакова и приводить к одним и тем же результатам.


        1. CodeRush Автор
          11.07.2015 19:59

          Потому, что для UEFI закрытый код инициализации памяти и чипсета поставляется в составе платформы AMI Aptio, доступ к которой у нас имеется, а в случае coreboot инициализацию выполняет открытый код, написанный сообществом в результате реверс-инжениринга и потому не всегда работающий правильно. Да и избавиться от проприетарных компонентов не получится даже с coreboot, все равно нужны и ME, и VBIOS, на использование которых все равно придется купить у Intel лицензию.


  1. Mingun
    11.07.2015 12:47
    +2

    Мне одному кажется, что этот UEFI постепенно превращается в мини-ОС? С очень многими сомнительными «фичами» (сужу со стороны дилетанта). Например, мне решительно непонятно, что делает текстовый протокол HTTP в том месте, где передаваться будут в основном двоичные данные? Определённо, где-то UEFI свернул не туда…


    1. CodeRush Автор
      11.07.2015 13:07
      +1

      UEFI — это пока еще не ОС в привычном понимании термина, это скорее очень продвинутый аналог HAL. На ОС становится похожа его комбинация с UEFI Shell, вот её уже можно назвать однозадачной дисковой ОС с прямым доступом к ресурсам, таким себе новым DOS без костылей времен Очакова.
      Добавление загрузки по HTTP объяснимо и ожидаемо, ведь хоть какой-нибудь HTTP-сервер имеется почти в каждой внутренней сети, и просто положить в /boot/bootx64.efi файл с загрузчиком намного проще, чем поднимать TFTP-сервер, настраивать специальным образом DHCP так, чтобы от отвечал на PXE-запросы и собрать загрузчик для 16-битного реального режима, не забыв проследить, чтобы его размер не превысил доступные 0x20000 байт.
      Туда он свернул или не туда — посмотрим лет через 10-15, сейчас же в каждом новом стандарте просто добавляют очередную нужную фичу, показавшуюся полезной участникам UEFI Forum. К счастью, большая часть этих фич не является обязательно к реализации, и некоторые «темные углы» стандарта EFI 1.01 так и не реализованы до сих пор. UEFI хорош тем, что если какая-то его часть мне особенно не нравится — я ее просто не собираю и все. К примеру, мне не нравится стандартный механизм Capsule Update, и в моих реализация функциих UpdateCapsule и QueryCapsuleCapabilities просто возвращают EFI_UNSUPPORTED. Кому-то не нравится SMM, кому-то другому — RW и RO-данные в одной микросхеме, но все эти вопросы решаемые и разные части стандарта не приколочены друг к другу намертво. UEFI похож на конструктор, каждый собирает из него то, что считает нужным.


      1. Mingun
        11.07.2015 14:37
        +2

        К счастью, большая часть этих фич не является обязательно к реализации

        В том-то и беда этого стандарта — слишком много вот этих всех «необязательных фич». Через 10-15 лет он будет «стандартизировать» вообще всё, что угодно, только вот реализаций 95% этого хлама вообще никогда не появится, а количество понимающих его человек сведётся к нулю, говоря утрированно.


        1. CodeRush Автор
          11.07.2015 15:04
          +2

          Не думаю. Если реализаций не появится — ненужные части просто выкинут, как это уже случилось с «хвостатыми» файлами в при переходе с FV Rev1 к FV Rev2. Наличие стандарта (даже если он всеобъемлющий и непонятный) гарантирует интероперабельность при условии, что реализации следуют букве этого самого стандарта. На данный момент в реализациях UEFI 2.4 замечательно работают драйверы, написанные для EFI 1.01, хотя их и рекомендуется переписать под новую Driver Model, чтобы они были меньше и загружались быстрее. EFI-приложения, не использующие вендорские расширения, запускаются и работают на реализациях UEFI любого производителя (проверял лично на реализациях AMI, Phoenix, Insyde и Intel). С пониманием там тоже не должно быть больших проблем, я думаю. Да, стандарт достаточно объемный, но основные идеи (как устроены драйверы, что такое протоколы, как вызвать общий код, как сохранить свои данные и т.п) намного проще, чем интерфейс через прерывания и IO-порты, которым грешил legacy BIOS.
          Мне тоже не нравится тот факт, что фичи постоянно добавляют, а баги в реализациях чинят не очень резво, но сделать с этим фактом я могу только одно — не пихать в свои БИОСы бездумно все подряд, до чего появился доступ, ведь чем меньше кода в прошивке, тем там меньше багов. К сожалению, такое мнение среди «обычных пользователей» не слишком популярно, им нужен графический Setup с красивой картинкой на фоне и прочий stuff. И загрузка чтобы без PXE-костылей. И дуалбут в Android. И черта в ступе еще. Пока такой подход позволяет продать больше плат, чем конкуренты — процесс добавления фич не остановить.


  1. Mingun
    11.07.2015 14:36

    Не туда, а вот сюда