BIOS 编译过程:C文件到EFI文件

    上一篇Blog介绍了exe的生成,从C 到 exe可以通过“cl /c”来编译到“obj”,然后再“link”到exe。如果用到其他lib的话,还需要用“/I<dir> add to include search path”来添加相应的lib文件。

    这里我们写了一个最精简的Pkg,里面有个最精简的UEFI app,用来探究C文件到EFI文件的过程。这个UEFI app 代码只有“Hello.inf”和“Hello.c”两个文件,使用了最少的lib,以方便看流程:

#include <Uefi.h>

EFI_STATUS
EFIAPI
Main (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EFI_SUCCESS;
}

    用“build > log.txt”可以把build log记录下来分析,log里面跟这个app相关的命令有以下几条:

	"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\cl.exe" /Fod:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\.\Hello.obj /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Id:\udk2017_25818\AppPkgSample\Hello  /Id:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG  /Id:\udk2017_25818\MdePkg  /Id:\udk2017_25818\MdePkg\Include  /Id:\udk2017_25818\MdePkg\Include\Ia32 d:\udk2017_25818\AppPkgSample\Hello\Hello.c
	"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\cl.exe" /Fod:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\.\AutoGen.obj /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Id:\udk2017_25818\AppPkgSample\Hello  /Id:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG  /Id:\udk2017_25818\MdePkg  /Id:\udk2017_25818\MdePkg\Include  /Id:\udk2017_25818\MdePkg\Include\Ia32 d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\AutoGen.c
	"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\lib.exe" /NOLOGO /LTCG /OUT:d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\Hello.lib @d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\object_files.lst
	"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\link.exe" /OUT:d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.dll /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:_ModuleEntryPoint /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data  @d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\static_library_files.lst
	"GenFw" -e UEFI_APPLICATION -o d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.efi d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.dll

    这个过程就是EFI编译的过程,我们来分析每一步的意义,每一个命令接收了什么东西,产出了什么东西,都要搞清楚。

    第一步:命令"cl.exe",输入:Hello.c,输出:Hello.obj. 主要参数:/Fo 生成obj文件,/c 只编译不链接,/I 设定搜索目录。如下:

"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\cl.exe" /Fod:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\.\Hello.obj /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Id:\udk2017_25818\AppPkgSample\Hello  /Id:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG  /Id:\udk2017_25818\MdePkg  /Id:\udk2017_25818\MdePkg\Include  /Id:\udk2017_25818\MdePkg\Include\Ia32 d:\udk2017_25818\AppPkgSample\Hello\Hello.c

    第二步:命令"cl.exe",输入:AutoGen.c,输出:AutoGen.obj ,如下:

	"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\cl.exe" /Fod:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\.\AutoGen.obj /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Id:\udk2017_25818\AppPkgSample\Hello  /Id:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG  /Id:\udk2017_25818\MdePkg  /Id:\udk2017_25818\MdePkg\Include  /Id:\udk2017_25818\MdePkg\Include\Ia32 d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\AutoGen.c

    第三步:命令"lib.exe",输入:Hello.obj&AutoGen (见objobject_files.lst),输出:Hello.lib。如下:

"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\lib.exe" /NOLOGO /LTCG /OUT:d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\Hello.lib @d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\object_files.lst

    其中,object_files.lst内容如下,可见用到了第一步的Hello.obj和第二步的AutoGen.obj:

d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/AppPkgSample/Hello/Hello/OUTPUT/Hello.obj
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/AppPkgSample/Hello/Hello/OUTPUT/AutoGen.obj

    第四步:命令"link.exe",输入:“static_library_files.lst”里面的lib文件,输出:Hello.dll。如下:

"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\link.exe" /OUT:d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.dll /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:_ModuleEntryPoint /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data  @d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\static_library_files.lst

其中,static_library_files.lst内容如下,可见用到了第三步生成的Hello.lib:

d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/BaseMemoryLib.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/BasePcdLibNull/BasePcdLibNull/OUTPUT/BasePcdLibNull.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/BaseLib/BaseLib/OUTPUT/BaseLib.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull/OUTPUT/BaseDebugLibNull.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib/OUTPUT/UefiBootServicesTableLib.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint/OUTPUT/UefiApplicationEntryPoint.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/AppPkgSample/Hello/Hello/OUTPUT/Hello.lib
    第五步:命令"GenFw",输入:Hello.dll,输出:Hello.efi。如下:
"GenFw" -e UEFI_APPLICATION -o d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.efi d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.dll
在Linux内核编译过程中加入对EFI(Extensible Firmware Interface)的支持,以便生成适用于UEFI启动的.efi文件,一般涉及以下步骤: 1. **准备工作**: - 安装必要的工具:你需要安装cross-compilation工具链,如`binutils-arm-none-eabi`(针对ARM架构),或者`gcc-aarch64-linux-gnu`(对于AARCH64等其他架构)。 - 获取Linux内核源码:从官方仓库下载最新版本的Linux内核源码,并解压到合适的位置。 2. **配置内核**: - 进入内核源码目录,运行`make menuconfig`打开配置界面,寻找“x86_64”或相应架构的选项,然后激活"UEFI Support"和"Load Linux from EFI System Partition"(从ESP加载)等选项。 - 根据需求选择其他配置项,例如硬件支持、网络堆栈等。 3. **编译内核**: - 使用`make x86_64-eatmydata_defconfig`(或其他对应架构的配置名)快速创建一个基本配置,然后继续使用`make defconfig`手动配置。 - 使用`make prepare`编译预处理文件,接下来执行`make`或`make modules`构建内核模块。 - 最后,运行`make efi_image`来生成.efi文件。 4. **验证和安装**: - 检查`vmlinuz.efi`和`System/Library/Code Signing/RootCertificates.pem`等文件是否存在,确认无误后,将它们复制到合适的UEFI ESP(EFI System Partition)路径下。 - 如果你的主板支持,可以在UEFI BIOS设置中修改启动顺序,让系统优先从ESP加载。 ```注意:具体的编译步骤可能会因内核版本和目标平台的不同而有所差异。```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值