飞腾D2000 UEFI编译与固件打包全流程实战解析
2026/9/23 7:41:36 网站建设 项目流程

做固件的人都知道,飞腾D2000这套平台跟x86那套玩法完全是两码事。拿到板卡第一件事往往就是对着默认固件发愁:版本太老、想调内存参数、想换启动Logo、想把自己的驱动编进UEFI里,甚至只是想让串口日志更全一点。网上关于D2000 UEFI编译的资料零零散散,环境怎么搭、命令怎么跑、编出来的fd文件跟最终烧录的BIOS镜像到底是什么关系,坑多得离谱。我前后在D2000平台上折腾了好几轮,从环境搭建到编出可刷镜像,每一步都踩过坑,这次把整套流程和排查思路完整写出来,算是给自己做个记录,也给后面接手的人省点时间。

这篇文章适合手里有D2000开发板或整机、需要定制固件的开发者,也适合刚接触ARM服务器平台、想搞明白UEFI编译和固件打包之间关系的人。文章里不会出现什么高深的理论,全是实际跑过的命令、路径、报错和解决办法。为了说清楚编译产物和最终BIOS镜像的关系,我会先从D2000固件的组成讲起,这部分搞不明白,后面打包环节一定会出问题。

1. 先弄清D2000固件里到底装了什么,才不会把“UEFI编译”和“BIOS打包”混为一谈

1.1 D2000的“BIOS”不是一个文件,而是一组镜像的合体

很多人第一次接触D2000固件,会下意识地认为:UEFI源码编译完,生成一个fd文件,那就是BIOS了,直接烧进去就行。这个理解错得非常离谱。D2000板卡上有一颗SPI NOR Flash,容量通常从16MB到64MB不等,里面装的是好几个不同功用的镜像,UEFI主固件只是其中之一。

我这边以常见的32MB SPI Flash布局为例,拆开看典型分区:

分区起始偏移(十六进制)大小内容说明
BootRom保留区0x000000001MB芯片BootROM引导参数、FIP等,由厂商出厂固化
UEFI主镜像0x00100000约20MBUEFI Award/EDK2编译产出的FD镜像,含PEI、DXE、BDS等
UEFI变量区0x01F0000064KB ~ 256KB存BootOrder、Boot####、SecureBoot密钥、平台配置等
BMC固件(部分服务器板卡)0x01F400008MB左右带外管理控制器固件,D2000部分开发板没有
厂商配置区0x01C000001MBMAC地址、序列号、板级设置、Logo等

注意,这张表里的偏移是我实际工程里的一个参考值,不同板卡差异很大,尤其是变量区的位置和大小。这个偏移跟芯片内部BootROM的硬编码有关,BootROM上电后会从固定的地址去加载下一级引导代码,所以打包的时候偏移一旦出错,烧进去板子直接砖,没有任何协商余地。

1.2 源码编译真正产出的是什么

在EDK2工程里,编译命令执行完之后,你会得到一个或多个FD文件,比如D2000.fd。FD是一个完整的固件卷(Firmware Device),里面包含了PEI阶段的固件文件系统(FFS)、DXE驱动、BDS启动管理器、UEFI Shell等一堆东西。EDK2的构建系统会在最后阶段用GenFv、GenFds这类工具把分散的模块封装成FV,再拼成FD。

但注意,这个FD通常不包括UEFI变量区的初始内容,也不包括BMC固件,更不包含厂商写在Flash其他位置的配置数据。它只是“BIOS”里体积最大、逻辑最核心的那一部分。所以一次完整的固件发布,需要把UEFI主镜像、变量区初始化模板、可能存在的BMC固件、Logo、DTB等按硬件设计好的Flash布局拼到同一个文件里,这一步叫打包,产出的最终文件才是能烧录的完整BIOS镜像。

很多新手卡在“编译成功了但烧进去不启动”这个状态,十有八九是把fd文件直接当完整BIOS烧了,把Flash里其他区域的数据冲掉了。所以说,动手编译之前先弄清楚整条链路,能省下大把救砖的时间。

1.3 从源码到烧录,完整流程分四步

以我在D2000平台上的实践来说,一次完整的固件定制要经历下面四个阶段:

  1. 源码准备:拿到对应板卡的UEFI BSP源码包,确认平台目录和默认配置。
  2. 交叉编译:在x86主机上用aarch64工具链编译出FD固件镜像。
  3. 镜像打包:用打包脚本把FD、变量区模板、DTB、Logo等按Flash布局拼成最终烧录镜像。
  4. 刷写验证:通过UEFI Shell、BMC或SPI烧录器把镜像写入Flash,然后上电验证。

