这里保留一份完整的MakeFile文件用来做Shell或者其他类似EFI文件的生成。
由于GenFw是EDK2项目下挂的工具,因此EFI的制作,即便没有依赖EDK提供的系统表库,依然最好在EDK2项目下创建对应子项目,具体来说,在EDK2项目下挂包含两个主要操作:
1、在EDK2的子目录下建立文件夹
2、在EDK2的makefile之前进行source的环境变量配置
source ./edksetup.sh
其中.是edk2的根目录。
完成source后,可以依托编译、连接、GenFw的顺序进行efi文件的开发了
makefile的具体举例:
#######################################################################
## Shell项目的主要作用是在AARCH64这一特定环境上开发efi裸机程序 ##
#######################################################################
#######################################################################
## 生成步骤是: ##
## 1、gcc命令带参数生成o文件 ##
## 2、gcc命令带lds链接脚本生成obj文件、map文件 ##
## 3、GenFw命令进行PE头的格式转换 ##
## GenFw命令需要进行一次source ./Shell.sh来将GenFw工具加载到PATH中 ##
#######################################################################
#######################################################################
# 项目名称
ProjectName = Shell
# 库文件路径参数
LIBFLAGS = -I /edk2/MdePkg/Include/ -I /edk2/MdePkg/Include/X64/
# EFI的入口函数
EFIMain = EFI_Main
#######################################################################
# 编译器设置
CC = aarch64-linux-gnu-gcc
# 最终efi文件名
FinalTarget = ${ProjectName}.efi
# 目标可执行文件名
TARGET = ${ProjectName}.obj
# 生成的段描述map名称
Map = ${ProjectName}.map
# 链接脚本路径
LdsPath = ${CURDIR}/GccBase.lds
# map文件路径
MapPath = ${CURDIR}/${Map}
# 编译标志
CFLAGS = -Os -g -fshort-wchar -fno-builtin -Wall -fno-common -ffunction-sections -fdata-sections -mlittle-endian -fno-short-enums -funsigned-char -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -fno-stack-protector -ffreestanding -ffixed-x18 -mcmodel=small -fPIC
# 链接标志,注意这里依赖了GccBase.lds脚本以及将会生成一个.map的文件用来描述最终应用程序的
LDFLAGS = -nostdlib -Wl,--gc-sections -Wl,-e,${EFIMain},-Map,${MapPath} -z common-page-size=0x1000 -Os -g -fshort-wchar -fno-builtin -Wall -Wno-array-bounds -fno-common -ffunction-sections -fdata-sections -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -Wl,-plugin-opt=-fno-stack-protector -ffreestanding -ffixed-x18 -mcmodel=small -Wno-unused-but-set-variable -Wno-unused-const-variable -fPIC -Wl,--script=${LdsPath} -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 -Wno-error
# PE头文件工具设置
GENFW = GenFw
# PE头参数设置
MODULE_TYPE = UEFI_APPLICATION
# 自动获取当前目录下所有的 .c 文件
SRCS = $(wildcard *.c)
# 将 .c 后缀替换为 .o 后缀,生成目标文件列表
OBJS = $(SRCS:.c=.o)
# 最终EFI文件生成
${CURDIR}/$(FinalTarget): ${CURDIR}/$(TARGET)
-$(GENFW) -e $(MODULE_TYPE) $^ -o $@
# 默认目标:生成集中的可执行文件
# 依赖所有的 .o 文件
${CURDIR}/$(TARGET): ${CURDIR}/$(OBJS)
-$(CC) $(LDFLAGS) $^ -o $@
# 模式规则:如何从 .c 生成 .o
# $< 代表第一个依赖文件(即对应的 .c 文件)
# $@ 代表目标文件(即对应的 .o 文件)
${CURDIR}/$(OBJS): ${CURDIR}/${SRCS}
-$(CC) $(CFLAGS) -c $< -o $@
# 伪目标:清理编译生成的文件
.PHONY: clean
clean:
rm -f ${CURDIR}/$(OBJS) ${CURDIR}/$(TARGET) ${CURDIR}/$(FinalTarget)
# 伪目标:查看变量值(调试用)
.PHONY: info
info:
@echo "Sources: $(SRCS)"
@echo "Objects: $(OBJS)"
@echo "Target: $(TARGET)"
@echo "FinalTarget: $(FinalTarget)"这样跑出来的结果是:

这个makefile会将所有的c文件打包成一个${ProjectName}.efi