___           ___           ___           ___           ___           ___     
     /\  \         /\__\         /\  \         /\__\         /\  \         /\  \    
    /::\  \       /:/  /        /::\  \       /:/  /        /::\  \       /::\  \   
   /:/\:\  \     /:/  /        /:/\:\  \     /:/__/        /:/\:\  \     /:/\:\  \  
  /::\~\:\  \   /:/  /  ___   /:/  \:\  \   /::\__\____   /::\~\:\  \   /::\~\:\  \ 
 /:/\:\ \:\__\ /:/__/  /\__\ /:/__/ \:\__\ /:/\:::::\__\ /:/\:\ \:\__\ /:/\:\ \:\__\
 \/_|::\/:/  / \:\  \ /:/  / \:\  \  \/__/ \/_|:|~~|~    \:\~\:\ \/__/ \/_|::\/:/  /
    |:|::/  /   \:\  /:/  /   \:\  \          |:|  |      \:\ \:\__\      |:|::/  / 
    |:|\/__/     \:\/:/  /     \:\  \         |:|  |       \:\ \/__/      |:|\/__/  
    |:|  |        \::/  /       \:\__\        |:|  |        \:\__\        |:|  |    
     \|__|         \/__/         \/__/         \|__|         \/__/         \|__|    
       

Настройка среды Linux для сборки EFI

Оглавление

Специфичные детали конфигурации для Ubuntu

На этой странице не будет подробно рассказано, как установить Ubuntu или создать виртуальную машину, мы сосредоточимся на нескольких способах настройки Ubuntu, прежде чем можно будет установить и настроить UDK.

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

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential uuid-dev iasl nasm git

На этом этапе у тебя должны быть все зависимости для UDK, которые не включены в сам пакет, и ты готов установить её.

Установка UDK

Первым шагом в настройке среды разработки является установка UDK, в данном случае TianoCore EDK II : https://github.com/tianocore/tianocore.github.io/wiki/EDK-II. Это среда с открытым исходным кодом для разработки UEFI и PI.

mkdir ~/src
cd ~/src
git clone https://github.com/tianocore/edk2
cd edk2
make -C Basetools/
export EDK_TOOLS_PATH=$HOME/src/edk2/BaseTools
mkdir Conf
. edksetup.sh BaseTools 

Если всё удалось, вывод должен быть похож на следующий:

bash$. edksetup.sh BaseTools
WORKSPACE: /home/user/src/edk2
EDK_TOOLS_PATH: /home/user/src/edk2/BaseTools
Copying $EDK_TOOLS_PATH/Conf/build_rule.template
	to $WORKSPACE/Conf/Build_rule.txt
Copying $EDK_TOOLS_PATH/Conf/tools_def.template
	to $WORKSPACE/Conf/tools_def.txt
Copying $EDK_TOOLS_PATH/Conf/target.template
	to $WORKSPACE/Conf/target.txt

На этом этапе были создали компоненты BaseTools и настроена среда оболочки сборки. Следующим шагом является настройка установки для использования правильного компилятора GCC. Сначала определи свою версию GCC, используя команду ниже.

bash$ gcc --version
gcc (Ubuntu4.9.2-10ubuntu13) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE

Согласно вышеприведенному выводу, машина использует версию GCC 4.9.2. В целях конфигурации это будет упоминаться как «GCC49».

Затем, открой Conf/target.txt файл и найди следущие строки:

ACTIVE_PLATFORM		=Nt32Pkg/Nt32Pkg.dsc
TOOL_CHAIN_TAG		=MYTOOLS
TARGET_ARCH       =IA32

И измени их на следующее:

ACTIVE_PLATFORM		=MdeModulePkg/MdeModulePkg.dsc
TOOL_CHAIN_TAG		=GCC49
TARGET_ARCH       =IA32 X64

Примечание: если на твоём компьютере с Ubuntu установлена другая версия GCC, используй свой номер вместо GCC49.

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

bash$cd ~/src/edk2
bash$build
Build environment: Linux-3.19.0-15-generic-x86_64-with-Ubuntu-15.04-vivid
Build start time: 14:18:08, Aug.11 2015
WORKSPACE        = /home/user/src/edk2
ECP_SOURCE       = /home/user/src/edk2/EdkCompatibilityPkg
EDK_SOURCE       = /home/user/src/edk2/EdkCompatibilityPkg
EFI_SOURCE       = /home/user/src/edk2/EdkCompatibilityPkg
EDK_TOOLS_PATH   = /home/user/src/edk2/BaseTools
Architecture(s)  = IA32 X64
Build target     = DEBUG
Toolchain        = GCC49
Active Platform          = /home/user/src/edk2/MdeModulePkg/MdeModulePkg.dsc
Processing meta-data ....