这四个阶段各有各的坑,下面按顺序逐个展开。

2. 编译环境搭建:工具链和依赖版本比想象中更挑

2.1 宿主系统的选择

D2000的UEFI源码是基于TianoCore EDK2的,通常在x86_64的Linux主机上做交叉编译就行。操作系统方面,我试过Ubuntu 18.04和20.04,都是可以跑通的。20.04默认的GCC版本是9.x,但很多老一批的D2000 BSP包默认用的是GCC5工具链配置,编到一半会因为GCC版本太新出现各种奇怪的警告和报错。比较稳妥的做法是用Ubuntu 18.04配合GCC 7.5,或者直接用20.04,但手动把工具链切到aarch64-linux-gnu-gcc-7。

如果你拿到的是新版本的BSP包,官方一般会写清楚推荐的GCC版本,优先遵循官方建议。我这边用的比较多的是Ubuntu 20.04 + GCC 7.5交叉工具链的组合,兼容性最好,踩坑最少。

2.2 安装基础依赖包

先刷新索引,然后把编译过程中会用到的工具一次性装齐:

sudo apt update sudo apt install -y build-essential git uuid-dev nasm python3 python3-distutils \ acpica-tools iasl bison flex ccache

这些包的作用不一样,nasm和iasl是给ACPI表和x86汇编用的,在ARM平台上一般不直接参与D2000的编译,但EDK2的全局构建系统有可能在某些环节调用它们,缺了会直接中断。uuid-dev是用来生成GUID的工具库,EDK2里所有模块的GUID处理都依赖它。

2.3 交叉编译工具链安装与验证

D2000是ARMv8架构,所以编译目标是aarch64:

sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu

如果官方BSP要求GCC 7,可以这样装:

sudo apt install -y gcc-7-aarch64-linux-gnu g++-7-aarch64-linux-gnu

装完之后确认工具链有效:

aarch64-linux-gnu-gcc --version

然后写一个最简单的C程序,交叉编译一下,确认环境没问题:

// hello.c #include <stdio.h> int main(void) { printf("hello d2000\n"); return 0; }
aarch64-linux-gnu-gcc -o hello hello.c file hello

如果file命令输出里出现了“ELF 64-bit LSB executable, ARM aarch64”,说明工具链工作正常。这一步千万别跳过,很多环境问题都是在这里提前暴露的。如果file输出是x86-64,说明gcc命令解析到了宿主系统的原生编译器上,需要检查PATH顺序或者用完整路径调用交叉编译器。

2.4 为什么我强烈建议你用虚拟机或容器

UEFI编译过程中会生成大量中间文件,Build目录轻松超过10GB,而且EDK2的构建系统对环境的依赖非常敏感,同一个工程在不同机器上编出来的行为可能不一样。我之前就遇到过因为宿主系统里装了一个特殊版本的Python库,导致build脚本执行到一半崩掉的情况,排查了很久才发现是系统环境的问题,重新搭一台干净环境很快就编过了。

所以动手之前,先准备一个快照或者独立的Docker容器,环境搞坏了直接回滚,不要在自己的主力开发机上硬刚。这个习惯在固件开发里特别值钱,因为你不知道哪次实验会把系统库改乱。

3. D2000 UEFI源码编译:从edksetup到生成FD文件

3.1 拿到源码后第一件事:检查平台目录结构

我用的D2000 UEFI BSP包是厂商提供的一个EDK2工程,解压之后目录结构大致是:

edk2/ ├── edksetup.sh ├── BaseTools/ ├── MdeModulePkg/ ├── MdePkg/ ├── ArmPkg/ ├── ArmPlatformPkg/ ├── Platform/ │ └── Phytium/ │ ├── D2000/ │ │ ├── D2000.dsc │ │ ├── D2000.fdf │ │ └── Library/ │ └── Common/ ├── Silicon/ │ └── Phytium/ │ └── FT2000/ └── ...

关键的三个文件分别是:

  • .dsc文件:平台描述文件,定义要编译哪些模块、使用什么PCD(平台配置数据库)策略。
  • .fdf文件:固件描述文件,定义固件的Flash布局、FD里包含哪些FV、各模块如何放置。
  • build.sh或README:厂商给的编译入口脚本。

