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

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

3天内不再提示

U-Boot调试神器:深挖rk平台atags.c,解决90%的ARM启动问题

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

扫码添加小助手

加入工程师交流群

ARM嵌入式开发中,U-Boot作为启动第一站,其向内核/可信固件(ATF/TOS)传递的参数是否正确,直接决定了后续系统能否正常启动。瑞芯微Rockchip)平台下的atags.c,正是调试这类参数问题的金钥匙”——它不仅是ATAGS参数的解析器,更是嵌入式工程师定位启动故障的核心工具。

本文将结合实际开发板的atags命令输出,从atags.c的核心逻辑出发,拆解其功能、调试价值,并结合实战场景讲解如何利用该模块快速解决ARM启动类问题。

wKgZO2mPvoWALkDEAAAhy-3MKuk600.png

一、ATAGS是什么?atags.c又做了什么?

基础:ATAGSARM Tags)是ARM架构下U-Boot与内核/下级固件的参数桥梁,类比x86SMBIOS,负责传递硬件配置、内存分区、启动设备等关键信息。

瑞芯微定制的atags.c,则是这套桥梁可视化调试工具,核心实现3项功能,结合实际开发板输出可更直观理解:

1.结构化解析+打印所有ATAGS参数

遍历ATAGS_PHYS_BASE(实际开发板为0x001fe000)物理内存区域,解析瑞芯微定制的所有ATAG类型(除常见的串口、DDR内存、TOS/ATF内存等,还包含corepstoreboot1 param等特有Tag),并输出每个参数的具体值(如实际串口波特率1500000DDR 3个有效bank地址等)。

核心函数:atags_print_all_tags()(遍历所有Tag+atags_print_tag()(按Tag类型打印字段),实际开发板执行atags命令后,会依次输出coreserialddr_mem10Tag的完整参数。

2.统计ATAGS内存使用状态

计算ATAGS区域的总大小、已用大小、可用大小,判断是否存在内存溢出(参数写入越界)。结合实际开发板输出,其ATAGS区域地址范围为0x001fe000 ~ 0x00200000,总大小0x000020008KB),已用仅0x000003e0,可用空间充足,无溢出风险。

核心函数:atags_stat()——通过累加每个Tag的占用字节(t->hdr.size << 2),输出内存使用占比,实际输出中“in use size”“available size”可直接判断内存状态。

3.暴露U-Boot命令行调试接口

通过U_BOOT_CMD注册atags命令,开发者无需修改代码、无需重新编译,在U-Boot命令行输入atags即可触发上述解析和统计,是无侵入式调试的关键。实际开发板的所有ATAGS参数,均通过这一条命令直接获取,无需额外调试操作。

核心逻辑:do_dump_atags()绑定命令执行逻辑,一行命令就能拿到全量参数+内存状态,下文所有实战分析均基于开发板真实atags输出。

二、为什么atags.c是调试刚需

ARM平台启动故障80%以上与U-Boot传递的参数不匹配有关,而atags.c正是定位这类问题的终极武器。以下是高频调试场景及对应的价值:

调试场景

atags.c能解决什么问题?(结合实际板卡)

内核启动失败

验证core(核心参数)、ddr_mem(内存)、rootdev(根设备)是否正确,实际板卡corerootdev0x0,需核对内核配置;

TOS/ATF启动异常

查看atf_memATF内存,实际phy_addr=0x0size=0x100000)、tos_memTEE/DRM内存)是否地址冲突/配置异常;

串口调试乱码/无输出

核对serial Tag:波特率1500000、物理地址0xfeb50000、使能0x1,确认与内核串口配置一致;

启动设备识别错误(EMMC→SD

定位bootdev Tagdevtype=0x2devnum=0x0,对照瑞芯微手册判断设备类型是否匹配;

ATAGS参数丢失/溢出

通过实际ATAGS state判断:已用0x3e0 < 总大小0x2000,无溢出,若参数丢失可排查Tag写入逻辑;

固件版本/签名异常

验证fwver TagDDRSPLBL31BL32固件版本明确,可核对是否为目标版本;

自定义参数生效验证

新增/修改RAM分区、boot1参数后,可通过ddr_memboot1 param Tag快速验证写入成功;

pstore存储异常

查看pstore Tagtable参数,实际板卡前5项均为0x8000@0x110000,可验证持久化存储配置;

三、实战:用atags命令解决4类高频问题(基于真实板卡输出)

以下结合实际开发板的真实atags输出,讲解4类高频启动问题的定位方法,所有操作均基于板卡实际参数,可直接套用。

场景1:内核启动后内存识别错误

操作步骤:

1.U-Boot命令行执行atags,找到[ddr_mem]段:

[ddr_mem]:  magic = 0x54410052   size = 0xc0
  count = 0x3 version = 0x0 bank[0] = 0x0 bank[1] = 0x100000000 bank[2] = 0x2f0000000 bank[3] = 0xf0000000 bank[4] = 0x100000000 bank[5] = 0x10000000 bank[6] = 0x0 bank[7] = 0x0 bank[8] = 0x0 bank[9] = 0x0 bank[10] = 0x0 bank[11] = 0x0 bank[12] = 0x0 bank[13] = 0x0 bank[14] = 0x0 bank[15] = 0x0 bank[16] = 0x0 bank[17] = 0x0 bank[18] = 0x0 bank[19] = 0x0  flags = 0x2 data[0] = 0x0 data[1] = 0x0   hash = 0xb713be00

1.对比内核设备树(DTS)中的内存配置,重点关注2点:

板卡count=0x3,说明有3个有效DDR bank,实际有效地址为bank[1]0x100000000)、bank[2]0x2f0000000)、bank[5]0x10000000),若DTS中内存地址/数量与这些值不一致修正U-BootDDR初始化逻辑,重新生成ATAGS参数;

