UEFI开发探索57-如使用最新的EDK2搭建编译环境

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】

最近浏览github上edk2的发布代码,注意到一个问题,现在发布的方式有点不一样了。之前过一段时间,就会发布一个完整的打包源代码,比如2018年3月发布的UDK2018,我一直都用这个开发的。不过,我没有找到UDK2019,更别说UDK2020了。

为什么我关注这个呢?主要是因为这种打好包的源码,整理得比较好,也比较稳定,并且还提供完整的API文档。另外,如果直接git EDK2的主线,编程时会发现它其实缺一些包是,有的包些还需要在Google的项目中下载。(观察下https://github.com/tianocore/edk2下的.gitmodules就知道了)

既然没有更新的打包源码,就只能用git下载最新的EDK2来编译了。不过,github那感人的下载网速,没有一定的定力,还真扛不住。

之前的博客中,其实已经给了解决的方法了。但是没有详细讲如何搭建最新的EDK2编译环境,正好用这篇博客完整地说一遍。

1 将github上项目导入到gitee仓库上

具体的方法可以参考我之前的博客:

或者

https://blog.csdn.net/luobing4365/article/details/105658274

对edk2,我常用的项目包括edk2、edk2-platforms、edk2-libc,它们的github地址分别为:

https://github.com/tianocore/edk2.git
https://github.com/tianocore/edk2-platforms.git
https://github.com/tianocore/edk2-libc.git

为了更新submodules(子模块),以下的库也是必须的:

https://github.com/openssl/openssl
https://github.com/ucb-bar/berkeley-softfloat-3.git
https://git.cryptomilk.org/projects/cmocka.git
https://github.com/kkos/oniguruma
https://github.com/google/brotli

把它们都导入到gitee仓库上,以备后用。

2 下载源码

(以下的例子中,gitee上的仓库是我私有的,其他人是无法下载的。请替换为自己的仓库)

在下载源码前,必须安装必要的编译工具,包括Visual Stdio、Python、ASL和Nasm。安装方法在第22篇博客中已经讨论过了(UEFI开发探索22-环境搭建3),就不重复了。

首先需要安装Windows版本的git工具,下载地址为:https://git-scm.com/download/gui/win。下载后点击安装即可。

右键,选择“Git Bash Here”,新建工作目录,并将常用的三个项目的源代码git下来,命令为:

$mkdir UEFIWorkspace
$cd UEFIWorkspace
$git clone git@gitee.com:luobing4365/edk2.git
$git clone git@gitee.com:luobing4365/edk2-libc.git
$git clone git@gitee.com:luobing4365/edk2-platforms.git

为了更新submodules,必须修改edk2目录中的.gitmodules,否则更新时,它还是去github上下载。

把edk2\.gitmodlues中的内容修改为(注意替换为自己的gitee仓库):

[submodule “CryptoPkg/Library/OpensslLib/openssl”]
         path = CryptoPkg/Library/OpensslLib/openssl
         url = git@gitee.com:luobing4365/openssl.git
[submodule “SoftFloat”]
         path = ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
         url = git@gitee.com:luobing4365/berkeley-softfloat-3.git
[submodule “UnitTestFrameworkPkg/Library/CmockaLib/cmocka”]
         path = UnitTestFrameworkPkg/Library/CmockaLib/cmocka
         url = git@gitee.com:luobing4365/cmocka.git
[submodule “MdeModulePkg/Universal/RegularExpressionDxe/oniguruma”]
         path = MdeModulePkg/Universal/RegularExpressionDxe/oniguruma
         url = git@gitee.com:luobing4365/oniguruma.git
[submodule “MdeModulePkg/Library/BrotliCustomDecompressLib/brotli”]
         path = MdeModulePkg/Library/BrotliCustomDecompressLib/brotli
         url = git@gitee.com:luobing4365/brotli.git
[submodule “BaseTools/Source/C/BrotliCompress/brotli”]
         path = BaseTools/Source/C/BrotliCompress/brotli
         url = git@gitee.com:luobing4365/brotli.git

然后进入edk2的目录,更新submodules,否则会影响后面BaseTools的编译。

$cd ekd2
$git submodlue update –init

如果以后需要更新edk2,可以在edk2的目录下打开git bash,使用如下命令:

$git pull
$got submodule update

源码下载完成,可以准备搭建环境了。

3 编译BaseTools

这个步骤比较简单,打开VS2015的Native命令行,进入edk2,执行:

C:\UEFIWorkspace\edk2> edksetup.bat Rebuild

编译完成后,工作目录的结构如下:

图1 源码结构目录

4 编译UEFI程序

在图1中,有一个名为“mybuild.bat”的批处理文件,这是为了以UEFIWorkspace为编译的工作目录而写的。

在以前使用UDK2018的时候,edk2-libc下的三个包文件AppPkg、StdLib、StdLibPrivateInternalFiles,被直接放在了UDK2018的目录下,与其他的包放在一起。这样当然也可以,可以直接编译,不用设置库的寻找路径。

但是,当使用edk2-platforms的时候,我实在不想把这个项目的所有文件也一起拷贝到edk2的目录中去,这会让整个edk2目录臃肿无比,也很不利于查找文件。

所以,我写了mybuild.bat,用来保持现在这种简洁的目录结构。这个批处理文件的内容为:

@REM 为保持比较清爽的目录而编写的,同时也方便编译新添加的各种包。
@REM Copyright (c) 2020-2030, Robin
@echo off
set WORKSPACE=%CD%
set EDK_TOOLS_PATH=%CD%\edk2\BaseTools
set CONF_PATH=%CD%\edk2\Conf
set PACKAGES_PATH=%CD%\edk2;%CD%\edk2-libc
@echo Set the Workspace.  -by robin 20200515

使用也比较简单,在执行edksetup.bat之前执行它就可以了。以编译AppPkg为例,命令如下(打开VS2015的编译命令行):

C:\UEFIWorkspace> mybuild.bat
C:\UEFIWorkspace> edk2\edksetup.bat
C:\UEFIWorkspace> build -p edk2-libc\AppPkg\AppPkg.dsc -t VS2015x86 -a IA32

所编译出的程序在C:\UEFIWorkspace\Build下。

5 新的特性

最新的edk2中(当前我使用的是2020年3月份的版本),已经取消了NT32Pkg这个模拟器了,取而代之的是EmulatorPkg。

让人高兴的是,新的模拟器终于提供了64位程序的支持了!再也不用为了测试64位的efi程序,还要特意打开VirtualBox或者Qemu来进行测试了。把执行文件拷贝到虚拟机的镜像里,是有点麻烦,有时甚至不如直接用实际的机器,用U盘拷贝文件去测试来得快。

另外,这也意味着,应该可以直接使用Visual Studio自带的调试器,调试64位的代码了。

EmulatorPkg的编译,之前在Linux下已经试过,编译命令如下:

C:\UEFIWorkspace> build -p edk2 \EmulatorPkg\EmulatorPkg.dsc -t VS2015x86 -a X64

编译出来的模拟器名称为WinHost.exe,位于Build\EmulatorX64\DEBUG_VS2015x86\X64下,双击运行即可。

10,686 total views, 1 views today

《UEFI开发探索57-如使用最新的EDK2搭建编译环境》有10个想法

  1. 你好,linux下编译EmulatorPkg完成后,模拟器名字叫什么?怎么使用?我编译完执行run时,出现了gdb。
    希望您能解答,尽可能详细,谢谢。

    1. ~/UEFIWorkspace$ cd Build/EmulatorX64/DEBUG_GCC5/X64/ && ./Host

      名字为Host。注意看下EmulatorPkg下的说明文档,里面其实有详细说明

  2. 除了没下载git以外都是按照楼主的方法,Rebuild basetool 怎么都不过, 提示 brotli 模块有问题
    开发环境搭建确实是个头疼的问题

    1. 在后续的EDK2提供的搭建方式中,brotli模块,可以通过更新子模块的方式来进行了。git submodules update –init

  3. 您好。
    您在博文中提到,“另外,这也意味着,应该可以直接使用Visual Studio自带的调试器,调试64位的代码了。”
    我想试着实现一下。
    参考您之前的博客,我成功搭建了VS2015下的调试环境。但是,如果我的工程中使用了C标准库函数,即使我在EmulatorPkg.dsc中include了StdLib,仍无法编译成功。(可能说的不是很明白,举个例子,搭建好VS2015调试环境后,可编译成功正常调试AppPkg中的Hello工程,却无法成功编译AppPkg中的Main工程,原因就是Main工程使用了C标准库函数)(相同的操作,在Nt32Pkg下include StdLib,编译AppPkg中的Main工程,就可以编译成功,自然也能正常调试,是不是EmulatorPkg不支持StdLib?如果确实不支持,如果要调试64位的使用了C标准库函数的工程,该如何做?)
    部分代码如下,EmulatorPkg.dsc中include StdLib的代码:
    DEFINE EMULATE
    !include StdLib/StdLib.inc
    部分报错信息如下:
    d:\workspace_edk\edk2\StdLib\LibC\Wchar\Copying.c(32): error C2220: warning treated as error – no ‘object’ file generated
    Building … d:\workspace_edk\edk2\StdLib\LibC\StdLib\StdLib.inf [X64]
    d:\workspace_edk\edk2\StdLib\LibC\Wchar\Copying.c(32): warning C4013: ‘StrCpy’ undefined; assuming extern returning int
    d:\workspace_edk\edk2\StdLib\LibC\Wchar\Copying.c(47): warning C4013: ‘StrnCpy’ undefined; assuming extern returning int
    。。。
    d:\workspace_edk\edk2\StdLib\LibC\Wchar\Concatenation.c(34): error C2220: warning treated as error – no ‘object’ file generated
    d:\workspace_edk\edk2\StdLib\LibC\Wchar\Concatenation.c(34): warning C4013: ‘StrCat’ undefined; assuming extern returning int
    cl : Command line warning D9025 : overriding ‘/GL’ with ‘/GL-‘
    d:\workspace_edk\edk2\StdLib\LibC\Wchar\Concatenation.c(47): warning C4013: ‘StrnCat’ undefined; assuming extern returning int
    cl : Command line warning D9025 : overriding ‘/O1’ with ‘/Od’

    1. 这和是否用VS2015调试无关,主要还是需要在EmulatorPkg中编译成功自己的工程。因为平常的开发中,不怎么用到StdLib,您说的这种情况我没有遇到过。我的考虑,可以参考Nt32Pkg的DSC和DEC文件,看是哪边导致编译不通过,再去考虑调试的问题。StrCpy等都是UEFI的MdePkg中自带的,也许是EmulatorPkg中没有包含这些常用的库吧(没有去仔细研究,不一定正确)

    2. 上午正好有点时间,看了下这个问题,是可以调试StdLib的64位app了。具体的问题和解决方法,准备在UEFI探索的第92篇博客中给出,有空看看吧

罗冰(Robin)进行回复 取消回复

电子邮件地址不会被公开。