
1. 项目概述与核心价值在嵌入式系统开发中尤其是基于TI AM335x这类复杂应用处理器的项目最让人头疼的往往不是应用逻辑的编写而是系统“第一脚”怎么踢出去——也就是上电启动。很多工程师都遇到过这样的场景精心设计的板子焊接完毕满怀期待地通电结果串口一片死寂或者卡在某个神秘的阶段。问题的根源十有八九出在对ROM Code和SYSBOOT配置的理解不够透彻上。ROM Code你可以把它理解为芯片出厂时自带的“生存本能”。它固化在芯片内部的只读存储器中是系统上电或复位后CPU脱离复位状态执行的第一段代码。它的任务非常明确在几乎“一无所有”没有初始化内存、没有配置时钟、外设都处于默认状态的硬件环境下完成最基础的初始化然后根据我们预先设定的“寻人启事”即SYSBOOT引脚配置去指定的地方如Flash、SD卡、网络找到并加载我们真正的应用程序Initial Software ISW。这个过程就是启动引导Booting。AM335x的ROM Code之所以强大且复杂在于它支持多达十几种启动设备并允许通过引脚灵活配置启动顺序和参数。但这份强大也带来了复杂性SYSBOOT[4:0]这5个引脚的不同电平组合对应着TI手册里那张令人望而生畏的庞大配置表决定了启动设备的优先级、接口的工作模式、甚至外部晶振的频率。理解这张表是驯服AM335x启动过程的关键。本文将从一个一线嵌入式开发者的视角带你彻底拆解AM335x的ROM Code启动流程。我们不会止步于翻译数据手册而是结合实际的调试经验、常见的配置“坑点”以及内存布局的深层逻辑让你不仅知道SYSBOOT每个比特位是干什么的更明白为什么要这么设计以及在你的板子上应该如何配置才能确保万无一失。无论你是正在评估AM335x进行新硬件设计还是正在为一块“变砖”的开发板寻找救砖方案这篇文章都将提供可直接参考的路径和避坑指南。2. ROM Code启动流程全景解析AM335x的启动不是一个简单的“读取-运行”过程而是一个分层递进、包含安全切换的状态机。理解这个全景图是后续进行任何细节调试的基础。2.1 启动阶段划分从Secure到PublicAM335x的启动流程严格分为两个阶段安全模式Secure Mode和公共模式Public Mode。这是一种基于TrustZone安全扩展的设计。2.1.1 安全启动阶段Secure Startup芯片上电或冷复位后CPU首先运行的是安全ROM代码Secure ROM Code。这部分代码对用户是完全不可见的存储在芯片内部的安全区域。它的核心任务有三个芯片自检与安全初始化进行最底层的芯片完整性检查初始化安全相关的硬件模块。运行环境建立为后续公共代码的执行准备一个最小的、安全的环境。模式切换完成其使命后将CPU的操作模式从安全世界Secure World切换到普通世界Normal World 即Public Mode并将执行权交给公共ROM代码。这个阶段开发者无法干预但其结果直接影响后续流程。例如如果安全启动失败如芯片熔丝被错误编程设备可能无法进入公共模式。2.1.2 公共启动阶段Public Startup公共ROM代码Public ROM Code就是我们通常所说的“ROM Code”也是本文讨论的核心。它的入口地址固定在0x30000。一旦CPU跳转到此地址便开始了我们可观测和配置的启动流程。其主要职责包括基础硬件初始化配置MPUCortex-A8内核的看门狗超时默认为3分钟初始化必要的时钟和DPLL。解析SYSBOOT配置读取控制模块Control Module中SYSBOOT引脚锁存的状态生成启动设备列表。执行引导循环按照列表顺序尝试从各个设备引导。加载与验证镜像找到有效镜像后将其加载到内部SRAM并进行必要的验证如校验和。跳转执行最终将CPU的执行权交给加载到SRAM中的ISW。关键点公共ROM Code运行时MMU和L1缓存都是关闭的。这意味着所有内存访问都是物理地址、非缓存的。这解释了为什么ROM Code的初始化代码对性能要求不高以及为什么ISW通常需要先被加载到SRAM确保稳定执行而非直接在外存XIPExecute In Place。2.2 核心引导流程详解公共ROM Code的主引导流程是一个典型的“尝试-失败-下一个”循环其逻辑可以用以下步骤概括这也是调试时分析串口输出或指示灯状态的理论依据平台初始化配置看门狗、根据SYSBOOT[15:14]配置系统主晶振频率、初始化核心DPLLCORE, MPU, PER以产生各模块所需的工作时钟。构建设备列表根据SYSBOOT[4:0]的值查表确定最多4个备选启动设备及其顺序。例如SYSBOOT[4:0] 00101b对应着NOR - USB_MS (USB1) - EMAC1 - USB_CL (USB0)这个搜索序列。遍历设备列表 a.取设备从列表中取出当前要尝试的设备。 b.判断类型内存设备NOR/NAND/MMC/SPI/QSPI/USB_MS执行“内存引导流程”。ROM Code会尝试读取该存储设备的特定偏移地址如MMC的扇区0寻找有效的镜像头。外设设备UART/USB_CL/EMAC执行“外设引导流程”。ROM Code会初始化该接口然后等待主机如PC通过XMODEM、RNDIS、TFTP等协议发送镜像。 c.尝试引导如果在该设备上找到了有效且完整的镜像则将其拷贝到内部SRAM的指定区域0x402F0400或0x402F4000开始取决于芯片版本。如果失败超时、通信错误、镜像无效则递增该设备的“引导错误计数器”位于0x40337DE0开始的地址并返回步骤3a尝试列表中的下一个设备。镜像验证与跳转成功加载镜像到SRAM后ROM Code会进行必要的验证对于安全启动可能包括数字签名验证。验证通过后它会准备一个引导参数结构体的指针放入R0寄存器然后跳转到SRAM中镜像的入口点将控制权彻底移交给ISW通常是U-Boot或类似的二级引导程序。这个流程的精华在于其容错性和灵活性。通过一个有序的列表系统可以自动尝试多种启动方案例如优先从板载Flash启动失败后自动降级到通过网络或USB烧录模式启动这极大地方便了工厂生产和现场维护。3. SYSBOOT配置引脚深度解读与实战配置SYSBOOT配置是连接硬件设计与软件启动行为的桥梁。AM335x提供了多达19个SYSBOOT引脚SYSBOOT[18:0]但最常用、也最复杂的是其中一部分。我们将其分为两类全局配置位和设备相关配置位。3.1 全局配置位影响整个启动环境这些位的设置对后续所有启动尝试都有影响必须在设计硬件时首要确定。3.1.1 SYSBOOT[15:14] - 系统时钟源选择这是最重要的配置之一它决定了输入到芯片的主振荡器Main Oscillator频率。00b: 19.2 MHz01b: 24 MHz10b: 25 MHz11b: 26 MHz为什么是这几个频率因为内部DPLL的倍频系数是针对这些基频优化设计的可以产生无误差的标准时钟如25MHz的基频可以方便地倍频出100MHz、125MHz等常用频率。配置错误后果如果硬焊接的是24MHz晶振但配置为00b19.2MHz那么DPLL计算出的所有时钟CPU、外设频率都会偏差约20%可能导致内存控制器、USB PHY等对时钟精度敏感的模块工作异常表现为启动失败或运行不稳定。3.1.2 SYSBOOT[18] - CLKOUT2输出控制仅PG1.2及以后版本0b: 不将EXTDEV_PLL时钟路由到CLKOUT2引脚。1b: 将EXTDEV_PLL时钟路由到CLKOUT2引脚输出。3.1.3 SYSBOOT[17] - CLKOUT1输出使能0b: 禁用CLKOUT1引脚时钟输出。1b: 使能CLKOUT1引脚时钟输出。3.1.4 SYSBOOT[16] - USB DP/DM引脚交换仅PG1.2及以后版本0b: USB差分数据线不交换正常连接。1b: USB DP/DM信号交换。 这个功能用于纠正PCB布线时可能出现的差分线反接错误无需改动硬件即可通过软件配置修复。3.1.5 SYSBOOT[13:12] - 保留位必须设置为00b用于正常操作。3.2 设备相关配置位与启动顺序解码SYSBOOT[4:0]这5位是启动配置的“灵魂”它直接映射到数据手册中那个庞大的表格Table 5-10。我们不需要死记硬背但要理解其编码逻辑。3.2.1 启动顺序的编码逻辑SYSBOOT[4:0]的值0b00000 到 0b11111作为一个索引查表得到对应的4个启动设备序列。ROM Code会严格按照这个顺序尝试。例如00101b(十进制5):NOR - USB_MS (USB1) - EMAC1 - USB_CL (USB0)01100b(十进制12):MMC0 - (无) - (无) - (无)注意很多配置的2、3、4号设备是“无效”或“不关心”的ROM Code尝试完第一个就会失败或停止3.2.2 设备特定参数解析同一启动设备如NAND在不同的SYSBOOT[4:0]配置行中可能还需要其他SYSBOOT位来定义其工作模式NAND Flash相关SYSBOOT[6]: Wait引脚复用选项。决定NAND的R/B#Ready/Busy信号使用哪个引脚。SYSBOOT[5]: ECC校验责任方。0b: ECC由ROM Code计算和校验。这是最常用的设置因为ROM Code在读取NAND时会自动处理ECC。1b: ECC由NAND控制器硬件完成。通常用于高级场景或使用不支持标准ECC的NAND芯片时。NOR Flash相关SYSBOOT[11]: 复用与非复用模式选择。决定地址/数据总线是复用共用还是独立。SYSBOOT[9]: WAIT信号监控使能。如果NOR Flash速度较慢需要使能此功能ROM Code会在读写时采样WAIT信号以插入等待周期。SYSBOOT[8]: Wait引脚复用选项类似NAND。SYSBOOT[7:6]: NOR Flash引脚复用选项。决定NOR Flash接口占用哪组GPIO引脚。QSPI Flash相关SYSBOOT[7]: 数据线宽度选择。0b: 四线读取Quad Read速度更快。1b: 单线读取Single Read兼容性更好。SYSBOOT[6]: QSPI引脚复用选项。以太网EMAC相关SYSBOOT[5]: PHY接口类型选择。0b: MII接口。需要更多引脚约16个常用于板载PHY。1b: RMII接口。引脚数减半约7个常用于外接PHY模块或节省布线空间。SYSBOOT[18]与SYSBOOT[5]配合为外部PHY提供时钟。当SYSBOOT[5]0EXTDEV_PLL配置为25MHzSYSBOOT[5]1则配置为50MHz并通过CLKOUT2输出如果SYSBOOT[18]1。3.3 实战配置案例与硬件设计要点假设我们要设计一个典型的工业控制器启动方案为首选从板载eMMCMMC0启动备用方案为通过以太网EMAC1进行TFTP网络启动。确定SYSBOOT[4:0]值查阅手册Table 5-10寻找第一设备为MMC0第二设备为EMAC1的行。我们发现SYSBOOT[4:0] 10110b十进制22对应EMAC1 - NAND_I2C - NAND - MMC0顺序不符。我们需要的是MMC0在第一顺位。继续查找01100b十进制12是MMC0但无EMAC1。10110b顺序不对。实际上手册的表格是固定的可能没有完全符合我们“MMC0第一EMAC1第二”的条目。这时需要做出权衡方案A推荐选择00100b十进制4MMC1 - MMC0 - USB_MS - USB_CL。我们将eMMC接到MMC0端口但配置为从MMC1启动这不对。实际上我们可以将eMMC硬件连接到MMC1接口然后选择此配置。这样第一启动设备是MMC1我们的eMMC第二是MMC0可接SD卡座作为备用第三、四是USB。网络启动不在列表中。方案B使用网络如果我们必须保留网络启动作为备用可能需要选择以EMAC1为第一启动设备的配置如11011b十进制27EMAC1 - UART0 - NOR。但这意味着放弃了MMC0作为第一启动项。结论AM335x的ROM Code启动顺序表是预定义的灵活性有一定限制。常见的做法是生产环境配置为从最可靠的存储如eMMC启动不设复杂备用。开发/烧录环境配置为从UART或USB启动方便通过串口或USB下载程序到Flash。配置其他引脚假设我们使用24MHz晶振则SYSBOOT[15:14] 01b。不使用CLKOUT1则SYSBOOT[17] 0b。不使用USB交换则SYSBOOT[16] 0b(如果芯片版本支持)。保留位SYSBOOT[13:12] 00b。我们的启动设备是MMC不涉及NAND/NOR/QSPI/EMAC的特殊配置位SYSBOOT[11], [9], [8], [7], [6], [5]这些位在该配置行中通常标记为“don‘t care”但硬件设计时最好给这些引脚接固定电平上拉或下拉避免悬空导致状态不确定。硬件设计根据以上决定我们需要在PCB上通过电阻将SYSBOOT[4:0]、SYSBOOT[15:14]等引脚拉高或拉低。强烈建议使用0欧姆电阻或跳线帽来配置这些引脚而不是直接焊接死。这为后续调试和启动模式切换留下了余地。4. 内存映射与关键数据结构剖析理解ROM Code运行时的内存布局对于高级调试、分析启动失败原因以及编写自己的引导程序都至关重要。4.1 ROM与RAM内存地图4.1.1 片上ROM内存布局AM335x的片上ROM总容量为240KB其中前176KB为Secure ROM后64KB为Public ROM。Public ROM的映射如下0x30000 - 0x3001F:异常向量表。这是CPU发生复位、中断、 abort等异常时首先跳转的地址。0x30020:Public ROM CRC值。用于校验ROM代码本身的完整性。0x30080 - 0x300BC:死循环Dead Loops集合。这是ROM Code预定义的一系列无限循环分支指令用作默认的异常处理或调试状态指示。例如0x3009C是“验证测试通过”循环0x300A0是“验证测试失败”循环。通过让PC指针停在这些地址可以间接判断代码执行到了哪个状态。0x30100 - 0x3FFFC:ROM代码与常量数据区。0x3FFFC(PG1.2):ROM版本号。低8位是主版本次8位是次版本。4.1.2 公共L3 RAM内存布局关键工作区这是ROM Code和初始软件ISW运行时的“舞台”范围是0x402F0000到0x4033FFFF。0x402F0400(PG1.1) 或0x402F4000(PG1.2) 到0x40337C00下载镜像区。这是ROM Code从外部设备Flash, SD卡网络等拷贝进来的初始软件如U-Boot的存放位置。大小约为271KBGP设备。重要限制如果通过USB大容量存储USB_MS模式启动镜像只能从0x40300000始存放最大尺寸缩减到约220KB。0x40337DE0 - 0x40337DEC启动错误计数器。四个32位寄存器分别记录第1到第4个启动设备尝试失败的次数。这是一个非常实用的调试信息。如果系统反复重启可以连接调试器读取这些地址看看是哪个设备卡住了。0x40337E00 - 0x40338E1F公共栈空间。8KB大小用于ROM Code的函数调用。0x40338E00 - 0x40338E1FRAM异常向量表。ROM异常向量最终会跳转到这里。0x40338E20 - 0x40338E3F异常处理程序地址表用户可修改。这是关键默认情况下这些地址指向ROM中的死循环。我们的ISW可以在早期初始化中修改这些地址例如0x40338E38的IRQ句柄使其指向我们自己的中断服务程序从而接管异常处理。0x40338E40 - 0x40338E63跟踪数据区。ROM Code在执行过程中会在此处写入跟踪向量记录执行路径用于深度调试。0x40338E64以上ROM静态变量区。4.2 异常处理机制ROM到RAM的接力AM335x的异常处理设计得很巧妙实现了从ROM固定处理到用户自定义处理的平滑过渡。异常发生例如发生了一个“未定义指令”异常。跳转至ROM向量CPU硬件自动跳转到0x30004Undefined Instruction异常向量地址。ROM向量引导0x30004处存放的指令是LDR PC, [PC, #0x20]假设。这条指令的效果是将程序计数器PC设置为内存地址[0x30004 8 0x20] 0x3002C处存放的值。但根据ROM映射0x3002C并不是一个直接存储地址的向量表项。实际上ROM Code的向量表指令是精心计算的它会跳转到RAM异常向量表的对应位置即0x40338E04。RAM向量接力0x40338E04处存放的指令是LDR PC, [PC, #0x20]。这条指令会读取0x40338E28地址处的值到PC。用户自定义处理0x40338E28这个地址位于“异常处理程序地址表”中。它的默认值是0x30084ROM中的SWI死循环。但是我们的ISW在启动后可以修改0x40338E28这个内存位置将其值改为我们自己的SWI异常处理函数的地址。这样当下次发生SWI异常时流程就会变成0x30008 - 0x40338E08 - [0x40338E2C] - 我们的处理函数。这种机制保证了ROM Code的异常向量表是固定且不可写的但通过一层RAM中的间接跳转为用户程序提供了覆盖默认异常处理的灵活性。4.3 引导参数结构体ROM留给ISW的“信件”当ROM Code成功找到并验证镜像后在跳转到ISW之前它会将一个重要的数据结构的地址放入R0寄存器。这个数据结构就是引导参数结构体它是ROM Code传递给下一阶段软件的“交接文档”。其结构定义如下基于常见理解具体偏移需核对最新手册typedef struct { uint32_t reserved; // 0x00: 保留 void* device_descriptor; // 0x04: 指向启动设备描述符的指针ROM内部使用 uint8_t boot_device; // 0x08: 当前使用的启动设备代码 uint8_t reset_reason; // 0x09: 复位原因位图 uint8_t reserved2[10]; // 0x0A: 保留 } boot_params_t;boot_device这是一个枚举值告诉ISW它是从哪个设备被加载的。例如0x07代表MMC/SD port 00x47代表CPGMAC0以太网。ISW可以根据这个信息初始化对应的驱动或者显示启动来源。reset_reason一个位掩码指示本次启动是由什么事件触发的。例如bit 0表示上电复位bit 4表示看门狗复位。这对于诊断系统意外重启的原因极其有用。在U-Boot等引导程序中通常会在一开始就保存R0的值然后解析这个结构体从而获得关键的硬件上下文信息。5. 时钟与电源初始化细节ROM Code在公共启动阶段需要建立一个让自身和后续基本外设如UART用于调试输出MMC用于读取镜像能够运行的最小时钟系统。5.1 DPLL配置策略ROM Code不会配置所有的DPLL和时钟它只初始化启动所必需的部分MPU ADPLLS锁定到300MHz为Cortex-A8内核提供时钟。这是CPU运行的主频。CORE ADPLLS锁定到2GHz然后通过分频器产生L3_FCLK: 100MHz。这是L3互连总线的功能时钟许多高速外设挂载于此。Ethernet Module Clocks: 100MHz, 50MHz, 5MHz。用于以太网控制器和PHY。PER ADPLLJ锁定到960MHz分频后产生PER_CLKOUTM2: 192MHz。作为多个低速外设的时钟源。SPI_CLK: 48MHz (192MHz / 4)。MMC_CLK: 96MHz (192MHz / 2)。用于SD/MMC控制器。UART_CLK: 48MHz (192MHz / 4)。I2C_CLK: 48MHz (192MHz / 4)。QSPI_CLK: 12MHz (192MHz / 16)。用于QSPI Flash接口。USB PHY时钟直接使用PER_CLKDCOLDO的960MHz。关键点这个时钟配置是一个最小化、安全的配置。它保证了ROM Code自身和基本启动外设能工作但性能并非最优。例如MMC时钟只有96MHz可能无法发挥eMMC 5.1的高速性能。因此我们的ISW如U-Boot在启动后通常需要根据实际硬件如DDR3的速度、外设需求重新配置DPLL和时钟分频器以达到最佳性能。5.2 看门狗与超时管理ROM Code在公共初始化阶段会配置并启动MPU的看门狗定时器超时时间设置为3分钟。这是一个重要的安全机制。作用防止系统在启动过程中卡死。例如如果SYSBOOT配置错误导致ROM Code一直在尝试一个不存在的设备如错误的NAND时序或者在等待主机发送网络镜像时主机无响应看门狗会在3分钟后触发复位让系统有机会尝试列表中的下一个启动设备。对ISW的影响我们的ISW在获得控制权后必须尽快重新配置或禁用这个看门狗。否则如果ISW的初始化或加载操作系统的时间超过3分钟系统会被看门狗复位陷入重启循环。在U-Boot中通常是在board_init_f或board_init_r的早期调用看门狗相关函数进行处理。6. 常见启动问题排查与调试技巧实录基于AM335x的启动问题排查是一个从硬件到软件、从静态配置到动态交互的过程。以下是我在实际项目中总结的排查流程和技巧。6.1 问题排查流程图与速查表当一块AM335x板卡无法启动时可以遵循以下流程图进行系统性排查graph TD A[板卡上电无反应] -- B{测量核心电压与时钟}; B --|正常| C{检查SYSBOOT引脚电平}; B --|异常| Z[检查电源电路与晶振]; C --|与设计相符| D{连接JTAG调试器}; C --|不符| Y[检查上下拉电阻与PCB短路/开路]; D --|可连接| E{暂停CPU 查看PC指针}; D --|无法连接| X[检查JTAG接口、 复位电路、 芯片是否损坏]; E --|PC在ROM区间 0x30000附近| F{查看启动错误计数器 0x40337DE0}; E --|PC在其他地方或杂乱| W[可能DDR/时钟初始化失败 或代码跑飞]; F --|计数器1递增| G[第一启动设备失败 检查该设备硬件与连接]; F --|计数器2递增| H[第二启动设备失败]; F --|计数器均为0| I[未进入设备尝试循环 检查ROM Code早期初始化]; G -- J[具体设备排查: Flash/MMC/USB/UART/ETH];表启动失败常见症状与可能原因症状可能原因排查方向完全无反应无电流电源故障核心电压缺失晶振未起振测量电源轨电压用示波器测晶振引脚有电流但串口无任何输出SYSBOOT配置错误UART引脚复用错误时钟配置错误1. 确认SYSBOOT[15:14]与板上晶振匹配。2. 确认UART0引脚未被其他功能占用。3. 测量UART_TXD引脚是否有波形波特率可能与预期不同。串口输出乱码波特率不匹配时钟频率错误1. 尝试常用波特率115200, 57600, 38400。2. 确认SYSBOOT[15:14]配置正确。输出CCC后停止ROM Code在尝试UART下载模式XMODEM这是正常行为表示ROM Code正在等待主机通过串口发送镜像。如果不想用UART启动检查SYSBOOT[4:0]配置确保UART不在启动列表前几位。输出C后停止看门狗超时复位系统在3分钟内未找到有效镜像。检查所有启动设备。可通过JTAG读取0x40337DE0开始的错误计数器判断卡在哪个设备。仅输出少量字符后停止DDR初始化失败或ISW镜像损坏1. 使用JTAG检查DDR控制器配置。2. 检查烧写到存储设备的镜像是否完整校验和。3. 确认镜像格式如TI的GP Header是否正确。6.2 高级调试手段利用跟踪向量与错误计数器当常规串口日志不足时需要动用更底层的调试工具。6.2.1 读取跟踪向量Tracing Data地址0x40338E40开始的20个字节5个字保存了ROM Code执行路径的跟踪码。这些代码是ROM Code内部定义的TI通常不公开完整列表但通过对比正常和异常启动时的值可以定位问题发生在哪个阶段。例如如果跟踪向量在某个值后不再变化可能意味着代码在该处卡死。6.2.2 读取启动错误计数器这是最实用的调试信息之一。通过JTAG或挂载到运行中的ISW如果它能部分运行读取0x40337DE0(Boot Mode 1),0x40337DE4(Boot Mode 2)等地址的值。如果0x40337DE0的值很大说明系统反复尝试第一个启动设备都失败了然后看门狗复位循环往复。问题肯定出在第一个设备上。如果0x40337DE0为0但0x40337DE4有值说明第一个设备尝试成功或快速失败但卡在了第二个设备上。6.2.3 使用JTAG进行指令级调试连接JTAG调试器如TI的XDS系列在CCS或GDB中暂停CPU。检查PC指针如果PC在0x30000到0x3FFFF之间说明CPU还在执行ROM Code。检查寄存器查看R0-R15、CPSR寄存器。R0在跳转到ISW前应包含引导参数结构体地址。检查内存查看0x402F0400或0x40300000区域确认从启动设备读取的镜像数据是否被正确加载到此。可以对比原始镜像文件进行验证。单步执行在ROM Code区域小心地进行单步观察执行流是否按预期跳转。6.3 特定设备启动失败排查要点6.3.1 MMC/SD卡启动失败现象错误计数器1如果MMC是第一个设备持续增加。排查电气用示波器检查MMC_CLK引脚M19/L18是否有96MHz时钟输出CMD和DAT线是否有上拉配置确认SYSBOOT[4:0]正确选择了MMC0或MMC1。镜像SD卡是否格式化为FAT镜像是否放在名为MLO的文件中对于RAW模式是否烧写到了正确的扇区MLO文件是否包含TI特有的GP Header时序对于eMMCROM Code使用的是默认的、较保守的时序。如果eMMC芯片型号较新或要求特殊时序可能需要通过eMMC的扩展寄存器进行配置这超出了ROM Code的能力可能导致初始化失败。6.3.2 UART启动无响应现象串口输出CCC后停止但主机发送XMODEM协议无反应。排查波特率ROM Code的UART波特率是固定的1152008N1。确认主机终端软件设置正确。流控ROM Code的UART启动不使用硬件流控RTS/CTS。确保连接线只用了TX、RX、GND三根线。协议ROM Code期望的是XMODEM协议。确保使用的下载工具如kermit的send命令或lrzsz的sb命令支持并正确使用了XMODEM。镜像头通过UART下载的镜像同样需要包含TI的GP Header。6.3.3 以太网EMAC启动失败现象系统停留在等待网络状态错误计数器增加。排查SYSBOOT[5]确认配置为MII还是RMII与PHY芯片的接口类型匹配。SYSBOOT[18]与时钟如果使用RMII且需要50MHz时钟参考确认SYSBOOT[18]1且SYSBOOT[5]1并用示波器测量CLKOUT2引脚是否有50MHz输出。PHY地址ROM Code默认尝试的PHY地址是1。确保你的PHY芯片的硬件地址通过PHYAD引脚设置是1。网络环境确保开发板与主机在同一网段主机开启了DHCP服务器用于BOOTP获取IP和TFTP服务器并且TFTP服务器目录下有正确的镜像文件如u-boot.img。启动问题的排查往往需要耐心和系统性思维。从最基础的电源、时钟、配置引脚查起逐步深入到接口信号、协议交互。充分利用错误计数器和跟踪向量这些ROM Code提供的内建诊断工具能极大缩短定位问题的时间。记住一个稳定的启动是嵌入式产品可靠性的基石在SYSBOOT配置和启动镜像制作上多花些功夫能为后续开发省去无数麻烦。