flags=0x2,需对照瑞芯微rk_atags.hflags的宏定义,确认DDR工作模式是否符合预期,模式错误也会导致内存识别失败。

场景2:内核串口乱码(U-Boot串口正常)

操作步骤:

1.执行atags找到[serial]段:

[serial]:  magic = 0x54410050   size = 0x30
 version = 0x0  enable = 0x1   addr = 0xfeb50000 baudrate = 1500000  m_mode = 0x0    id = 0x2  res[0] = 0x0  res[1] = 0x0   hash = 0xf968b524

1.排查方向:

波特率mismatch:板卡U-Boot传递的波特率为1500000,若内核cmdline/DTS中串口波特率配置为1152009600等,会直接导致乱码要么修改U-BootATAGS串口参数,要么调整内核配置,保持一致;

串口物理地址错误:板卡串口基地址为0xfeb50000,需核对SOC手册,确认该地址对应串口控制器是否为内核配置的串口设备,若地址错误需修正U-Boot的串口基地址定义;

enable=0x1(串口已使能),id=0x2(串口编号),可核对内核是否配置了对应编号的串口设备,避免串口编号不匹配导致无输出。

场景3TOS/ATF启动异常

操作步骤:

1.执行atags找到[atf_mem][tos_mem]段:

[atf_mem]:  magic = 0x54410055   size = 0x28
 version = 0x0 phy_addr = 0x0   size = 0x100000  res[0] = 0x0  res[1] = 0x0   hash = 0x1fe8a1b8
[tos_mem]:  magic = 0x54410053   size = 0x7c
 version = 0x10000 tee_mem:      name = tee.mem    phy_addr = 0x8400000      size = 0x1000000     flags = 0x1 drm_mem:      name = drm.mem    phy_addr = 0x0      size = 0x0     flags = 0x0 res[0] = 0x0 res[1] = 0x0 res[2] = 0x0 res[3] = 0x0 res[4] = 0x0 res[5] = 0x0 res[6] = 0x0  res1 = 0x0  hash = 0x949aa8bf

1.排查方向:

ATF启动异常:atf_mem.phy_addr=0x0,需确认ATF内存是否配置为自动分配地址未定义,若SOC要求ATF内存必须指定非0物理地址修正U-BootATF内存配置,重新生成ATAGS

TOS启动异常:tee_mem.phy_addr=0x8400000size=0x100000016MB),查看该地址范围是否与ddr_mem中的有效bank地址冲突,若冲突调整TEE内存分区的物理地址;

drm_mem.phy_addr=0x0size=0x0,说明未配置DRM内存,若板卡需要DRM功能,需在U-Boot中启用DRM内存配置,否则会导致TOSDRM模块初始化失败。

场景4ATAGS内存溢出导致参数丢失

操作步骤:

1.执行atags查看内存统计段:

ATAGSstate:      addr=0x001fe000 ~0x00200000   Totalsize =0x00002000   inuse size =0x000003e0 availablesize =0x00001c20

1.排查方向:

板卡实际已用大小(0x3e0)远小于总大小(0x2000),可用空间充足(0x1c20),可排除内存溢出导致的参数丢失问题;

若后续新增Tag(如自定义RAM分区、新增固件版本信息),导致已用大小接近总大小0x2000 →需扩大ATAGS区域总大小,修改rk_atags.h中的ATAGS_SIZE宏(当前为0x2000),重新编译U-Boot

额外检查:addr=0x001fe000 ~ 0x00200000,需确认该内存区域未被DDRATF等其他模块占用,避免内存地址冲突导致ATAGS参数写入失败。

四、总结:atags.c的调试核心逻辑

瑞芯微atags.c的本质,是将U-Boot写入物理内存的ATAGS参数可视化”——结合实际开发板情况,无需通过JTAG调试、无需加临时打印,仅用atags一条命令,就能快速获取coreserialddr_mem10类核心参数,以及ATAGS内存使用状态,验证参数的正确性。

其调试核心逻辑可总结为:

