建议:在虚拟机上进行实验
1 实验环境
Windows 10,VisualStudio2017pro(30天适用版),python3.7
2 UEFI 环境搭建
安装VS2017 Pro
在 edk2\Conf\tools_def.txt 中可以看到可以使用的工具链,这里使用VS2017 pro(30天适用版)
选择 使用C++桌面开发 默认配置,安装目录 建议默认
安装NASM
Index of /pub/nasm/releasebuilds/2.15.02/win64
下载后 建议以管理员模式打开 以便安装给任何用户使用,安装目录的长度不要过长
建议安装到C:/NASM
安装IASL
https://acpica.org/sites/acpica/files/iasl-win-20200717.zip
建议将压缩包解压后放到C:/ASL
目录格式类似:
C:
-- ASL
-- -- iasl.exe
-- -- xxx.exe
安装 Python 3.7.x
https://www.python.org/downloads/windows/
更高版本应该也行,不过要下载x86-64版本,注意勾选添加到环境变量
下载edk2
Lib C progject
$> git clone https://github.com/tianocore/edk2-libc.git
edk2 master
$> git clone --recursive https://github.com/tianocore/edk2
位置自定,但建议路径不要太长
文件目录结构为:
ed2k-ws
-- ed2k
-- ed2k-libc
成功的关键
之所以推荐按照建议的目录地址安装文件,是因为看到 edk2\Conf\tools_def.txt 中对于ASL_PATH似乎已有定义,并且还写死了,因此还是小心为重,不然很有可能会在构建时有指令无法执行导致程序中断退出
3 构建环境
打开 VS2017 开发人员命令提示符
> cd edk2-ws/edk2
> edksetup.bat rebuild
> edksetup.bat
不出意外的话这个过程中可能会报很多 Warning,但不会有 fatal error
运行后打开 edk2\Conf\target.txt
将 TARGET_ARCH = X64 or IA32 (本人选择X64)
将 TOOL_CHAIN_TAG = VS2017
还是在edk2目录下,> build
这个时候可能也会报 warning,但只要没有fatal error,应该没问题,完成后会显示done
这个时候切换为 英文输入法,否则打开WinHost后会失去锚点,没法控制 (好像死机了)
打开 edk2-ws\Build\EmulatorX64\DEBUG_VS2017\X64,点击WinHost.exe
现象如下:
进入文件系统
> fs0:
输入ls可以查看文件信息
这里面有个示例程序HelloWorld.efi,输出Hello World,它就是使用pcd静态全局变量进行输出
然后就是照葫芦画瓢了
4 照葫芦画瓢
打开ed2k目录,可以看到 HelloWorld.c 程序在 \edk2\MdeModulePkg\Application\HelloWorld文件夹下
观察.c程序和.inf文件,可以大概明白inf文件说明了.c文件的程序入口以及引用到的模块以及文件夹等信息
值得注意的是,HelloWorld.c文件中有这么三个变量,从注释可以看到,这大概是PCD的三个类型,bool,unsigned int,string
那么只要找到这三个变量的定义应该就能够可以输出自己想输出的语句了
利用搜索工具(VSCode一些插件),可以发现这三个变量的定义在 \edk2\MdeModulePkg\MdeModulePkg.dec文件中
其定义为 Guid.名称 | 值 | 类型 | token
那么事情就很简单了,改PcdHelloWorldPrintString的值应该就能更改输出了
还有一个问题,既然添加了一个HelloWorld模块,系统怎么知道到哪去找,并且进行编译呢?
在观看大佬的视频后,发现在 \edk2\EmulatorPkg\EmulatorPkg.dsc 文件中记录了 HelloWorld.inf 的路径,这样在编译的时候就会编译HelloWorld.c 生成 到 HelloWorld.efi 可执行文件
「UEFI」第1话 EDK2工程介绍以及HelloWorld_哔哩哔哩_bilibiliy
因此,我们只需要创建一个目录结构与HelloWorld类似的文件夹,并且配置好对应的参数设置,在MdeModulePkg.dec文件声明变量,再到 \edk2\EmulatorPkg\EmulatorPkg.dsc 声明一下.inf 文件的位置,就大功告成了
最后别忘了要再次build
关于.inf文件里的 file_guid
这个问题个人理解为唯一标识符,只要符合格式,保证其独一无二即可
如有问题或意见建议,恳请大佬批评指正!