打开D2000.dsc先看两个东西:PLATFORM_NAMETARGET_ARCHITECTURE。正常情况TARGET_ARCHITECTURE应该包含AARCH64。如果这里写的还是ARM,说明这个BSP是给32位ARM平台用的,跟D2000完全不搭,得换包。

3.2 source edksetup.sh之后发生了什么

进入UEFI源码根目录,第一步永远是:

source edksetup.sh

这个脚本会做两件事:设置EDK2的环境变量,把编译工具路径加入PATH;编译生成BaseTools底下的工具,比如GenFv、GenFds、VfrCompile这些。

如果之前没有编译过BaseTools,脚本运行时会自动编译。老版本EDK2这里有个坑:如果系统Python版本是3.x,但缺少distutils模块,脚本会直接报错。Ubuntu 20.04下可以提前执行:

sudo apt install -y python3-distutils

source edksetup.sh没有报错之后,再执行build命令才会进入正常流程。

3.3 修改编译配置:target.txt不能忽略

EDK2的默认配置文件在Conf/target.txt,这个文件控制着编译目标。打开后重点改这几项:

ACTIVE_PLATFORM = Platform/Phytium/D2000/D2000.dsc TARGET_ARCH = AARCH64 TOOL_CHAIN_CONF = Conf/tools_def.txt TOOL_CHAIN_TAG = GCC5 TARGET = RELEASE

TOOL_CHAIN_TAG是EDK2对交叉编译工具链的封装标签。GCC5在EDK2的tools_def.txt里定义好了aarch64交叉编译器的调用规则,它会根据CROSS_COMPILE环境变量去拼编译器路径。所以执行build之前通常还需要:

export CROSS_COMPILE=aarch64-linux-gnu-

如果你装了多个版本的交叉编译器,可以用绝对路径指定,比如:

export GCC5_AARCH64_PREFIX=/usr/bin/aarch64-linux-gnu-

注意,EDK2不同版本的变量名不太一样,有些版本用的是GCC5_AARCH64_PREFIX,有些则直接认CROSS_COMPILE。我这里习惯两个都设置上,防止遗漏。

TARGET建议第一次编译用RELEASE,原因后面单独讲。

3.4 执行编译:第一次编不过太正常了

配置改好后,执行:

build -n 16

-n 16是多线程编译参数,按你机器CPU核数来。EDK2的构建系统对多线程支持还可以,但我遇到过一些老的BSP包,用超过8线程编译会随机出现链接错误,这时候改成-n 4就能过。BSP包如果自带build.sh脚本,优先用脚本,脚本里通常会包含厂商调过的参数,比手动敲build命令稳得多。

第一次编译耗时取决于机器性能,通常在10到30分钟之间。等待的时候有一点可以留意:EDK2的编译输出日志信息量非常大,但绝大多数都不需要关注,只要没有红色的error:字样,就可以让它继续跑。

编完之后,产物在Build/目录下:

Build/PhytiumD2000/RELEASE_GCC5/ ├── FV/ │ ├── D2000.fd │ ├── D2000.fd.map │ └── FVMAIN.fv └── AARCH64/ ├── MdeModulePkg/ ├── ShellPkg/ └── ...

D2000.fd就是UEFI主镜像,但离可烧录还有一段距离,这个我下一节详细讲。

3.5 RELEASE和DEBUG怎么选,直接影响你的调试验体验

TARGET有两种常见值:RELEASEDEBUG

  • DEBUG:编译优化等级低,包含大量调试日志代码,生成的fd文件更大,启动速度慢,但串口会输出非常详细的模块加载信息。
  • RELEASE:优化等级高,裁剪掉调试日志,启动快,体积小,但出问题的时候只能靠POST码和少量串口信息判断。

我个人的建议是:第一次接触一块新板卡,先用RELEASE编一版,烧进去确认系统能正常起来。如果起不来,再切DEBUG版本,用串口日志定位。因为DEBUG版本的日志量太大了,对新手来说反而容易被淹没在无用信息里。等你能熟练看懂日志中自己关心的那几行之后,再切DEBUG也不迟。

4. 从FD到完整BIOS镜像:打包过程才是大量坑的源头

4.1 准备打包素材:不只是fd文件

打包这一步,中文资料里讲得最少,但恰恰是实际问题最多的地方。我最初也觉得,把D2000.fd直接丢给烧录工具不就完了吗?后来发现太天真了。

