Здравствуй, UEFI!

Здравствуй, UEFI!

Когда ранее мы упоминали, что командный DOS-ин­тер­пре­та­тор под наз­ва­ни­ем COM­MAND.COM в прин­ци­пе не ну­жен, так как его роль — это ор­га­ни­за­ция ин­тер­ак­тив­но­го ре­жи­ма, то дан­ный факт прак­ти­че­ски ни­ког­да не ре­а­ли­зо­вы­вал­ся на прак­ти­ке и ин­тер­пре­та­тор всег­да был в сис­те­ме. Для UEFI же при­сущ ди­а­мет­раль­но дру­гой под­ход — нуж­но обес­пе­чить преж­де все­го вы­пол­не­ние за­груз­чи­ка опе­ра­ци­он­ной сис­те­мы, по­э­то­му на­ли­чие про­ме­жу­точ­но­го ин­тер­ак­тив­но­го при­ло­же­ния ско­рее вре­дит, чем по­мо­га­ет.

В роли командного интерпретатора – EFI Shell

Поэтому EFI Shell формально существует в природе, но фак­ти­че­ски внутри firmware его нет. Что, однако, не оз­на­ча­ет не­воз­мож­ность его за­пус­ка — отнюдь. По­мес­тив на USB-носитель в раздел \boot\EFI\ файл EFI Shell под стан­дарт­ным наз­ва­ни­ем bootx64.efi, мы по­лу­чаем ре­ин­кар­на­цию DOS-системы, но на со­вре­мен­ный лад. Чтобы не быть при­вя­зан­ным к реальной аппаратуре и обезопасить себя от воз­мож­ных не­га­тив­ных по­след­ст­вий, я предлагаю даль­ней­шие дей­ст­вия перенести в эму­ли­ро­ван­ную среду и про­дол­жить зна­ком­ст­во с EFI Shell на примере QEMU и спе­ци­аль­но ада­п­­ти­­ро­­ван­­ным для него Ti­ano­core BIOS [3].

Итак, забираем архив с Tianocore BIOS, распаковываем в текущий каталог и запускаем эмулятор как:

/usr/local/qemu-1.6/bin/qemu-system-x86_64 -L

Ключ «-L» означает, что видео- и BIOS-файлы хранятся в текущей директории. Сам файл EFI Shell интегрирован в образ BIOS.

Командная строка EFI Shell напоминает CLI-интерфейс от DOS

Командная строка EFI Shell напоминает CLI-интерфейс от DOS

Запустив командный интерпретатор EFI, убеждаемся в первом впечатлении — очень похоже на старые, добрые дни MS-DOS. Есть встроенная справка (интегрированная в Shell команда help), присутствует текстовый редактор, который теперь умеет редактировать ASCII и UTF8-файлы, и ряд других команд. Однако, внедрение открытых технологий не мог­ло повлиять и на развитие UEFI. В числе команд замечаем также специфичные команды вида mount и load. Со­от­вет­ст­вен­но, означающие монтирование раздела и загрузку в память драйвера к устройству. Очень похоже на BSD- и Linux-системы, не правда ли?

Загрузка интерпретатора UEFI осуществляется силами UEFI Boot менеджера

Загрузка интерпретатора UEFI осуществляется силами UEFI Boot менеджера

Дабы ощутить всю мощь EFI, создадим файловый образ с GPT-таблицей. А в нем сделаем 2 раздела: один в формате FAT16, понятный для встроенных драйверов EFI, а другой отформатируем в EXT2, но с прицелом его монтирования из-под самой микро-ОС UEFI

$ parted ./hdcblk
WARNING: You are not superuser. Watch out for permissions.
GNU Parted 2.3
Using /home/anton/efi/hdcblk
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) Unit
Unit? [compact]? B
(parted) print
Model: (file)
Disk /home/anton/efi/hdcblk: 157286400B
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number Start End Size Type File system Flags
1 1048576B 52428799B 51380224B primary fat16 boot, lba
2 52428800B 157286399B 104857600B primary ext2

(parted) quit

Листинг 1. Определяем смещение внутри GPT-таблицы

Определим смещение и монтируем первый раздел в виде loop-устройства. Кладем необходимые драйверы и готовые EFI-приложения и запускаем QEMU заново. Пе­ред нами при­мон­ти­ро­ван­ный раздел FAT16, переход на него осу­ще­ст­вля­ет­ся как: «fs0:»

Проверим командой map, какие разделы еще при­мон­ти­ро­ва­ны, но видим только еще одно блочное устройство. Всё вер­но, в DXE пространстве ведь нет драйвера для EXT2-разделов.

EFI-приложение можно тестировать через интерфейс Boot Maintenance Manager

EFI-приложение можно тестировать через интерфейс Boot Maintenance Manager

