0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深入解析U-Boot TPL代码:嵌入式启动的“第一棒”背后的秘密

jf_44130326 来源:Linux1024 2026-02-05 14:07 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式系统启动过程中,从按下电源键到操作系统开始运行,中间藏着一系列精密的初始化步骤。今天我们就来拆解Rockchip平台U-Boot中的TPLTiny Program Loader)阶段核心代码tpl.c,看看这个"启动第一棒"是如何为整个系统保驾护航的。

wKgZO2kajDuAET28AADNCewxFLs428.png

什么是TPL?为什么它如此重要?

TPLU-Boot启动流程中最早执行的阶段之一,全称Tiny Program Loader(小型程序加载器)。不同于后续的SPLSecondary Program Loader)和U-Boot主体,TPL运行在系统资源极其有限的环境中(通常依赖片内SRAM),却要完成最关键的硬件初始化工作。

可以把嵌入式启动比作一场接力赛:

BootROM(芯片内置的启动程序)是"发令员"

TPL"第一棒选手",负责启动最基础的硬件

SPL"第二棒",完成更多初始化

U-Boot主体则是"最后一棒",最终引导操作系统

tpl.c正是"第一棒选手"的核心操作手册。

代码解析:TPL都做了些什么?

我们通过代码结构,一步步揭开TPL的工作内容:

1.最小化的"输出系统":串口调试的基石

#ifndefCONFIG_TPL_LIBCOMMON_SUPPORT#defineCONFIG_SYS_NS16550_COM1 CONFIG_DEBUG_UART_BASEvoidputs(constchar*str){ while(*str)    putc(*str++);}voidputc(charc){ if(c =='n')   NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1),'r'); NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), c);}#endif

这段代码实现了最基础的字符串输出功能。在TPL阶段,系统还没有加载完整的函数库,因此需要直接操作NS16550串口控制器实现putc(输出字符)和puts(输出字符串)函数。

特别注意到对换行符n的处理——自动转换为rn(回车+换行),这是为了保证在串口终端上能正确换行,细节处体现了调试友好性。

2.时间管理:系统的"心跳"初始化

#ifndefCONFIG_TPL_LIBGENERIC_SUPPORTint__weaktimer_init(void){return0; }#ifdefCONFIG_ARM64void__weak __udelay(unsignedlongusec){  u64 i, j, count; asmvolatile("MRS %0, CNTPCT_EL0":"=r"(count));  i = count;  j = usec *24; // 24MHz计数器  i += j; while(1) {   asmvolatile("MRS %0, CNTPCT_EL0":"=r"(count));   if(count > i)break;  }}#else// 非ARM64架构的延迟实现#endifvoidudelay(unsignedlongusec){ __udelay(usec); }#endif

时间延迟是硬件初始化的关键需求(比如等待外设上电稳定)。这段代码通过直接操作CPU计数器寄存器

ARM64架构读取CNTPCT_EL0寄存器

为其他架构使用mrrc p15指令

基于24MHz的基准频率计算延迟时间

这种底层实现确保了在没有操作系统支持的情况下,系统仍能获得精确的微秒级延迟能力。

3.核心初始化流程:board_init_f的使命

作为TPL阶段的主入口函数,board_init_f串起了整个初始化流程:

