UEFI编程入门-环境准备
UEFI编程入门-环境准备
环境准备
准备
需要安装Visual Studio 2019、Python 2.7+、IASL编译器、NASM编译器,并将后两者加入PATH。
其中IASL编译器下载地址https://www.intel.com/content/www/us/en/developer/topic-technology/open/acpica/download.html 。NASM编译器下载地址https://www.nasm.us/pub/nasm/releasebuilds/2.16.03/win64/ 。
下载EDK2开发包:
1 | git clone https://github.com/tianocore/edk2.git |
EDK2中通过Submodule方式提供了些必要的库文件和编译所需源文件,这里对他们进行初始化和更新,在edk2目录下:
1 | git submodule update --init #以后再更新就不用加--init了 |
再在edk2目录下编译BaseTools,这里要打开Visual Studio的x86 Native Tools Command Prompt。编译好的BaseTools在BaseTools目录中。
1 | edksetup.bat Rebuild |
接着为了方便后续添加新开发包,这里编写一个设置开发工具路径的批处理。在edk2和edk2-libc同目录下,新建mybuild.bat,添加:
1 | set WORKSPACE=%CD% |
UEFI编译依赖edk2/Conf目录下的target.txt和tools_def.txt。分别指定编译默认参数和编译工具链。例如target.txt的设置:
1 | ACTIVE_PLATFORM = EmulatorPkg/EmulatorPkg.dsc #目前正在编译的包 |
在tools_def.txt中有大量可用编译器,这个就不需要管了。
编译
先编译UEFI模拟器EmulatorPkg,在x86 Native Tools Command Prompt中:
1 | mybuild.bat |
再编译UEFI程序,同样在x86 Native Tools Command Prompt中:
1 | #例如编译edk2\-libc中的AppPkg包: |
编译出来的目标程序都在Build目录下。
模拟
运行WinHost:
1 | cd Build\EmulatorIA32\DEBUG_VS2022\IA32 |
成功启动后进入UEFI Shell,显示挂载了一些设备,其中FS0为主机Build\EmulatorIA32\DEBUG_VS2022\IA32目录。UEFI Shell命令与DOS或Bash差不多,如ls
或dir
、pci
等,用help -b
查看帮助。这里运行helloworld:
1 | fs0: |
调试
Visual Studio 2022联动
这里对HelloWorld.efi进行调试。在edk2\MdeModulePkg\Application\HelloWorld目录下用Visual Studio 2022新建一个生成文件项目(Makefile Project),工程名随便起,这里叫x43dbg_vs,其中生成命令行、清除命令行和重新生成命令行先随便填,接下来要改,其他不用管。之后打开x32dbg_vs.vcxproj并修改对应DEBUG选项的NMakeBuildCommandLine标签内容:
1 | cd /D D:\tests\UEFItest |
修改NMakeCleanCommandLine标签内容:
1 | cd /D D:\tests\UEFItest |
修改NMakeReBuildCommandLine标签内容:
1 | cd /D D:\tests\UEFItest |
再手动把edk2\MdeModulePkg\Application\HelloWorld\HelloWorld.c导入源文件下,之后进行Build,发现下方输出窗口内容同上述手动编译过程。然后在项目属性中设置调试->工作目录为D:\tests\UEFItest\Build\EmulatorIA32\DEBUG_VS2022\IA32\,命令改为WinHost.exe。之后对源码打断点,并用F5启动调试。随即启动WinHost.exe,在其中运行HelloWorld.efi,发现在Visual Studio中命中断点。
QEMU+WinDBG联动
先下载QEMU和Intel UDK Debugger Tool,前者在https://qemu.weilnetz.de/w64/,后者在https://www.intel.com/content/www/us/en/developer/articles/tool/unified-extensible-firmware-interface.html 。Intel UDK Debugger Tool安装时选择Pipe类型,Port填qemu_pipe_dbg。WinDBG和Intel UDK Debugger Tool安装目录上不要有汉字。
接下来为QEMU创建VHD虚拟硬盘。打开Windows自带磁盘管理工具,选中某个磁盘创建VHD,200MB大小即可,命名为lbdbg.vhd,并设为动态增长模式。然后对刚生成的虚拟硬盘文件装载,格式化为FAT32分区,再弹出。
接着用OvmfPkg制作一个支持源码级调试的BIOS镜像,例如32位:
1 | build -a IA32 -p edk2\OvmfPkg\OvmfPkgIa32.dsc -b NOOPT -D SOURCE_DEBUG_ENABLE #X64改为-a X64 OvmfPkgX64.dsc |
编译出的文件位于Build\OvmfIa32\NOOPT_VS2022\FV目录下的OVMF.fd,并将HelloWorld.efi复制到lbdbg.vhd分区中,弹出。找个地方新建dbgOvmfIa32文件夹,将lbdbg.vhd和OVMF.fd复制到这里。打开开始菜单的Start Windbg With Intel UDK Debugger Tool,如果弹出不支持该内核调试方法,则自行启动管道调试。在dbgOvmfIa32目录打开命令行,运行:
1 | qemu-system-i386 -L . -bios OVMF.fd -hdd lbdbg.vhd -serial pipe:qemu_pipe_dbg |
运行后用下面命令下断点,并用g
继续:
1 | bu HelloWorld!UefiMain |
制作启动盘
这里只讲针对UEFI BIOS制作的启动盘。启动文件通过编译ShellPkg得到:
1 | mybuild.bat |
在Build\Shell\RELEASE_VS2022下的IA32和X64目录下各有一个Shell.efi,所处目录类似于Build\Shell\RELEASE_VS2022\IA32\ShellPkg\Application\Shell\EA4BB293-2D7F-4456-A681-1F22F42CD0BC\OUTPUT,分别改名为bootx32.efi和bootx64.efi。之后将U盘格式化为FAT32格式,在U盘根目录下建立efi\boot目录,将bootx32.efi和bootx64.efi复制到该目录下。重启计算机,开机从U盘启动即可进入UEFI Shell。