Загрузим и при­мон­ти­ру­ем наш раздел с помощью ext2-драйвера с проекта rEFInd, т.е. выполним по­сле­до­ва­тель­но ко­ман­ды по одной на каждую строку: «load ext2_x64.efi», «mount blk3 fs1», «fs1:», «dir». Убеждаемся, что раздел успешно при­мон­ти­ро­ван.

Отлично, теперь у нас есть доступ практически к любой файловой системе, благо EFI-драйверы к ним уже созданы. А это означает, что не за горами создание не только аналога Volkov Commander для EFI-среды, но также и сервисных ути­лит и приложений — тот же антивирусный пакет, пор­ти­ро­ва­ние текстовых (и графических!) приложений (на­при­мер, бра­узер links) и многое другое. С учетом того, что перед нами из­на­чаль­но безопасная и чистая среда, то перед нами дей­ст­ви­тель­но лю­бо­пыт­ные пер­с­пек­ти­вы. Выглядят заманчиво? Еще бы!

Практически любая файловая система может быть смонтирована с помощью EFI-драйверов

Практически любая файловая система может быть смонтирована с помощью EFI-драйверов

Как и на чем создавать EFI-приложения?

Может создаться обманчивое впечатление, что EFI-приложение — это безумно сложное программирование. Но это не так. Для создания приложений требуется компилятор, который умеет создавать объектный код в формате PE32. И сре­да разработчика EDK II (EFI Development Kit) / UDK2010 (UEFI DevKit) [6]. Несмотря на то, что спецификации от­кры­ты и код ли­цен­зи­ру­ет­ся под BSD-лицензией и даже принимаются от пользователей ап­ст­рим-изменения в EDK II, сре­да UDK считается стабильной и эталонной для про­из­во­ди­те­лей ма­те­рин­ских плат, т.к. раз­ра­ба­ты­ва­ет­ся и под­дер­жи­ва­ет­ся компанией Intel.

Формат EFI-приложения должен соответствовать стандарту PE32

Формат EFI-приложения должен соответствовать стандарту PE32

Среда разработчика существует как для Linux, так и для систем на базе Windows и Mac OS X. Сборка обеспечивается, как правило, компиляторами GCC и нативными из состава Visual Studio 2008 и Xcode. Хотя повторюсь – фактически, достаточно будет только компилятора и заголовочных файлов EDK. Данный факт особенно актуален, если принято решение задействовать ассемблер, а именно flatasm [4]. В этом случае получится создавать наиболее оп­ти­ми­зи­ро­ван­ный и минимальный код. Конечно, при росте проекта имеет смысл пе­ре­о­ри­ен­ти­ро­ватьмся на C/C++ и пе­ре­хо­дить, со­от­вет­ст­вен­но, на EDK.

Более подробно на создании EFI-приложений остановимся в следующих публикациях, а пока отмечу, что приложение вида «Hello, World» на ASM занимает всего 50 строк. Компилируется FlatASM на станции с Core2Duo за 1 ми­кро­се­кун­ду и за­ни­ма­ет только 2 Кб.

Выводы

С точки зрения дальнейшего развития подсистемы низкоуровневого аппаратного обеспечения (BIOS) появление от­кры­то­го решения, похожего на EFI, кажется закономерным и не случайным. Появляются серверные и деск­топ­ные плат­фор­мы на основе разных процессорных ар­хи­тек­тур (x86_64, ARM, IA64), чипсетов и интегрированных устройств, на­при­мер, организующих шифрование (чипы TPM). Для организации всего этого сонма в единое целое требуется мо­ду­ль­ный кон­ст­рук­тор, которым могли бы пользоваться как ко­неч­ные про­из­во­ди­те­ли, так и из­го­то­ви­те­ли от­дель­ных ап­па­рат­ных мо­ду­лей. К сча­стью, на­сущ­ность этой проб­ле­мы пер­вой уви­де­ла Intel и пред­ста­ви­ла та­кое от­кры­тое ре­ше­ние как UEFI. К вя­щей ра­дос­ти про­грам­мис­тов сис­тем­ного ПО, т.к. при бли­жай­шем рас­смот­ре­нии ука­зан­ное ре­ше­ние яв­ля­ет­ся на­сто­я­щей мик­ро-опе­ра­ци­онvной сис­те­мой с прак­ти­че­ски не­ог­ра­ни­чен­ны­ми воз­мож­но­стя­ми по уп­рав­ле­нию как ап­па­рат­ной ча­стью, так и за­гру­жа­е­мой в даль­ней­шем ре­аль­ной ОС — будь это Windows, BSD, Linux или нечто ана­ло­гич­ное. А при­ме­не­ния этим воз­мож­но­стям от­кры­ва­ют­ся са­мые ши­ро­кие.

Ссылки

[3] http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=OVMF

[4] http://flatassembler.net/