Jetson 启动 LOGO 无黑屏切换:从 Bootloader 到 APP 首屏的显示接力机制解析

发布时间:2026/7/10 3:13:45
Jetson 启动 LOGO 无黑屏切换:从 Bootloader 到 APP 首屏的显示接力机制解析 B站 嵌入式孙老师博主个人介绍博主书籍-京东购买链接*Yocto项目实战教程加博主微信进技术交流群jerrydevJetson 启动 LOGO 无黑屏切换从 Bootloader 到 APP 首屏的显示接力机制解析前言最近在分析 Jetson Thor 的 UEFI 启动显示配置时看到两个比较关键的选项SOC Display Hand-Off Mode Always SOC Display Hand-Off simplefb / efifb这个配置看起来只是和启动 LOGO 有关但它背后对应的是一个很典型的产品启动体验问题Jetson 从 Bootloader 阶段启动到 Linux再到 APP 首屏显示如何避免中间黑屏、闪屏这篇文章结合我的理解梳理一下 Jetson 启动显示的接力过程以及simplefb、efifb、simpledrm、DRM/KMS在这个过程中分别起什么作用。1. 启动显示的核心问题很多嵌入式 Linux 设备启动时显示流程可能是这样上电 ↓ Bootloader 显示 LOGO ↓ Linux Kernel 启动 ↓ 屏幕黑一下 ↓ 图形系统启动 ↓ APP 首屏显示用户看到的现象就是LOGO 消失 屏幕黑屏 画面闪烁 APP 起来后重新显示更理想的启动体验应该是上电 ↓ Bootloader 显示 LOGO ↓ Linux early display 接住画面 ↓ DRM/KMS 正式显示驱动接管 ↓ APP 首屏自然显示也就是说显示画面不是每个阶段重新开始而是一个阶段接一个阶段完成显示接力。2. Jetson 启动显示链路Jetson 的启动链路可以简化成BootROM ↓ MB1 / MB2 ↓ UEFI ↓ Linux Kernel ↓ rootfs ↓ APP如果只看显示相关部分可以简化为UEFI LOGO ↓ simplefb / efifb / simpledrm ↓ DRM / KMS ↓ Weston / Qt / APP更直观一点┌──────────────────────────────┐ │ Bootloader / UEFI │ │ 初始化显示硬件绘制 LOGO │ └───────────────┬──────────────┘ │ │ Display Hand-Off ↓ ┌──────────────────────────────┐ │ Linux Early Display │ │ simplefb / efifb / simpledrm │ │ 继续使用已有 framebuffer │ └───────────────┬──────────────┘ │ │ DRM/KMS 接管 ↓ ┌──────────────────────────────┐ │ Linux 正式显示驱动 │ │ 建立完整显示管线 │ └───────────────┬──────────────┘ ↓ ┌──────────────────────────────┐ │ 用户空间 APP │ │ Weston / Qt / 应用首屏 │ └──────────────────────────────┘这里要注意一点Display Hand-Off 严格来说主要发生在 UEFI 到 Linux early display 阶段。从 Linux Kernel 到 APP 首屏则是 DRM/KMS 和用户空间显示服务继续完成显示接力。所以这里说的“Bootloader 到 APP 首屏”指的是完整用户可见显示链路而不是 Bootloader 直接把 framebuffer 交给 APP。3. 什么是 Display Hand-OffDisplay Hand-Off 可以理解为Bootloader 把已经初始化好的显示现场交给 LinuxLinux 早期阶段继续使用它。在 UEFI 阶段系统通常已经完成了这些工作初始化显示控制器 初始化 HDMI / DP / eDP 分配 framebuffer 绘制启动 LOGO 启动显示扫描输出如果 Linux 启动后立刻重置显示硬件就容易出现黑屏或闪屏。Display Hand-Off 的思路是UEFI 已经把屏幕点亮 Linux early boot 先不要打断它 而是继续使用 UEFI 留下来的 framebuffer它通常需要传递这些关键信息信息作用framebuffer 地址Linux 知道图像数据在哪里framebuffer 大小Linux 知道显示内存范围分辨率Linux 知道屏幕宽高stride / pitchLinux 知道每一行占多少字节pixel formatLinux 知道像素格式显示状态尽量保持当前显示不中断一句话总结Display Hand-Off 的本质就是让 Linux 接住 Bootloader 已经点亮的那一帧画面。4. 为什么不能直接让 Linux 重新初始化显示当然可以重新初始化但代价是启动显示体验变差。重新初始化显示通常涉及关闭当前显示输出 释放旧 framebuffer 重新配置 display controller 重新配置 HDMI / DP / eDP 重新申请显示 buffer 重新设置显示时序 重新点亮屏幕这个过程中容易出现黑屏 闪屏 LOGO 消失 显示器重新同步 HDMI/DP 信号重新识别对开发板调试来说这可能只是一个小现象但对产品来说这是很明显的体验问题。例如车载、机器人、工业屏、边缘 AI 终端等设备用户更希望看到上电就有画面 启动 LOGO 平滑过渡 APP 首屏自然接上 中间没有明显黑屏所以 Display Hand-Off 并不是单纯为了显示一张 LOGO而是为了让启动显示链路更连续。5. simplefb、efifb、simpledrm 的作用在 Jetson UEFI 显示交接中经常会看到几个概念simplefb efifb simpledrm它们的共同目标是在正式 DRM/KMS 显示驱动加载之前Linux 先继续显示 Bootloader 留下来的 framebuffer。可以简单对比名称信息来源作用simplefbDevice Tree通过 DT 描述 framebufferefifbUEFI GOP通过 EFI 图形信息接管 framebuffersimpledrm固件 framebuffer用 DRM 框架接管早期显示6. simplefb通过 Device Tree 交接simplefb通常依赖 Device Tree。大致流程是UEFI / Bootloader ↓ 把 framebuffer 信息写入 Device Tree ↓ Linux 解析 /chosen 下的 framebuffer 节点 ↓ simplefb 接管显示示意节点如下chosen { framebuffer { compatible simple-framebuffer; reg 0x0 0x90000000 0x0 0x00800000; width 1920; height 1080; stride 7680; format a8r8g8b8; }; };这里最关键的是地址要对 大小要对 分辨率要对 stride 要对 format 要对否则 Linux 虽然接管了 framebuffer但可能出现花屏、错位、颜色异常甚至黑屏。7. efifb通过 UEFI GOP 交接efifb更偏 UEFI 标准路径。UEFI 中有一个图形输出协议GOP: Graphics Output Protocol它的逻辑是UEFI GOP 初始化显示 ↓ UEFI 绘制 LOGO ↓ Linux 读取 EFI framebuffer 信息 ↓ efifb 继续显示所以在 UEFI 平台上efifb是比较自然的 early display 路径。8. DRM/KMS正式显示驱动接管simplefb、efifb、simpledrm只是早期显示接管它们不是最终显示方案。Linux 正式起来后还是要由 DRM/KMS 显示驱动建立完整显示管线plane crtc encoder connector mode timing framebuffer display controller完整接力关系可以理解成Bootloader framebuffer ↓ simplefb / efifb / simpledrm ↓ DRM/KMS 正式显示驱动 ↓ Weston / Qt / APP如果 DRM/KMS 接管过程不平滑即使前面的 Display Hand-Off 正常后面也可能出现短暂闪屏。所以完整的“无黑屏切换”实际包含两次关键交接UEFI → Linux early framebuffer Linux early framebuffer → DRM/KMS9. APP 首屏和 Display Hand-Off 的关系这里有一个容易误解的点Display Hand-Off ≠ Bootloader 直接交给 APPAPP 是用户空间程序它要等下面这些阶段完成后才会启动Linux Kernel 启动 rootfs 挂载 init/systemd 启动 图形服务启动 APP 启动所以更准确的链路是Bootloader LOGO ↓ Display Hand-Off ↓ Linux early framebuffer ↓ DRM/KMS ↓ Weston / Qt ↓ APP 首屏也就是说阶段负责内容UEFI点亮屏幕显示 LOGODisplay Hand-Off把 framebuffer 信息交给 Linuxsimplefb / efifbLinux 早期接住画面DRM/KMS正式显示驱动接管APP显示最终业务界面10. Jetson 中的关键配置在 Jetson UEFI 中类似下面的配置很关键SOC Display Hand-Off Mode Always SOC Display Hand-Off simplefb / efifb可以这样理解配置含义SOC Display Hand-Off Mode是否执行显示交接Always始终尝试把 UEFI 显示状态交给 LinuxSOC Display Hand-Off选择交接方式simplefb通过 Device Tree 交接efifb通过 EFI framebuffer 交接如果没有正确开启可能出现UEFI 阶段 LOGO 正常 Linux Kernel 一启动屏幕黑掉 等 DRM/KMS 或 APP 起来后才重新显示如果配置正确显示链路会更加平滑UEFI LOGO ↓ Linux early display 接住 ↓ DRM/KMS 接管 ↓ APP 首屏显示11. 为什么开启后仍然可能黑屏Display Hand-Off 不是万能开关。实际 bring-up 中仍然可能遇到黑屏、花屏或闪屏。11.1 framebuffer 信息错误常见问题framebuffer 地址错误 framebuffer size 不够 stride 不正确 format 不匹配 width / height 不匹配可能现象花屏 颜色异常 画面错位 LOGO 显示异常11.2 framebuffer 内存被覆盖UEFI 绘制 LOGO 使用的是一块内存。如果 Linux 启动后没有正确保留这块内存它可能被内核重新分配导致LOGO 被破坏 画面突然变乱 启动中途花屏11.3 Linux 没有对应 early framebuffer 驱动需要确认内核是否支持相关驱动例如CONFIG_FB_SIMPLE CONFIG_FB_EFI CONFIG_DRM_SIMPLEDRM如果 Bootloader 传了信息但 Linux 没有驱动接收屏幕仍然可能黑。11.4 DRM/KMS 接管时闪屏即使 early display 阶段正常DRM/KMS 正式接管时也可能重新配置显示管线导致短暂黑屏或闪屏。这类问题通常要继续看 DRM/KMS 日志和显示模式设置过程。12. 工程调试方法遇到 Jetson 启动显示问题可以按阶段排查。现象可能阶段排查方向上电后一直无显示UEFI 前后电源、屏幕、HPD、接口、pinmuxUEFI 有 LOGOLinux 启动后黑Display Hand-Offsimplefb/efifb、DT、kernel configLOGO 花屏framebuffer 参数地址、stride、format、sizeKernel 早期正常后面闪一下DRM/KMSmode setting、connector、驱动切换系统起来后无 APP 画面用户空间Weston、Qt、APP、自启动服务APP 首屏慢rootfs/应用systemd、图形服务、APP 初始化常用命令dmesg|grep-iframebufferdmesg|grep-isimpledmesg|grep-iefifbdmesg|grep-isimpledrmdmesg|grep-idrm查看 framebuffercat/proc/fbls-l/dev/fb*如果走 simplefb可以检查 Device Treels/proc/device-tree/chosen/ dtc-Idtb-Odts-oout.dts kernel.dtbgrep-iframebuffer out.dtsgrep-isimple-framebuffer out.dts13. 我的理解以前看启动 LOGO容易理解成Bootloader 显示一张图 Linux 起来后再显示一张图 APP 起来后再显示自己的界面但 Jetson UEFI 的 Display Hand-Off 让我更清楚地看到好的启动显示体验不是每个阶段各画各的而是显示状态在不同阶段之间连续传递。可以把它理解成一次接力UEFI 我先点亮屏幕显示 LOGO。 Linux early display 我先接住 framebuffer不让屏幕黑。 DRM/KMS 我建立正式显示管线接管长期显示。 APP 我显示业务首屏替换启动 LOGO。这就是从 Bootloader 到 APP 首屏的显示接力机制。总结Jetson 启动 LOGO 无黑屏切换本质依赖一条完整的显示接力链路Bootloader / UEFI ↓ Display Hand-Off ↓ Linux early framebuffer ↓ DRM/KMS ↓ APP 首屏其中最关键的一步是UEFI 把 framebuffer 信息交给 Linux early display这个过程可能通过simplefb efifb simpledrm完成。它解决的问题是Linux 启动时不要打断 Bootloader 已经点亮的显示带来的价值是减少黑屏 减少闪屏 提升启动体验 方便 bring-up 调试 让 Bootloader 到 APP 首屏显示更加连续一句话总结Jetson 启动 LOGO 无黑屏切换不是某个阶段单独完成的而是 Bootloader、Linux early display、DRM/KMS 和 APP 首屏之间完成了一次连续的显示接力。