一个可烧录的完整BIOS镜像,在打包阶段至少需要准备这些素材:

  • UEFI主镜像D2000.fd,这个刚刚编译出来的。
  • 变量区初始化模板VarStore.fd或类似的二进制文件。它覆盖了Flash的NVRAM区域,里面会写入默认的BootOrder、Timeout等。这个文件通常由BSP包附带,不用自己编译。
  • 板级设备树*.dtb。D2000 UEFI引导U-Boot或者Linux的时候会用到设备树,但UEFI阶段的版本也可能需要。
  • Logo图片:可选的启动Logo,BMP格式最稳妥。
  • 厂商配置块:包含MAC地址、序列号、板卡型号等,这部分通常不用动。

把这些素材按Flash布局拼起来,才是完整镜像。

4.2 打包脚本的核心逻辑:偏移对齐和填充

厂商BSP包一般会提供一个GenFirmware.shpack_linux.sh之类的打包脚本,脚本的核心内容本质上就是多次调用dd命令,往一个大镜像文件里按偏移写入各分区的内容。如果你的BSP没有脚本,那需要手动做这件事。

写一个参考脚本,注意这里的偏移是示例值,必须按你实际板卡的原理图或BSP默认配置来:

#!/bin/bash # D2000 打包参考脚本(32MB SPI Flash) set -e BLOCK_SIZE=4096 FLASH_SIZE=0x2000000 # 32MB UEFI_FD=Build/PhytiumD2000/RELEASE_GCC5/FV/D2000.fd VAR_STORE=VarStore.fd DTB_FILE=board.dtb OUT_IMAGE=bios_full.bin # 1. 生成全0填充的底图 dd if=/dev/zero of=$OUT_IMAGE bs=$BLOCK_SIZE \ count=$((FLASH_SIZE / BLOCK_SIZE)) # 2. 写入UEFI主镜像,起始偏移0x00100000 dd if=$UEFI_FD of=$OUT_IMAGE bs=$BLOCK_SIZE \ seek=$((0x00100000 / BLOCK_SIZE)) conv=notrunc # 3. 写入设备树,起始偏移0x01C00000 dd if=$DTB_FILE of=$OUT_IMAGE bs=$BLOCK_SIZE \ seek=$((0x01C00000 / BLOCK_SIZE)) conv=notrunc # 4. 写入UEFI变量区模板,起始偏移0x01F00000 dd if=$VAR_STORE of=$OUT_IMAGE bs=$BLOCK_SIZE \ seek=$((0x01F00000 / BLOCK_SIZE)) conv=notrunc # 5. 打印输出文件大小确认 ls -lh $OUT_IMAGE

seek的单位是块,所以要除以块大小。如果你改过BLOCK_SIZE,所有计算都要保持一致。conv=notrunc很关键,表示只覆盖对应偏移位置的数据,不清空文件其他部分。

4.3 偏移错误导致的典型故障

这块我必须多说几句,因为它是打包阶段最隐蔽的坑。如果你把UEFI FD写到了错误的偏移,或者变量区覆盖了UEFI主镜像的一部分,表现出来的故障非常迷惑:

  • 板子完全无输出,电流表显示上电了但串口一个字符都不出。
  • 能进UEFI,但保存设置重启后所有配置都丢失,每次都是默认值。
  • 启动到一半卡死,偶尔又能过去,完全随机。
  • 网络启动选项异常,PXE菜单乱码。

这些情况不用怀疑,大概率都是Flash布局错位。排查方法就是把你的完整镜像用hexdump之类工具导出来,对照原理图上标注的偏移,确认每一个分区头部的magic number是否出现在正确位置。做固件这行的都知道一个原则:烧录之前double check偏移,是比任何技术都重要的基本功。

4.4 确认产物完整性:烧录前做一个最终检查

打包脚本执行完之后,不要急着烧,先做三个检查:

第一,检查镜像文件大小。32MB的Flash,最终镜像应该精确等于0x2000000字节,多一个字节少一个字节都说明脚本有问题。

stat -c %s bios_full.bin

第二,检查关键偏移处是否有预料中的数据特征。比如UEFI FD的头部通常有_FVH标记,UEFI变量区头部有NVAR之类的结构特征(不同EDK2版本可能不同)。用xxd查看即可:

xxd -l 256 -s 0x00100000 bios_full.bin xxd -l 256 -s 0x01F00000 bios_full.bin

第三,对比一下打包前后,FD文件在镜像里对应区间的内容是否完全一致。使用cmp按偏移比对:

