1. 项目概述
最近在折腾Jetson AGX Orin开发板时,发现开机时显示的英伟达默认Logo略显单调。作为一个喜欢个性化设备的开发者,我决定研究下如何更换这个开机Logo。本以为是个简单的图片替换操作,没想到实际过程中踩了不少坑,特别是发现需要重新编译UEFI固件才能实现这个需求。本文将详细记录整个操作过程,包括环境准备、源码获取、图片处理、编译调试等关键步骤,以及过程中遇到的各种报错和解决方案。
2. 环境准备与工具安装
2.1 宿主机环境配置
首先需要准备一台Ubuntu 22.04的宿主机(物理机或虚拟机均可)。我使用的是Ubuntu 22.04 LTS虚拟机,配置如下:
- 内存:建议至少8GB
- 磁盘空间:至少50GB可用空间
- 网络:稳定的互联网连接(编译过程需要下载大量依赖)
注意:虽然可以在Jetson设备本身上进行编译,但由于编译过程资源消耗较大,建议使用性能更强的x86主机进行交叉编译。
2.2 Docker安装与配置
由于UEFI固件编译环境依赖较多,使用Docker容器可以避免污染主机环境。安装Docker的命令如下:
bash复制sudo apt update
sudo apt install docker.io
sudo usermod -a -G docker ${USER}
安装完成后需要重新登录使组权限生效。验证Docker是否安装成功:
bash复制docker run hello-world
2.3 编译环境变量配置
为了简化后续操作,我们需要设置一些环境变量:
bash复制export EDK2_DEV_IMAGE="ghcr.io/tianocore/containers/ubuntu-22-dev:latest"
export EDK2_USER_ARGS="-v \"${HOME}\":\"${HOME}\" -e EDK2_DOCKER_USER_HOME=\"${HOME}\""
export EDK2_BUILD_ROOT="/build"
export EDK2_BUILDROOT_ARGS="-v \"${EDK2_BUILD_ROOT}\":\"${EDK2_BUILD_ROOT}\""
alias edk2_docker="docker run -it --rm -w \"$(pwd)\" ${EDK2_BUILDROOT_ARGS} ${EDK2_USER_ARGS} \"${EDK2_DEV_IMAGE}\""
这些变量定义了:
- 使用的Docker镜像(官方提供的UEFI开发镜像)
- 挂载的目录(将主机目录映射到容器内)
- 简化后的docker运行命令别名
验证配置是否生效:
bash复制edk2_docker echo hello
3. 获取UEFI源码
3.1 创建工作目录
首先创建编译工作目录并设置权限:
bash复制sudo mkdir -p /build
sudo chown -R ${USER}:${USER} /build
cd /build
3.2 初始化edkrepo配置
edkrepo是NVIDIA用于管理UEFI源码的工具,需要先初始化配置:
bash复制edk2_docker init_edkrepo_conf
edk2_docker edkrepo manifest-repos add nvidia https://github.com/NVIDIA/edk2-edkrepo-manifest.git main nvidia
3.3 克隆源码仓库
根据你的Jetson AGX Orin的固件版本选择对应的tag。我使用的是r36.4.3版本:
bash复制edk2_docker edkrepo clone nvidia-uefi-r36.4.3 NVIDIA-Platforms r36.4.3
提示:如果遇到网络问题导致克隆失败,可以尝试强制使用HTTP/1.1协议:
bash复制git config --global http.version HTTP/1.1 edk2_docker git config --global http.version HTTP/1.1
4. 准备自定义Logo图片
4.1 图片规格要求
UEFI固件支持的Logo图片有特定要求:
- 格式:BMP
- 颜色:灰度(8位)
- 分辨率:需要准备三种尺寸
- 640x480
- 1280x720
- 1920x1080
4.2 图片转换处理
假设你有一张名为mylogo.png的自定义图片,使用ImageMagick进行转换:
bash复制cd /build/nvidia-uefi-r36.4.3
convert mylogo.png -resize 640x480 -background white -gravity center -extent 640x480 -strip BMP3:nvidiagray480.bmp
convert mylogo.png -resize 1280x720 -background white -gravity center -extent 1280x720 -strip BMP3:nvidiagray720.bmp
convert mylogo.png -resize 1920x1080 -background white -gravity center -extent 1920x1080 -strip BMP3:nvidiagray1080.bmp
转换参数说明:
-resize:调整图片到指定尺寸-background white:填充背景为白色(确保非标准比例图片也能正确显示)-gravity center:图片居中-extent:扩展画布到指定尺寸-strip:移除不必要的元数据BMP3:指定输出为BMP格式
4.3 替换默认Logo
将生成的BMP文件复制到UEFI源码的Assets目录:
bash复制cp nvidiagray480.bmp edk2-nvidia/Silicon/NVIDIA/Assets/
cp nvidiagray720.bmp edk2-nvidia/Silicon/NVIDIA/Assets/
cp nvidiagray1080.bmp edk2-nvidia/Silicon/NVIDIA/Assets/
5. 编译UEFI固件
5.1 开始编译
进入源码目录执行编译脚本:
bash复制edk2_docker bash -lc "cd $(pwd) && bash edk2-nvidia/Platform/NVIDIA/Jetson/build.sh"
5.2 常见编译错误及解决
在实际编译过程中,可能会遇到以下问题:
问题1:venv/bin/activate路径错误
错误信息:
code复制edk2-nvidia/Silicon/NVIDIA/scripts/prepare_stuart.sh: line 29: venv/bin/activate: No such file or directory
解决方案:
bash复制ln -sfn local/bin venv/bin
问题2:缺少kconfiglib模块
错误信息:
code复制ModuleNotFoundError: No module named 'kconfiglib'
解决方案:
bash复制edk2_docker bash -lc '
cd '"$(pwd)"' &&
if [ -f venv/bin/activate ]; then
. venv/bin/activate
else
. venv/local/bin/activate
fi &&
python -m pip install --upgrade pip &&
python -m pip install kconfiglib==14.1.0 &&
python -c "import kconfiglib; print(kconfiglib.__file__)" &&
bash edk2-nvidia/Platform/NVIDIA/Jetson/build.sh
'
问题3:Python路径问题
错误信息:
code复制ImportError: bad magic number in 'kconfiglib': b'\x03\xf3\r\n'
解决方案:
bash复制edk2_docker bash -lc '
cd '"$(pwd)"' &&
unset PYTHONNOUSERSITE &&
export PYTHONPATH="$HOME/.local/lib/python3.10/site-packages${PYTHONPATH:+:$PYTHONPATH}" &&
/opt/venv/bin/python3 -c "import sys, kconfiglib; print(sys.executable); print(kconfiglib.__file__)" &&
bash edk2-nvidia/Platform/NVIDIA/Jetson/build.sh
'
6. 生成固件与烧录
6.1 获取编译生成的固件
成功编译后,生成的固件位于:
code复制/build/nvidia-uefi-r36.4.3/images/uefi_Jetson_RELEASE.bin
6.2 替换SDK中的固件
将生成的固件替换到你的Jetson SDK中的bootloader目录:
bash复制cp /build/nvidia-uefi-r36.4.3/images/uefi_Jetson_RELEASE.bin /path/to/sdk/bootloader/uefi_jetson.bin
6.3 烧录固件
使用NVIDIA提供的烧录工具进行烧录:
bash复制cd /path/to/sdk
sudo ./flash.sh jetson-agx-orin-devkit mmcblk0p1
7. 验证与调试
7.1 验证新Logo
烧录完成后重启设备,应该能看到自定义的开机Logo。如果出现黑屏,可能是:
- 图片格式不正确(必须为8位灰度BMP)
- 图片尺寸不匹配
- 图片命名错误(必须替换所有三个分辨率的图片)
7.2 调试技巧
如果遇到问题,可以:
- 检查编译日志中的警告和错误
- 尝试使用更简单的图片(如纯色背景)
- 确保所有步骤都正确执行,特别是图片转换和路径设置
8. 总结与经验分享
整个替换过程比预想的要复杂,主要难点在于:
- 需要完整的UEFI编译环境
- 图片格式有严格要求
- 编译过程中可能遇到各种依赖问题
几个关键经验:
- 图片转换时务必使用正确的参数,特别是
-strip BMP3选项 - 编译环境最好使用干净的Ubuntu 22.04系统
- 遇到问题时,仔细阅读错误信息,大部分问题都有解决方案
最后,虽然这个过程有些复杂,但成功替换开机Logo后的成就感还是很值得的。这个技术也可以用于企业定制化设备,显示公司Logo等场景。