<LOTS OF MAKEFILE AND OTHER BUILD OUTPUT HERE>


- Done -
Build end time: 13:51:03, Aug.11 2015
Build total time: 00:06:34
bash$

Еще одно замечание: если вы получили ошибку «No command ‘build’ found», перезапустите скрипт edksetup.sh. Команда для этого: ‘. Edksetup.sh’ Обязательно используйте ‘.’ в начале команды, или она не будет работать.

На данный момент, предполагая, что сборка не выдает никаких ошибок, ты успешно создал среду сборки для EDK II. Следующим шагом является понимание того, как создать базовый исполняемый файл EFI, что будет описано в следующем разделе.

Создание и сборка базового пакета EFI

В этом подразделе ты узнаешь, как создать базовую EFI-программу в стиле «HelloWorld», и как использовать EDK2 для ее создания.

Пакет EFI и его компоненты

Основная структура сборки EDK II сосредоточена вокруг пакетов, которые используются для хранения нескольких модулей (которые в конечном итоге встроены в исполняемые файлы EFI).

Использование мастера драйверов UEFI для создания нового пакета

Мастер драйверов UEFI - это инструмент, созданный Tianocore (теми же людьми, которые опубликовали EDK II), предназначенный для облегчения создания новых драйверов и пакетов EFI. Он автоматизирует некоторые из основных задач, которые вам необходимо выполнить, чтобы создать новый пакет.

Исходники можно найти вот тут https://svn.code.sf.net/p/edk2share/code/trunk/DriverDeveloper/UefiDriverWizard, а краткое описание можно нати вот тут https://github.com/tianocore/tianocore.github.io/wiki/UEFI-Driver-Wizard.

Настроить мастер установки драйверов очень просто: используй Subversion для проверки кода, создай каталог на компьютере с Ubuntu для всего этого, и скопируй “мастера” туда. Затем перейди в этот каталог и запусти скрипт launch.py, который запустит графический интерфейс.

Предполагая, что ты хранишь код мастера драйверов в папке src, которую ты создал выше, и что твой код изначально находился в ~/Downloads/UefiDriverWizard, команды для выполнения всего этого следующие:

cp -r ~/Downloads/UefiDriverWizard ~/src/
cd ~/src/UefiDriverWizard
python launch.py

Отсюда запускается графический интерфейс. Первый шаг - перейти в меню мастера драйверов UEFI и выбрать «Открыть рабочее пространство». Это позволит мастеру использовать ранее настроенную рабочую область, а именно «~/src/edk2». Выбери эту папку и нажми «Открыть».

Теперь мастер настроен на использование рабочего пространства. Следующим шагом является создание нового пакета, используя File-> New Package. Это откроет диалоговое окно, которое позволит определить имя, GUID пакета, версию пакета и GUID платформы для твоего пакета.

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

1

После того как ты ввел путь к пакету, имя и версию (последняя часть пути и имя должны быть идентичны), нажми «Готово».

Это сгенерирует файл объявления пакета (HelloEfi.dec) и файл описания сборки (HelloEfi.dsc.) Мы вернемся к файлу dsc, как только мы будем готовы собрать исполняемый файл в конце.

Сейчас мы переходим к созданию файла Hello World на C добавим его в пакет.

Твой исходник: HelloEfi.c и твоя информация о сборке: HelloEfi.inf

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

Следующие команды будут устанавливать каталоги по мере необходимости. Команды предполагают что имя и путь вашего пакета идентичны приведенным на скриншотах ранее, если нет просто замени их на свои.

cd ~/src/edk2/HelloEfi
mkdir Library
mkdir Library/HelloEfi
cd Library/HelloEfi

Как только ты окажешься в каталоге Library/HelloEfi, пришло время создать наш C-файл, HelloEfi.c

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

/** @file
    This is a basic Hello World EFI program
**/
#include <Uefi.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiLib.h>
EFI_STATUS
EFIAPI
UefiMain (
  IN EFI_HANDLE            ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
)   
{
    Print(L"Hello EFI! \n");
    return EFI_SUCCESS;
}

Этот код имеет 3 #includes. Однако файлы заголовков на которые они ссылаются не включены в пакет HelloEfi. Вместо этого они являются частью MdePkg, основного пакета предоставляемого как часть EDK II.