# 从完整镜像中取出UEFI区域,与原始FD比较 dd if=bios_full.bin of=extract_uefi.bin bs=4096 \ skip=$((0x00100000 / 4096)) count=$((0x01400000 / 4096)) cmp D2000.fd extract_uefi.bin

如果cmp没有输出,说明UEFI主镜像在打包过程中没有被破坏。这三个步骤做完,完整镜像才算可以进入刷写阶段。

5. 刷写进板卡:三种常用方式与验证手段

5.1 刷写前第一件事:备份原始固件

不管用哪种方式刷写,动手之前必须先把当前板卡里的固件完整备份出来。万一刷挂了,至少还有原始固件可以用来恢复。备份方法取决于你的板卡支持哪种接口:在UEFI Shell里用fpt命令、在BMC里用固件升级页面的导出功能、或者直接用SPI烧录器读取整颗Flash都行。

备份的完整镜像一定要留好,并且标注好来源板卡和备份日期。我见过有人备份了但没有做校验,等到要用的时候才发现备份文件损坏,那种绝望感不想经历第二次。

5.2 在UEFI Shell中刷写:最常用的方式

D2000板卡上电后,通常会进入UEFI引导界面。如果你的板卡支持UEFI Shell,可以把完整镜像放到FAT32格式的U盘里,插到板卡上,进入Shell后执行刷写命令。

不同板卡的刷写命令不一样,有些板卡自带一个Flash.nsh脚本放到U盘里,在Shell里执行:

# 在UEFI Shell中执行 # 假设文件系统映射为 FS0: FS0: flash.nsh bios_full.bin

如果板卡没有现成脚本,有些UEFI固件会内置fpt命令,也就是Intel的Flash Programming Tool,D2000平台如果有对应的efi版本,可以这样:

fpt -f bios_full.bin -D

注意,在UEFI Shell下刷写时,刷写过程中绝对不能断电,否则Flash里的内容处于半写状态,很容易变砖。刷写完成后不要直接强制断电,要等固件自己完成收尾工作,按提示重启板卡。

5.3 用BMC带外刷写:服务器板卡常见的路子

如果你的D2000板卡带BMC,那么刷写路径通常更安全。BMC一般会提供一个Web管理页面,里面有一个固件升级/BIOS升级的功能入口,上传完整镜像,BMC会负责把镜像写入Flash。这种方式的优势在于即使系统OS挂了,只要BMC还在,就还能救回来。

尤其在企业级设备上,BMC刷写是首选方案,因为带外通道完全独立于CPU,刷写过程不依赖UEFI状态。

5.4 SPI烧录器:最后一道救命稻草

如果UEFI已经刷挂了,Shell进不去,BMC也没有,那只能用SPI烧录器直接在线烧录Flash芯片。市面上常见的USB SPI烧录器(比如CH341A)配上一根测试夹或者插座,就能直接读写Flash。

操作步骤简述如下:

  1. 断开板卡电源,拆出Flash芯片或找到板载烧录座。
  2. 用烧录器软件读取芯片型号,确认容量。
  3. 备份当前内容(如果还能读出来)。
  4. 加载完整镜像,执行擦除和写入。
  5. 写入完成后校验。
  6. 断电,装回芯片,上电。

这个方式虽然土,但却是救砖成功率最高的方法。需要注意,D2000板卡的Flash芯片封装可能比较小,测试夹夹不好容易接触不良。另外,烧录器软件里“芯片类型”必须选对,选错了轻则读取内容不对,重则可能把芯片锁死。

5.5 刷写后如何判断固件真的起来了

刷写完成后,上电观察这几个信号,基本能判断是否成功:

  • 串口日志:D2000 UEFI启动过程中,串口(UART0,波特率通常115200)会输出一段日志。只要能看到UEFI v2.7Press DEL to enter setup之类的字样,说明UEFI主镜像已经被正确加载。
  • 显示输出:接上显示器或显卡,看是否能出现UEFI Logo或HII设置界面。
  • POST码:如果板卡上有数码管或POST卡接口,可以看到两位十六进制的POST码,走到0x00或特定数值说明启动流程走完。
  • 进入系统:UEFI引导U盘或NVMe上的系统,能进入GRUB菜单或Shell,说明整个引导链路都通了。

如果上面任何一项没反应,不要慌,按后面一节给的排查顺序逐个确认。

6. 从我自己踩过的坑里提炼的检查清单

第三个大坑:编译环境问题。有一个典型的项目报错出现在我第一次编老版本BSP时。报错信息是:

/usr/bin/ld: cannot find crt1.o: No such file or directory collect2: error: ld returned 1 exit status

