4. 启动ROM与引导加载器
在VxWorks的启动链中,bootrom是上电后最先获得执行权的一段固件级代码。它通常被烧录在目标板的NOR Flash、EPROM或通过ROM启动的存储介质中,由CPU复位向量直接跳入。bootrom的核心使命并不是运行完整的VxWorks应用,而是完成最小化的硬件初始化、建立可用的运行环境,并最终把控制权交给真正的VxWorks镜像或网络引导流程。理解bootrom,关键在于把它看作“启动链的第一级加载器”,而不是一个缩小的操作系统。
bootrom到底承担什么职责
bootrom通常由VxWorks提供的bootrom工程编译生成,内部包含引导加载器(bootloader)和可选的VxWorks引导镜像。它的职责可以归纳为四类:第一,CPU与基础外设初始化,包括异常向量、时钟、内存控制器、串口和定时器;第二,建立最小运行环境,使C代码可以执行,并初始化栈、堆和必要的全局数据结构;第三,提供引导参数与下载通道,例如通过串口、以太网或USB接收VxWorks镜像;第四,加载并跳转到VxWorks入口,完成从固件到操作系统的交接。
与PC上的BIOS/UEFI不同,bootrom通常与目标板硬件强绑定,其内存映射、串口基地址、Flash扇区布局都需要在工程配置中明确指定。因此,bootrom的构建不是“编译一个通用程序”,而是“为特定板卡定制一段启动固件”。
bootrom的构建流程
在Tornado或Workbench环境下,bootrom的构建通常从创建一个“bootrom工程”开始。工程会引用BSP(板级支持包)中的config.h、configAll.h以及sysLib.c、sysSerial.c等文件。构建流程可以概括为:选择BSP → 配置引导参数 → 选择镜像格式 → 编译链接 → 生成可烧录文件。
具体来说,第一步是在Workbench中新建“Boot ROM”工程,选择与目标板匹配的BSP,例如pentium、arm或ppc系列。第二步是配置引导参数,这些参数最终会写入bootrom的默认boot line中。第三步是选择bootrom的格式:常见的有bootrom.bin(纯二进制)、bootrom.hex(十六进制)、bootrom_uncmp(未压缩)和bootrom_comp(压缩)。压缩格式可以节省Flash空间,但启动时需要先解压到RAM。第四步是编译链接,生成bootrom文件。第五步是通过烧录器或Flash编程工具将bootrom写入目标板。
一个典型的bootrom工程配置片段如下:
/* config.h 中的关键引导参数 */
#define DEFAULT_BOOT_LINE \
"motetsec(0,0)host:vxWorks h=192.168.1.100 e=192.168.1.50 u=target pw=vxworks"
/* 内存配置 */
#define LOCAL_MEM_LOCAL_ADRS 0x00000000
#define LOCAL_MEM_SIZE 0x04000000 /* 64MB */
/* 串口配置 */
#define CONSOLE_BAUD_RATE 115200
#define CONSOLE_TTY 0
这段配置说明:目标板通过motetsec网卡引导,主机IP为192.168.1.100,目标板IP为192.168.1.50,用户名为target,密码为vxworks,镜像文件名为vxWorks。内存起始地址为0x00000000,大小为64MB。串口波特率为115200。这些参数在bootrom启动后可以通过串口命令行修改,但默认值来自编译时的配置。
引导参数配置与交互
bootrom启动后,通常会在串口输出一段启动信息,并进入一个简单的命令行界面。这个界面支持查看和修改引导参数,例如使用p命令打印当前boot line,使用c命令修改boot line,使用@命令启动引导。引导参数的核心是boot line,它决定了“从哪里加载、加载什么、加载到哪”。
boot line的典型格式为:device(unit,flags)host:file h=hostIP e=targetIP u=user pw=password。其中device是引导设备,如motetsec、ata、tffs;host是主机名或IP;file是镜像文件名;h、e、u、pw分别指定主机IP、目标IP、用户名和密码。如果使用串口下载,则设备名可能是tsfs或serial,此时需要指定波特率和文件路径。
h和e留空,由bootrom自动获取。
与VxWorks镜像的衔接机制
bootrom完成硬件初始化和参数解析后,会进入镜像加载阶段。如果引导设备是以太网,bootrom会通过TFTP或FTP协议从主机下载vxWorks文件到目标板RAM的指定地址。下载完成后,bootrom会校验镜像的头部信息,确认入口地址和加载地址。然后,bootrom关闭中断、设置栈指针,并跳转到VxWorks的入口点。
VxWorks镜像的入口通常是usrInit或sysInit。在跳转之前,bootrom需要确保内存中已经正确放置了镜像,并且CPU处于可执行状态。跳转后,VxWorks会重新初始化内存管理、中断控制器和外设驱动,因为bootrom的初始化只是“最小化”的,不能直接复用。例如,bootrom可能只初始化了一个串口用于控制台,而VxWorks需要初始化所有串口、网卡和文件系统。
衔接过程中最容易出问题的环节是内存地址冲突。如果bootrom的加载地址与VxWorks镜像的链接地址不一致,跳转后就会跑飞。因此,在构建VxWorks镜像时,必须确保其链接地址与bootrom的加载地址匹配。通常,bootrom会将镜像加载到0x00100000或0x00200000等高端地址,而VxWorks镜像的链接脚本也会指定相同的入口地址。
| 阶段 | 执行主体 | 关键动作 | 输出/结果 |
|---|---|---|---|
| 上电复位 | CPU | 取复位向量,跳入bootrom | bootrom开始执行 |
| 硬件初始化 | bootrom | 配置时钟、内存、串口 | 串口可输出,内存可读写 |
| 参数解析 | bootrom | 读取boot line,确定引导方式 | 下载通道就绪 |
| 镜像加载 | bootrom | 通过TFTP/FTP下载vxWorks | 镜像位于RAM指定地址 |
| 跳转交接 | bootrom → VxWorks | 关闭中断,设置栈,跳转入口 | VxWorks开始执行 |
实际构建中的注意事项
在实际工程中,bootrom的构建往往需要反复调试。常见问题包括:串口无输出,通常是波特率或引脚配置错误;网络下载失败,可能是IP地址冲突或TFTP服务未启动;跳转后无响应,多半是加载地址与链接地址不匹配。解决这些问题的关键是先确认bootrom本身能正常运行,再检查引导参数和镜像地址。
此外,bootrom的版本管理也很重要。不同批次的板卡可能使用不同的Flash芯片或内存布局,因此bootrom工程需要与硬件版本对应。建议在bootrom启动信息中打印版本号和编译时间,便于现场排查。对于量产设备,通常会将bootrom和VxWorks镜像一起烧录到Flash中,此时bootrom还需要支持从本地Flash加载镜像,而不是依赖网络。
总结来说,bootrom是VxWorks启动链中承上启下的关键环节。它把裸机硬件变成可加载镜像的环境,又把控制权交给完整的VxWorks内核。掌握bootrom的构建流程、引导参数配置和镜像衔接机制,是进行VxWorks板级开发和系统部署的基础能力。