Для того чтобы сконфигурировать ваш пакет HelloEfi для понимания, где находятся эти заголовочные файлы и узнать какие из них включают в себя библиотечные классы, вам нужно будет создать файл информации о сборке (.INF).

Подобно файлу C, этот файл будет расположен в HelloEfi/Library/HelloEfi/ и называется HelloEfi.inf. Его источник ниже:

##
#    Inf file for HelloEfi.efi
##

[Defines]
    INF_VERSION            =0x00010005
    BASE_NAME              =HelloEfi
    FILE_GUID              =ef6a784a-f1ee-4f75-ac0b-ba8f0869a2f2
    MODULE_TYPE            =UEFI_APPLICATION
    VERSION_STRING         =0.1
    ENTRY_POINT            =UefiMain

[Sources]
    HelloEfi.c

[Packages]
    MdePkg/MdePkg.dec

[LibraryClasses]
    UefiApplicationEntryPoint
    UefiLib

[Guids]

[Ppis]

[Protocols]

[FeaturePcd]

[Pcd]

Теперь у вас есть исходный код C и информация о сборке для этого конкретного исполняемого файла. Следующим шагом является добавление этого INF-файла в файл описания сборки для всего пакета.

DSC: Build Description File или Файл Описания Сборки

HelloEfi.dsc, расположенный в ~/src/edk2/HelloEfi/ , это файл описания сборки для всего пакета. Этот файл определяет такую информацию, как наименование и номер версии пакета, а также имена импортируемых библиотечных классов и компонентов для сборки из самого пакета. Мастер UEFI Driver создал большую часть этого файла для вас ранее, поэтому теперь единственное что нужно изменить, это раздел [Components] чтобы добавить ваш новый файл HelloEfi.inf.

Для этого откройте HelloEfi.dsc в любимом текстовом редакторе и прокрути вниз до раздела [Components]. В этом разделе добавьте путь из папки edk2 в файл inf, как показано ниже:

<the LibraryClasses section ends>

[Components]
  # THE LINE BELOW IS WHAT YOU NEED TO ADD
  HelloEfi/Library/HelloEfi/HelloEfi.inf
  # ADD THE LINE ABOVE

В качестве примечания: одна из проблем связанных с мастером драйверов заключается в том, что он настроен на использование символов новой строки DOS/Windows. Это означает, что если вы откроете файл DSC в Vim, вы увидите что файл в формате DOS и Vim будет отображать символ «^M» в конце каждой строки.

Нужно будет это исправить чтобы твой пакет мог быть правильно проанализирован в Unix. Можно вручную удалить каждый из символов «^M» или ввести в Vim следующую команду:

:%s/^M//g

Чтобы получить «^M», вам нужно набрать CTRL + V, а затем CTRL + M. Нажатие «^ M» заставит его искать эти литеральные символы, а не 0xD.

Теперь, когда у тебя есть файл DSC, отформатированный для Unix и указывающий на твой INF-файл, ты готов к сборке!

Сборка пакета и обнаружение исполняемого файла

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

. edksetup.sh
build -p HelloEfi/HelloEfi.dsc
cd Build/HelloEfi/Debug_GCC49/X64
<HelloEfi.efi is in this directory!>

Создание EFI из PocPkg директории внутри QuarkMatter репозитория

Следующим шагом является понимание того, как создать код из репозитория QuarkMatter в UDK. Одним из возможных решений было бы поместить клон репозитория QuarkMatter в подкаталог твоего корневого каталога EDK (~/src/edk2). Однако, чтобы упростить работу с использованием git (вместо того, чтобы заполнять .gitignore всеми другими файлами которые мы создали), мы вместо этого поместим символические ссылки в корневой каталог UDK а затем создадим из них ссылки.

Чтобы сделать ссылки и собрать пакет, нужно будет выполнить следующие команды:

cp -rs /$PATHTOQUARKMATTER/quarkmatter/PocPkg /home/user/src/edk2/  #Создание символических ссылок
cd /home/user/src/edk2				#Навигация в edk2 директорию для сборки
. edksetup.sh					#Убеждаемся что переменные окружения правильно выставленны
build -p PocPkg/PocPkg.dsc			#Создаем пакет так, как если бы исходный код находился в каталоге edk2
cd Build/PocPkg/Debug_GCC49/X64			#Переход к расположению получаемых двоичных файлов EFI

Этот процесс может быть применен к любым другим пакетам которые не находятся в каталоге edk2, которые ты хочешь собрать.