这个报错看着像链接器出问题,实际上是因为系统缺少32位库,或者是交叉编译器的sysroot路径不对。我当时的解决办法是确认aarch64-linux-gnu-gcc能被正确调用,并且安装了libc6-dev-arm64-cross。如果你是Ubuntu系统,可以这样装:

sudo apt install -y libc6-dev-arm64-cross

第二个常见的坑是build命令执行时报:

Unknown tool chain tag 'GCC5'

这说明tools_def.txt里没有匹配的配置,通常是因为Conf/target.txt里的TOOL_CHAIN_CONF路径写错,或者BSP不支持当前EDK2版本。这时候优先查看BSP的README,确认它依赖的是哪个EDK2基线的版本。不要自己乱改tools_def,很容易把整个编译环境搞乱。

6.2 启动阶段遇到的黑屏卡死,怎么定位是哪一层的问题

刷完固件上电黑屏,先按以下顺序排查:

第一步,看串口有没有输出。如果没有输出,考虑BootROM没有加载到UEFI,多半是镜像偏移错了,或者Flash芯片本身没有正确识别。第二步,串口有输出但停在某一行不动,通常是某个DXE驱动加载失败,或者变量区配置导致驱动初始化异常。这时候用DEBUG版本固件重新编译一遍,日志会详细很多。第三步,能进UEFI但进不了系统,那是引导项的问题,跟固件本身关系不大。第四步,如果UEFI和系统都能进,但过一段时间随机死机,考虑内存参数、散热或供电问题,固件层面能调的只有内存相关PCD配置。

黑屏类问题,我见过最多的还是打包偏移错误。每次遇到黑屏,先做两件事:确认串口有没有电,确认是否用备份固件能正常启动。如果备份固件正常而新固件黑屏,那就是新固件本身的问题,按上面四步往下查。

6.3 引导系统时提示“磁盘布局不受UEFI支持”怎么办

这个报错实际上不是D2000特有的,Windows安装器在检测磁盘分区表时会报类似的提示,意思是当前磁盘是MBR分区或者没有EFI系统分区,与UEFI固件的引导方式不匹配。D2000的UEFI固件是纯ARM UEFI实现,不支持传统BIOS/CSM兼容模式,所以引导介质必须是GPT分区表,并且存在一个FAT格式的ESP分区。

如果你是要在D2000上装Linux,制作启动U盘时注意:

  • 用GPT分区表,不要用MBR。
  • 必须有一个EFI System Partition,文件系统格式为FAT16或FAT32。
  • 引导文件必须放在ESP分区下,GRUB镜像或者UEFI Shell文件按标准路径放置。

如果没有ESP分区,固件会认为这个设备不可引导,表现就是启动菜单里看不到U盘或者系统盘。这不是固件Bug,而是磁盘布局不符合UEFI规范。

6.4 刷写回退方案:永远保留一个“安全版本”

固件调试过程本质上是反复试错,回退能力一定要提前准备好。我的习惯是:

  1. 每拿到一块新板卡,立即备份一份出厂固件镜像,存到多个位置。
  2. 每次要烧新固件之前,把当前正常可用的版本再备份一次。
  3. 所有自定义镜像的文件名都带上日期、版本号和修改内容,比如:
bios_full_d2000_v0.3_20250115_增加立创串口补丁.bin

这样即使过了几个月,翻目录也能知道这个镜像当时改了什么东西。不要嫌麻烦,你永远不知道几个月后那个“当时随手改了一点”的镜像会是什么状态。

6.5 我特别想提醒的一个心态问题

固件开发跟普通软件开发最大的区别在于,犯错代价高,排查链路长。普通软件挂了,重启进程就行;固件挂了,可能得动用SPI烧录器。所以整个流程中最重要的习惯就是:动手之前想清楚,动手之后慢一点。每执行一个可能影响Flash内容的操作前,都问自己一句:备份了吗?偏移对吗?真有必要刷吗?

这个习惯帮我至少挽救了四五块板卡的命,也让我少走了很多冤枉路。

最后分享一个我自己总结的小技巧:在UEFI工程里改完PCD配置重新编译之后,如果改动量很小,我通常不会立刻打包整个镜像,而是先在DEBUG版本下编一次,用串口日志确认模块加载顺序没有异常,再返回RELEASE版本打包。这样虽然多花了几分钟编译时间,但能省下反复刷机救砖的几小时。D2000平台固件开发这条路,耐心比聪明值钱多了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询