执行atags命令解析ATAGS内存区域(0x001fe000~0x00200000打印10类结构化参数+内存统计对比预期配置(DTS/SOC手册/内核参数)定位参数不匹配/内存冲突/溢出问题

对于该类开发板而言,掌握atags.c的解析逻辑和atags命令的使用,能大幅降低ARM启动类问题的调试成本——比如串口乱码可直接核对serial Tag的波特率和地址,内存识别错误可快速查看ddr_membank配置,TOS/ATF异常可定位atf_mem/tos_mem的参数问题,从盲猜问题精准定位,这也是嵌入式开发中工具化调试的核心价值。

最后

嵌入式调试的核心是可视化可验证,而atags.c正是U-Boot参数调试的可视化工具。本文结合实际开发板的真实atags输出,完善了所有示例和实战场景,可直接用于后续板卡调试。若开发板遇到特定启动问题(如bootdev识别错误、pstore存储异常),可结合本文思路,通过atags命令定位,也欢迎在评论区交流~

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

    关注

    5209

    文章

    20629

    浏览量

    336790
  • u-boot
    +关注

    关注

    0

    文章

    135

    浏览量

    39921
  • 瑞芯微
    +关注

    关注

    27

    文章

    845

    浏览量

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

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    U-boot的基本介绍

    从本文开始,将陆续推送“手把手教你移植U-boot”系列文章,目标是由浅入深地讲解U-boot的工作流程、原理、配置方法和移植方法,手把手教你完成U-boot的移植工作,默认硬件开发平台
    发表于 07-14 16:52 4262次阅读
    <b class='flag-5'>U-boot</b>的基本介绍

    U-Boot启动及移植分析

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

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

    S3C44B0开发板上的移植方法和步骤。 u-boot是一个功能强大的bootloader开发软件,适用的CPU平台
    发表于 02-25 16:00 59次下载

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

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

    fireflyFace-RK3399主板U-Boot模式启动

    RK U-Boot 基于开源的 U-Boot 进行开发,工作模式有启动加载模式和下载模式。
    的头像 发表于 12-04 08:52 5637次阅读
    fireflyFace-<b class='flag-5'>RK</b>3399主板<b class='flag-5'>U-Boot</b>模式<b class='flag-5'>启动</b>

    fireflyAIO-3399C主板U-Boot介绍

    RK U-Boot 基于开源的 U-Boot 进行开发,工作模式有启动加载模式和下载模式。
    的头像 发表于 12-04 10:31 2078次阅读

    fireflyAIO-3288C主板U-Boot介绍

    RK U-Boot 基于开源的 U-Boot 进行开发,工作模式有启动加载模式和下载模式。
    的头像 发表于 12-16 13:52 1848次阅读
    fireflyAIO-3288<b class='flag-5'>C</b>主板<b class='flag-5'>U-Boot</b>介绍

    fireflyAIO-3288J主板U-Boot使用简介

    RK U-Boot 基于开源的 U-Boot 进行开发,工作模式有启动加载模式和下载模式。
    的头像 发表于 12-20 10:06 2394次阅读
    fireflyAIO-3288J主板<b class='flag-5'>U-Boot</b>使用简介

    fireflyROC-RK3308U-Boot简介

    RK U-Boot 基于开源的 U-Boot 进行开发,工作模式有启动加载模式和下载模式。
    的头像 发表于 12-21 11:10 3008次阅读
    fireflyROC-<b class='flag-5'>RK3308U-Boot</b>简介

    微雪电子AIO-3128C主板U-Boot使用介绍

    RK U-Boot 基于开源的 U-Boot 进行开发,工作模式有启动加载模式和下载模式。
    的头像 发表于 12-23 16:08 2108次阅读
    微雪电子AIO-3128<b class='flag-5'>C</b>主板<b class='flag-5'>U-Boot</b>使用介绍

    fireflyAIO-3399J主板U-Boot使用介绍

    RK U-Boot 基于开源的 U-Boot 进行开发,工作模式有启动加载模式和下载模式。
    的头像 发表于 12-24 10:00 2644次阅读
    fireflyAIO-3399J主板<b class='flag-5'>U-Boot</b>使用介绍

    在Vitis中调试ARM可信固件和U-boot

    在本篇博文中,我们将探讨如何在 Vitis 中调试 Zynq UltraScale 器件启动镜像。这些启动镜像包括 ARM 可信固件 (ATF) 和
    的头像 发表于 08-02 10:14 5349次阅读
    在Vitis中<b class='flag-5'>调试</b><b class='flag-5'>ARM</b>可信固件和<b class='flag-5'>U-boot</b>

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

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

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

    启动代码,拆解 RK3506 平台 U-Boot 重定位的实现逻辑、关键步骤与底层原理。 路径:u-boot/arch/
    的头像 发表于 11-28 07:05 958次阅读
    深入理解 <b class='flag-5'>RK</b>3506 <b class='flag-5'>U-Boot</b> 重定位:从代码到原理

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

    的SD/NAND/SPI等启动方式做了专属适配。本文将拆解image.c的核心逻辑,梳理RK平台镜像处理的关键流程,帮助开发者理解和调试
    的头像 发表于 02-24 16:46 1770次阅读
    深入解析<b class='flag-5'>U-Boot</b> image.<b class='flag-5'>c</b>:<b class='flag-5'>RK</b><b class='flag-5'>平台</b>镜像处理核心逻辑