当前位置: 首页 > news >正文

【UEFI实战】BIOS编译过程中报错“无法解析的外部符号memcpy”

环境

Win10系统。使用VS2022 Community进行编译。

现象

编译报错,报错信息如下:

NMAKE : fatal error U1077: "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\bin\Hostx86\x64\link.exe" /OUT:E:\Gitee\edk2-beni\edk2\Build\OvmfX64\DEBUG_VS2022\X64\ShellPkg\Application\Shell\Shell\DEBUG\Shell.dll.wtemp /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:_ModuleEntryPoint /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /ALIGN:4096 /DLL /WX /IGNORE:4210 /WHOLEARCHIVE  @E:\Gitee\edk2-beni\edk2\Build\OvmfX64\DEBUG_VS2022\X64\ShellPkg\Application\Shell\Shell\OUTPUT\static_library_files.lst: ش롰0x460

定位

从最后的报错信息看不出来原因,但是再往上翻可以看到:

UefiShellDebug1CommandsLib.lib(BufferImage.obj) : error LNK2001: 无法解析的外部符号 memcpy

UefiShellDebug1CommandsLib这个模块中并没有使用memcpy,所以初看这个报错会让人摸不着头脑,相似的还有memset的报错。

原因在于/LTCG (Link-time code generation) | Microsoft Learn这个功能,在edk2\Conf\tools_def.txt中有相关的配置:

# Linker warning 4210 is disabled globally, because it checks if static initializers are present and the VCRuntime is
# linked. We do not link the VCRuntime (except for HOST_APPLICATIONs) so this warning can be generated erroneously
# whenever there are static initializers, because we will always fail the VCRuntime linking checkDEBUG_VS2022_X64_DLINK_FLAGS  = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /ALIGN:4096 /DLL /WX /IGNORE:4210
RELEASE_VS2022_X64_DLINK_FLAGS  = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data /ALIGN:4096 /DLL /WX /IGNORE:4210
NOOPT_VS2022_X64_DLINK_FLAGS    = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /ALIGN:4096 /DLL /WX /IGNORE:4210

这是VS提供的一种优化代码的手段,但是如果存在这个配置,VS就可能对某些代码进行优化,最明显的就是那些数据搬运或清零的代码,所以就会使用到memcpymemset

在关于/LTCG的说明中可以通过/GL来关闭:

OFF
(可选)禁用链接时代码生成。 链接器会将使用 /GL 编译的所有模块都视为在没有该选项的情况下进行编译,并且任何 MSIL 模块都会导致链接失败。

不过实际上并没有效果,为了解决这个问题,可以通过另外的一个配置/Od,它用来关闭程序中的所有优化并加快编译速度,没有了优化也就没有了修改成memcpy这样的操作。

解决

可以通过在dsc(不建议放在这里,因为它会导致全局的无优化)或者inf中增加BuildOptions来添加该配置:

[BuildOptions]MSFT:*_*_*_CC_FLAGS = /Od

在前面提到的edk2\Conf\tools_def.txt文件中其实也有类似的配置:

NOOPT_VS2022_X64_CC_FLAGS       = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od /volatileMetadata-

但它只针对特定的编译过程,这里的NOOPT表示的应该就是“No Optimization",没有优化。

后续1

如果想要使用优化,理论上应该有让EDK模块包含外部库的方式,但是目前没有找到。尝试在安装VS2022的时候包含不同的组件(事实上在C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\lib\x64中已经有相关的库了),不过并没有实际的效果。

这个后续还需要研究。

后续2

另外在我们自己写BIOS代码的时候需要注意以下的一些情况,以避免上述的报错:

  1. 不要将struct等大块的内存作为传参,或者赋值。
  2. 不要使用大块的数组,且使用类似如下的初始化:
UINT8 Array[100] = {0};
http://www.xdnf.cn/news/577495.html

相关文章:

  • 七: NumPy的使用
  • vue+srpingboot实现多文件导出
  • Unity中GPU Instancing使用整理
  • Python训练Day30
  • 第3周作业-1层隐藏层的神经网络分类二维数据
  • MQTT报文介绍
  • Linux内存分页管理详解
  • Jsoup解析商品信息具体怎么写?
  • 阿里发布扩散模型Wan VACE,全面支持生图、生视频、图像编辑,适配低显存~
  • FreeCAD傻瓜教程-外螺纹的绘制,利用两个实体进行布尔运算来实现
  • 《P1433 吃奶酪》
  • MCU开发学习记录19* - CAN学习与实践(HAL库) - 定时传输、触发传输和请求传输(轮询与中断实现) -STM32CubeMX
  • Python 代码缩进与结构化编程:从基础到风格规范
  • Robotaxi新消息密集释放,量产元年来临谁在领跑?
  • [Java恶补day2] 49. 字母异位词分组
  • 【SW】从3D模型导出dxf图纸
  • 【算法专题十五】BFS解决最短路问题
  • 04_Prometheus监控docker容器(4)
  • 智慧社区新防线:华奥系AI技术如何让夏季安防“零隐患”
  • 如何在JavaScript中将数值转换为字符串并赋值给数组——以RuoYi-Vue项目为例
  • Redis Cluster动态扩容:架构原理与核心机制解析
  • 航电系统之航点跟踪系统篇
  • C++(27): 标准库 <iterator>
  • 逆向音乐APP:Python爬虫获取音乐榜单 (1)
  • Podman(Pod Manager)简介
  • 嵌入式STM32学习——串口USART 2.1(串口发送字符串和字符)
  • 应用分享 | 软件定义架构如何满足GNSS模拟测试的开放性需求?
  • JDK9~17语法新特性全览:Java语言的持续进化
  • Python数据可视化高级实战之二——热力图绘制探究
  • C++ 输出流格式控制