voidboard_init_f(ulongdummy){  rockchip_stimer_init(); // 系统定时器初始化  arch_cpu_init();    // CPU架构初始化#ifdef EARLY_DEBUG  debug_uart_init();   // 调试串口初始化  printascii("U-Boot TPL "PLAIN_VERSION"...n"); // 版本信息打印#endif  timer_init();      // 定时器初始化 // DRAM初始化(根据配置选择设备模型或直接调用)#ifdefined(CONFIG_SPL_FRAMEWORK) && !CONFIG_IS_ENABLED(TINY_FRAMEWORK)  ret = uclass_get_device(UCLASS_RAM,0, &dev);#else  sdram_init();#endif // 条件允许时返回BootROM执行下一阶段#ifdefined(CONFIG_TPL_ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_TPL_BOARD_INIT)  back_to_bootrom(BROM_BOOT_NEXTSTAGE);#endif}

这个函数的执行逻辑清晰展现了TPL的核心任务:

1.初始化系统定时器,建立时间基准

2.完成CPU架构相关初始化

3.启动调试串口,输出版本信息(关键的调试点)

4.初始化DRAM(内存),为后续阶段提供运行空间

5.交接控制权到下一阶段

对启动流程的关键作用

TPL作为启动的"第一棒",其工作质量直接决定了系统能否正常启动:

1.硬件最小化初始化:在资源受限的环境下,优先初始化串口、定时器、内存等关键硬件,为后续阶段铺路

2.启动流程衔接:通过back_to_bootrom函数与BootROM协作,确保启动流程按顺序推进

3.兼容性适配:通过条件编译(如CONFIG_ARM64CONFIG_TPL_LIBCOMMON_SUPPORT)支持不同架构和配置,提高代码复用性

4.故障隔离:如果TPL阶段失败(如DRAM初始化出错),系统会在早期挂起,避免错误扩散

对调试工作的特殊意义

对于嵌入式开发者来说,TPL阶段的调试支持堪称"救命稻草"

1.早期日志输出:通过debug_uart_initprintascii实现的早期打印,能帮助定位启动失败的第一现场。想象一下,如果连"U-Boot TPL版本信息"都打印不出来,排查问题会有多困难!

2.时序问题排查:精确的udelay函数确保硬件初始化时序正确,减少因时序错误导致的"偶发故障"

3.版本追溯:启动时打印的版本号(PLAIN_VERSION)和编译时间,能快速确认是否使用了正确的代码版本

4.错误定位hang函数在出错时进入死循环,配合JTAG等工具可捕获现场状态,避免系统"crash后无痕迹"

总结:TPL——启动流程的"基石"

tpl.c虽然代码量不大,却承载了嵌入式系统启动最基础也最关键的工作。它像一位严谨的"系统初始化工程师",在资源极度有限的环境下,有条不紊地完成硬件唤醒、环境准备和流程交接。

对于开发者而言,理解TPL代码不仅能帮助我们快速定位启动问题,更能深入理解嵌入式系统从"断电""运行"的整个唤醒过程。下次调试启动故障时,不妨先看看TPL阶段的日志输出——答案往往就藏在这些最早期的信息里。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式系统
    +关注

    关注

    41

    文章

    3829

    浏览量

    133887
  • u-boot
    +关注

    关注

    0

    文章

    137

    浏览量

    39948
  • 代码
    +关注

    关注

    30

    文章

    4976

    浏览量

    74384
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    嵌入式Linux启动时间优化的秘密之五-Bootloader

    本文主要讲述嵌入式Linux启动时间优化的秘密,我们继续上篇没有讲完的嵌入式Linux启动时间优化方法,本文主要会讲Bootloader。想
    发表于 04-21 17:24 3484次阅读
    <b class='flag-5'>嵌入式</b>Linux<b class='flag-5'>启动</b>时间优化的<b class='flag-5'>秘密</b>之五-Bootloader

    嵌入式系统中U-Boot 基本特点及其移植方法

    在介绍U-Boot 基本特点的基础上,结合U-Boot 移植经历,以MPC8xx 和嵌入式Linux 为背景,分析、探讨U-Boot 的移植方法、过程与相关移植要点, 并给出
    发表于 04-15 09:25 17次下载

    嵌入式系统中U-Boot 基本特点及其移植方法

    在介绍U-Boot 基本特点的基础上,结合U-Boot 移植经历,以MPC8xx 和嵌入式Linux 为背景,分析、探讨U-Boot 的移植方法、过程与相关移植要点, 并给出
    发表于 05-16 14:52 12次下载

    U-Boot启动及移植分析

    bootloader 开发是嵌入式系统必不可少而且十分重要的部分,U-Boot 为功能强大的bootloader 开发软件。本文详细分析了U-Boot启动流程,并结合其源码,阐述了
    发表于 09-01 16:34 27次下载

    种在U-BOOT嵌入千兆网络功能的方法

    种在U-BOOT嵌入千兆网络功能的方法摘 要:U-BOOT种开放源码的、用于多种嵌入式
    发表于 02-05 17:38 17次下载

    嵌入式U-BOOT启动流程及移植

    摘要:嵌入式系统般没有通用的bootloader,u-boot是功能强大的bootloader开发软件,但相对也比较复杂。文中对u-boot启动
    发表于 02-25 16:00 59次下载

    基于ARM9的U-Boot自动识别启动实现

    嵌入式ARM9系列处理器支持U-Boot从Nor FLASH或者Nand FLASH启动,也支持U-Boot直接下载到内存中调试运行,根据U-Boo
    发表于 03-04 16:23 91次下载
    基于ARM9的<b class='flag-5'>U-Boot</b>自动识别<b class='flag-5'>启动</b>实现

    u-boot学习指南

    u-boot 是免费的,我们做嵌入式般只需要使用 u-boot 即可,但如果你想成为个比较强的嵌入
    发表于 11-17 15:54 2次下载

    嵌入式Linux系统移植开发-(1)基于Yocto构建嵌入式u-boot,内核,文件系统

    基于Yocto构建嵌入式u-boot,内核,文件系统Yocto是什么?简单地概括,它是个工具,可以用来构建u-boot,kernel,文件系统,交叉编译工具链,等等。Yocto提供了
    发表于 11-01 17:38 14次下载
    <b class='flag-5'>嵌入式</b>Linux系统移植开发-(1)基于Yocto构建<b class='flag-5'>嵌入式</b><b class='flag-5'>u-boot</b>,内核,文件系统

    U-Boot架构浅析

    导读:嵌入式Linux系统搭建,bootloader是必不可少的环,而U-Boot已成嵌入式Linux事实标准。所以较为深入的分析
    发表于 02-07 11:56 7次下载
    <b class='flag-5'>U-Boot</b>架构浅析

    tiny4412编译与移植U-Boot

    U-Boot个主要用于嵌入式系统的引导加载程序, U-Boot本质是个裸机程序,是
    的头像 发表于 08-31 08:59 3421次阅读
    tiny4412编译与移植<b class='flag-5'>U-Boot</b>

    嵌入式系统中u-boot和bootloader详解

    嵌入式软件工程师听说过 u-boot 和 bootloader,但很多工程师依然不知道他们到底是啥。
    发表于 10-20 13:12 2676次阅读

    解析Rockchip平台U-Boot核心文件:boot_rkimg.c到底做了什么?

    嵌入式开发中,U-Boot 作为引导程序的 “中流砥柱”,负责初始化硬件、加载内核并启动系统。对于 Rockchip 平台的设备(如常见的开发板、智能终端),boot_rkimg.c
    的头像 发表于 02-03 15:29 952次阅读
    <b class='flag-5'>解析</b>Rockchip平台<b class='flag-5'>U-Boot</b>核心文件:<b class='flag-5'>boot</b>_rkimg.c到底做了什么?

    深入理解 RK3506 U-Boot 重定位:从代码到原理

    嵌入式系统中,U-Boot 作为引导加载程序,其启动流程的核心环节之就是 重定位(Relocation) 。对于 RK3506 这类基于 ARM Cortex-A 架构的芯片,重定
    的头像 发表于 11-28 07:05 996次阅读
    <b class='flag-5'>深入</b>理解 RK3506 <b class='flag-5'>U-Boot</b> 重定位:从<b class='flag-5'>代码</b>到原理

    深入解析U-Boot image.c:RK平台镜像处理核心逻辑

    在瑞芯微(RK)平台的嵌入式开发中,U-Boot作为核心的启动加载程序,负责完成镜像解析、校验、加载等关键流程。而image.c正是U-Boot
    的头像 发表于 02-24 16:46 1810次阅读
    <b class='flag-5'>深入</b><b class='flag-5'>解析</b><b class='flag-5'>U-Boot</b> image.c:RK平台镜像处理核心逻辑