简介:对于从事嵌入式底层开发的工程师而言,OMAP-L138处理器的固件烧录与启动引导往往是项目初期最易卡壳的环节。这套FlashAndBootUtils_2.29工具包正是为OMAP-L138及AM1808等平台量身打造的完整引导与烧录资源,内含引导加载程序、Flash编程工具、配置脚本、库与驱动以及使用文档,能够有效缩短系统搭建时间。压缩包共716个文件,压缩后大小仅3.65MB,文件类型涵盖obj目标文件、C源码、头文件、makefile构建脚本、ais启动镜像、cmd链接脚本、map映射文件与asm汇编源文件,目录结构清晰,便于按需检索。目前已有104位开发者学习下载该工具包。通过其中可见的UBL_OMAPL138_NAND、NOR、SPI_MEM等镜像,可以直接参考现成的NAND、NOR、SPI启动配置,结合U-Boot引导程序与多种烧录工具,完成从初始化、固件写入到启动验证的全流程,是OMAP-L138平台稳定开发与维护的实用助手。附带的文档还能辅助排查启动过程中的常见故障。
1. FlashAndBootUtils 2.29:OMAP-L138 不插 JTAG 也能烧启动镜像
看到 OMAP-L138_FlashAndBootUtils_2_29.tar.gz 这个文件名,先要清楚它解决什么问题。OMAP-L138 是 TI 一颗 ARM926EJ-S 加 C674x DSP 的 SoC,上电后由片内 ROM 的 RBL 按引脚采样决定从哪启动。FlashAndBootUtils 就是围绕这条启动链的一套工具:生成 AIS 镜像、用串口加载、再写进 NAND 或 SPI NOR,全程不依赖 JTAG。
对板级 bring-up 和生产烧录的人来说,这套工具的意义是把串口变成量产工位标配。2.29 是维护较成熟的版本,tar.gz 后缀说明它以源码形态分发,Linux 用户能解压后直接读代码、重编主机端工具。
下文按落地路径走:先 tar.gz 解压认目录,再讲 OMAP-L138 的 RBL 与 AIS 镜像机制,最后落在 sfh 串口烧写命令和不插 JTAG 的验证手法。
2. 先解压 tar.gz 再谈烧写:FlashAndBootUtils 2.29 的目录与工具分工
这套包解压后直接就能看懂,但不少人在这一步就翻车:盲目双击解压、解到错误的顶层目录、或者把 Windows 的 exe 硬拿到 Linux 上跑。解压之前先花两分钟确认包结构,后面每一步都知道该找谁。
2.1 tar.gz 文件怎么解压:先 -t 后 -x,两条命令就够了
# 第一步:只列出内容不落盘,确认顶层目录名和后缀是否可信 tar -tzf OMAP-L138_FlashAndBootUtils_2_29.tar.gz | head -n 40 # 第二步:确认目录结构后再解压,放到自己的工作目录而不是乱解在 home mkdir -p ~/ti && tar -xzf OMAP-L138_FlashAndBootUtils_2_29.tar.gz -C ~/ti # 第三步:用 file 确认压缩包格式,防止实质是 zip 却被改名成 tar.gz file OMAP-L138_FlashAndBootUtils_2_29.tar.gz-t是 test/list,只把压缩包内的文件名列出来不写盘;-z让 tar 处理 gzip 压缩层;-x是 extract;-f指定文件名;-C指定解压目标目录。先-t后-x不只是谨慎,更是排查手段:如果列目录时发现包内直接散落文件而没有顶层目录,解压时会污染当前目录,这时就该先mkdir一个目录再进去解。
包名里已经写了 OMAP-L138_FlashAndBootUtils_2_29,通常解压后会出现同名顶层目录,说明 TI 打包时做了版本隔离,这一点做得比很多第三方 BSP 规范。Linux 下如果报gzip: compressed data not read,先确认 tar 和 gzip 都装齐了,再确认文件下载完整。Windows 用户建议用 7-Zip 或 WSL 里的 tar,不要用资源管理器直接双击,长文件名和符号链接容易出问题。
2.2 包内两类工具:AISgen、sfh 与上板执行的目标侧代码
解压后先读包根目录的 README,这是第一依据。常见的 2.x 包结构大致分三块,目录名在不同小版本里略有出入,但分工是固定的:
| 目录/文件 | 运行位置 | 实际作用 |
|---|---|---|
| AISgen(常见命名形如 AISgen_d600kff) | Windows 主机 | 从 ELF 格式的 .out 生成 .ais 启动镜像 |
| sfh_OMAP-L138.exe 及源码 | 主机(Windows 为主) | 通过 UART 把 .ais 发送给目标,控制加载或烧写 |
| docs 文档目录 | 人读 | 启动流程、AIS 格式、烧写步骤说明 |
| 部分版本含 target 侧示例 | 目标板 | 上板执行的加载器/烧写器,最终被打进 AIS |
认识这两个工具是理解整条链路的关键。AISgen 是"编辑 + 编译"的角色,它把你写的程序、底层初始化、启动介质信息打包成一份 RBL 能解析的脚本;sfh 是"运输"角色,它只负责把这份脚本通过串口完整送到 OMAP-L138 的 RBL 手里。
Linux 上没有官方 AISgen GUI,常见做法是在 Windows 机器上生成 .ais 后把文件传到 Linux 工位,或者把生成参数记录成文档固定下来。主机端 sfh 在 Linux 上要么用包内源码重编,要么用 wine 跑 exe,后者不用改代码但串口映射要对上。
2.3 host 端与 target 端的分工边界
这里有一个容易误解的点:sfh 并不是烧写器本身。它把 AIS 镜像发给 RBL 之后,真正去初始化 DDR、擦除 NAND、写入数据的,是 AIS 里包含的目标端代码。sfh 只负责运输和简单的超时控制。
所以排查问题时要先分边。sfh 报错、卡住、发不出去,是 host 侧问题;sfh 正常退出但板子起不来,是 target 侧 AIS 的问题。AISgen 生成镜像时已经把时钟、DDR 时序、NAND 页大小、ECC 方案全部打进去了,换板卡或者换 flash 器件必须重新生成,这也是后面大多数启动失败的根源。
3. OMAP-L138 的 RBL 与 AIS 镜像:UART 能烧一切的原因
这一章讲机制。不把 RBL 和 AIS 的关系弄清楚,烧写命令出了问题就只能瞎试。OMAP-L138 的启动链其实很短,就两个角色:出厂固化在 ROM 里的 RBL,以及用户提供的 AIS 镜像。
3.1 Boot Mode 与 RBL:上电第一件事是读引脚
RBL 是 OMAP-L138 芯片内 ROM 里的一段引导代码,上电复位的瞬间,它会去采样 boot 引脚的电平组合,根据采样结果决定从哪个外设读取启动镜像。这个过程发生在任何用户代码运行之前,所以它不依赖 flash 里有没有内容。
| Boot 介质 | RBL 行为 | 典型场景 |
|---|---|---|
| NAND Flash | 按 ECC 读取首块数据并校验 AIS 头 | 产品的主启动介质 |
| SPI NOR(Master) | 从片选 0 偏移 0 读取镜像 | 小容量启动、生产调试 |
| NOR(EMIF) | 并行总线直接读 | 老设计或大容量场景 |
| UART | 在 UART0 等待接收 AIS 数据 | 烧写入口、空片恢复 |
| USB | HID 枚举后接收镜像 | 无串口环境调试 |
| EMIFA 异步 | 从异步接口读 | 特殊板卡设计 |
UART boot 默认是 115200 8N1,板卡通过拨码开关把 boot 模式切到 UART 后,RBL 就在等第一个 32 位 AIS 字。这就是 sfh 能接管目标的握手点。注意 boot 引脚只在复位上升沿被采样,切了拨码不按复位,RBL 不会重新读引脚,这是新手最常见的假故障。
3.2 AIS 镜像:一串让 RBL 忙起来的 32 位命令
AIS 全称 Application Image Script,是 TI 定义的一种启动脚本格式。镜像由 32 位字组成,第一个字是固定的魔术字 0x41504954,ASCII 对应 "APIT"。RBL 读到正确的魔术字后,开始逐条解析后面的命令。
这些命令干的事很集中:初始化 PLL 和 DDR、配置 pinmux、把应用数据从串口缓冲区搬到 IRAM 或 DDR 的指定地址,最后执行一条跳转命令进入应用入口。也就是说,一份 AIS 镜像同时携带了“底层配置”和“用户程序”两部分,AISgen 就是把这二者打包的工具。
用 AISgen 生成镜像时需要填的参数包括:器件型号、外部晶振频率、DDR 配置、启动介质、NAND 的页大小和 ECC 强度。任何一个参数和实际板卡不匹配,结果不是 RBL 解析失败,就是镜像加载后跑飞。典型现象是 UART 加载一切正常,换成 NAND boot 后没有任何输出。
3.3 为什么烧写要先走 UART
空板的 NAND 和 SPI NOR 里什么都没有,RBL 从这些介质读不到任何有效镜像,机器动不了。而 UART boot 是 RBL 自带的通路,不需要外部存储有任何内容,这决定了 UART 是唯一的“无中生有”的入口。
实际烧写用的是两阶段法。第一阶段,用 sfh 通过 UART 加载一份烧写器 AIS,这份镜像里包含了目标端 flash 驱动的完整实现;第二阶段,由这份 AIS 里的代码完成擦除和写入,把真正的应用镜像落进 NAND 或 SPI NOR。FlashAndBootUtils 把 AISgen 和 sfh 打包在一起,就是为了让这两个阶段在一套工具里闭环。
4. 用 sfh 串口烧写 NAND 与 SPI NOR:命令和参数照着改
原理落地之后,最关心的就是命令怎么写。sfh 的参数在不同小版本里略有出入,所以正确的第一步永远是先运行一次不带参数的 sfh,让它打印 usage。
4.1 最小可复现的 sfh 烧写流程
# 1) 板卡拨到 UART boot,串口接好,上电复位 # 2) 先不带参数运行,确认本版本 sfh 的参数语法 sfh_OMAP-L138.exe # 3) 只加载执行,不写 flash,先验证镜像能跑 sfh_OMAP-L138.exe -p COM5 -f loader.ais # 4) 烧写 NAND/SPI:老 wiki 里流传的写法,具体选项以包内 README 为准 sfh_OMAP-L138.exe -p COM5 -flash_nouart 2260 -f app.ais-p指定主机上的串口号,Windows 下是 COM 编号,Linux 下重编版本通常是 /dev/ttyUSB0 这种路径;-f指定要发送的 AIS 文件路径。-flash_nouart表示发送完镜像后不期望目标侧再通过 UART 回显,直接进入烧写等待状态,后面跟的 2260 是流传示例里的固定数值,不要凭感觉改,换版本前先看-h输出。
执行顺序不要乱:先拨码,再上电,最后运行 sfh。如果先运行工具再给板子上电,RBL 可能在工具准备好之前就进入超时等待。烧写过程中不要关闭串口终端或者断开电源,NAND 擦写中途断电会留下半写的坏块记录。
4.2 NAND 与 SPI NOR 的差异:ECC、页大小、镜像偏移
同样一份 .ais,烧 NAND 和烧 SPI NOR 在 AISgen 里的配置完全不同,烧写后的故障表现也不一样。
| 项目 | NAND | SPI NOR |
|---|---|---|
| 典型器件 | 2KB 页 + 64B spare 的 SLC | W25Q16/W25Q32 一类 |
| ECC | 常见 BCH4/BCH8,必须和 AISgen 选择一致 | 无 ECC 概念 |
| 镜像起始位置 | 第 0 块开始,坏块要跳过 | 偏移 0 开始 |
| AISgen 关键选项 | 页大小、spare、ECC 强度、时序参数 | SPI 时钟、模式、片选 |
| 烧写后典型故障 | ECC 不匹配,启动即死 | 时钟模式不对,读出乱码 |
NAND 的 ECC 是最大的坑。RBL 读 NAND 时按固定 ECC 方案校验,AISgen 生成烧写镜像时用的 ECC 强度和 RBL 期望的不一致,烧写过程可能正常结束,但复位后 RBL 校验失败,表现为没有任何启动输出。SPI NOR 没有 ECC,但 SPI 的时钟极性和相位如果配置错,读出来的数据会整体错位,现象是镜像头魔术字对不上。
关于坏块,RBL 本身不承担完整的坏块管理,烧写器 AIS 在写入时会做坏块跳过,但应用侧读取时如何映射坏块是设计阶段就要定的,不要在量产阶段才想着补。
4.3 烧写失败先查这四个位置
烧写失败时,见过太多人反复换波特率、换串口线,其实问题就集中在这四个地方。
第一,COM 口被占用。sfh 打不开串口或者立刻退出,先关掉其他串口工具和 IDE 的串口终端。第二,板子没进 UART boot。拨码切了但没复位,或者板卡默认 boot 模式被别的跳线覆盖。第三,AIS 配置和硬件不匹配。换了晶振或 DDR 没重新生成镜像,加载成功但马上跑飞。第四,供电或复位不稳,烧写过程中目标侧掉电,SPI 和 NAND 会留下半写状态。
提示:sfh 卡在等待握手时,先用 115200 8N1 的串口工具打开目标串口并按复位,如果能观察到 RBL 开始等待数据的短暂窗口,说明 UART boot 活着,问题在 sfh 的配置;如果完全没有反应,先查拨码和复位。
5. 不插 JTAG 验证烧写结果:用 AIS 里的 GPIO 打点定位启动进度
烧写完最怕的是“不知道写到哪一步才坏的”。UART 有输出还好,NAND 和 SPI 启动时 RBL 阶段是静默的,串口看不到任何东西。这里有一个实用技巧:做一个最小打点镜像,用 GPIO 点灯来标记启动进度。
/* 打点镜像:AIS 初始化完成后进入 main,把 GPIO1_12 拉高再拉低 */ void main(void) { volatile unsigned int *gpio_dir = (unsigned int *)0x01E26010; volatile unsigned int *gpio_data = (unsigned int *)0x01E26014; *gpio_dir &= ~(1u << 12); /* GPIO1_12 设为输出,清方向位 */ *gpio_data |= (1u << 12); /* 拉高,标记 RBL 已跳进应用 */ for (volatile int i = 0; i < 1000000; i++) ; /* 停留一段时间便于观察 */ *gpio_data &= ~(1u << 12); /* 拉低 */ for (;;) ; /* 停住,方便示波器抓波形 */ }OMAP-L138 的 GPIO 基址在 0x01E26000,bank1 的方向寄存器在 0x01E26010,数据寄存器在 0x01E26014,代码里的引脚按你板子原理图上的 LED 实际连接来改。这个文件编译成 ELF,用 AISgen 分别生成“UART 加载版”和“烧进 NAND/SPI 的最终版”。
验证逻辑很简单:拨到 NAND boot 复位后,LED 闪了一次,说明 RBL 已经成功解析 AIS 并跳进了用户代码,问题在后级的应用初始化;LED 完全没反应,问题在 RBL 阶段,重点查 ECC、镜像偏移、boot 引脚。这一步能把定位范围从整条启动链缩小到具体环节,比盲看串口乱码高效得多。
和打点配合的还有一个离线核对方法:烧写完成后,把 AISgen 输出的原始文件与从 flash 读出的内容做一次 hexdump 对比。sfh 的判断依赖目标侧回显或超时,离线对十六进制能抓住“写进去了但内容被 ECC 改写”这类隐蔽问题。hexdump -C重点看文件头和魔术字 0x41504954 所在位置,镜像偏移多一个字节都能一眼看出来。
下次调启动问题,先分清 RBL 阶段和 AIS 阶段,再决定是查 ECC 还是查跳转,一两个 GPIO 打点能省下一个下午。
本文还有配套的精品资源,点击获取