Файловые операции в UEFI

12 Дек 2014

Файловые операции в UEFI

Около 30 лет назад разработчики персональной платформы IBM PC, определяя архитектуру функций дискового сервиса BIOS, приняли очевидное и логичное решение, согласно которому процедуры firmware, находящиеся в постоянном запоминающем устройстве системной платы, должны работать с гибкими и жесткими дисками исключительно на уровне секторов, дорожек и цилиндров. Таким образом, для BIOS была отведена роль «исполнительного механизма», умеющего только читать и писать сектора, по заданиям от операционной системы, которая, в свою очередь, осуществляет поддержку файловых операций, каталогов, таблиц FAT32 и других подобных структур. Появление UEFI разрушило эту модель, сегодня firmware «умеет» работать с файлами. С чем связано такое изменение подходов?

Задача первая – загрузка ОС

Согласно «старой» модели, при которой интеллект загрузчика ОС, входящего в состав firmware, минимален, реализуется такой сценарий. BIOS (а точнее, процедура INT 19h) читает с диска загрузочный сектор с фиксированными координатами: цилиндр 0, поверхность 0, сектор 1. После этого, управление передается загрузчику, находящемуся в прочитанном секторе, он и управляет дальнейшими действиями. Размер этого загрузчика ограничен размером сектора и равен 512 байт. В силу такого малого размера, данный загрузчик «не умеет» находить файлы, расположенные произвольно. Именно поэтому, положение системных файлов MS DOS привязано к заданным областям диска и после обычного копирования этих файлов система не загружается. Также очевидно, что данный сценарий старта ОС трудно согласуется с такими нововведениями, как удаленная загрузка.

Спецификация UEFI поддерживает файловые операции на уровне firmware, поэтому загрузка ОС происходит принципиально по-другому. На диске должен присутствовать файл с заданным именем по заданному пути. Для x64 UEFI это EFI\BOOT\bootx64.efi. Какая-либо привязка к секторам диска отсутствует, загрузчик является обычным UEFI-приложением. Чтобы сделать диск загрузочным, нам достаточно создать каталоги и скопировать файл загрузчика, а расположив под этим именем UEFI Shell можно ощутить все преимущества «64-битной DOS среды».

Задача вторая – обновление firmware

Реализация функции обновления BIOS в составе CMOS Setup персональной платформы требует поддержки файловых операций на уровне firmware. Очевидно, файл «прошиваемого» образа требуется прочитать с дискового устройства. Справедливости ради, отметим, что такая функциональность появилась в ряде платформ еще до поддержки UEFI, но при этом ее реализация была «незаконной» с точки зрения используемой в данных платформах архитектуры Legacy BIOS, что, разумеется, не способствовало стабильной работе.

Задача третья – снимки экрана Setup

Еще один бонус, который принесла новая технология, это возможность сохранения графического образа экрана из CMOS Setup в виде BMP-файлов в корневом каталоге USB-флешки.

Архитектура EFI File Protocol: взгляд изнутри


Рис.1Структура интерфейсного блока EFI File Protocol согласно UEFI Specification

Рассмотрим реализацию и формат интерфейсного блока EFI File Protocol в рамках UEFI Driver Model (рис.1). Блок состоит из следующих полей:

  • Поле Revision отражает версию реализации протокола, далее следуют 10 указателей для вызова сервисных функций.
  • Open: открытие или создание файла
  • Close: закрытие файла.
  • Delete: удаление файла.
  • Read: чтение файла.
  • Write: запись в файл.
  • GetPosition: получение значения указателя для доступа к файлу
  • SetPosition: установка значения указателя для доступа к файлу
  • GetInfo: получение информации о файле или носителе
  • SetInfo: установка атрибутов файла или носителя
  • Flush: очистка буферов с выполнением ранее отложенной записи.

Реализация IA32 EFI использует 32-битные указатели для вызова функций (процедуры вызываются 32-битной внутрисегментной формой инструкции CALL), x64 UEFI использует 64-битные указатели (процедуры вызываются 64-битной внутрисегментной формой инструкции CALL).

Резюме

В рамках работы над проектом Tetris64 мы использовали функции EFI File Protocol для реализации следующих операций: загрузка, обновление и создание конфигурационного файла, а также сохранение графического образа экрана в виде неупакованного BMP-файла:
 

 

Рис. 2Снимок экрана, полученный из UEFI-среды в процессе запуска игры Tetris64

Все функции работают согласно спецификации UEFI. При отладке программы было замечено, что процедуры данного протокола критичны к выравниванию стека на границу 16-байтного блока, также как и процедуры Graphics Output Protocolна некоторых платформах. Это свидетельствует о том, что firmware оптимизировано с применением эффективных SSE-инструкций, например MOVAPS, для которых адрес операнда в памяти должен быть кратен 16.