在嵌入式系统领域,Bootloader 是一个至关重要的软件程序,它通常存储在芯片的非易失性(如闪存)中。其主要功能是在系统上电后,负责初始化系统硬件,并将操作系统或应用程序加载到内存中执行。下面,我们将详细探讨 Bootloader 的工作流程、主要功能,以及其发展进化的历程。

- 硬件初始化:Bootloader 启动后,首先会对处理器、时钟、内存和外设等硬件资源进行初始化,确保系统处于合适的状态,为后续操作做好准备。
- 引导设备选择:它需要检测可用的引导设备,如闪存、外部存储器或串口等,并从中选择一个作为加载操作系统或应用程序的来源。
- 加载操作系统或应用程序:依据预定义的引导策略,Bootloader 从选定的引导设备中读取操作系统镜像或应用程序,并将其加载到内存中。
- 执行加载的程序:程序加载到内存后,Bootloader 会跳转到该程序的入口点,启动执行。对于操作系统,这意味着将控制权移交给操作系统内核;对于应用程序,则开始执行其主函数。
- 错误处理和回滚:Bootloader 通常具备错误处理机制,在发生错误时执行相应操作,如跳转到备用引导设备或恢复到出厂设置状态。
- 升级支持:部分 Bootloader 还支持固件升级,允许通过特定接口或协议更新系统固件,无需物理访问设备。
- 古老的烧录方式:20 世纪 80 年代,以 51 为代表开始广泛应用于工业控制、家电等行业。起初,将可执行程序写入单片机内部 ROM 并非易事,且成本较高,需要依赖专门的烧录设备。受半导体技术与工艺限制,ROM 烧写大多需要高压,这种状况一直持续到 2000 年左右。
- ISP 与 ICP 烧录方式:随着低压电可擦写 ROM 的成熟,单片机开始集成可通过数字电平直接读写的存储介质,实现了在系统或在电路直接烧录程序,即 ISP(In System Programming)或 ICP(In Circuit Programming)。从广义上讲,两者区别不大,但严格来说,ISP 要求单片机驻留有专门程序与上位机通信,接收固件数据并烧录到自身 ROM,需具备基本的系统电路;而 ICP 可将 视为可供外部读写的存储电路,无需预置程序,也无需芯片处于可运行状态。以 AT89S51 为代表的支持 ISP 或 ICP 的芯片,让很多人摆脱了对的依赖,降低了单片机入门门槛。
- 更方便的 ISP 烧录方式
- 串口 ISP:2005 年前后,STC 单片机凭借串口 ISP 功能受到广泛关注。它进一步降低了单片机学习门槛,即使电脑并口逐渐减少,通过 USB - TTL 串口也能方便地进行烧录。如今,包括 STM32 全系列在内的很多单片机都支持串口 ISP,使其成为一种标配的程序烧录手段。
- 各种 USBISP:当固件体积较大时,串口 ISP 的速度成为短板。因此,一些单片机配有专门的 USBISP 器,如 AVR、C8051F、MSP430 等。然而,这些烧录方式存在依赖专门上位机或器硬件、价格较高、时需附加额外操作等弊端。
Bootloader 是一段存储在 ROM 中的程序,主要实现以下 4 个功能:
- 通过某种途径获取要烧录的固件数据。
- 将固件数据写入到 ROM 的 APP 区中。
- 跳转到 APP 区运行,引导烧录进去的用户程序启动。
- 在整个过程中,提供必要且友好的人机交互界面。
- 带 Shell 命令行的串口 BL:用户通过超级终端、SecureCRT 或 Xshell 等串口终端输入命令 “program”,BL 接收到命令后等待接收固件文件数据,串口终端通过文件数据传输协议将固件数据传给 BL,BL 将数据写入 ROM 的 APP 区,然后跳转到 APP 区运行程序。
- 插 SD 卡即烧录的 BL:将待烧录的固件拷贝到 SD 卡中,插入卡槽,BL 检测到 SD 卡插入后,搜索卡中的 BIN 文件,将其数据读出写入 ROM 的 APP 区,跳转到 APP 区运行程序。
- 芯片体系架构要支持:单片机程序的开头是中断向量表,包含程序栈顶地址和 Reset 程序入口。从 BL 向 APP 跳转时,APP 程序必须有自己的中断向量表,且单片机体系架构要允许中断向量表重定向。传统 51 单片机的中断向量表只能放在 ROM 开头,不支持 BL;而 STC 的 51 单片机通过硬件架构改进,实现了 BL 功能。此外,AVR 单片机通过配置熔丝位可控制复位入口地址以及 BOOT 区的大小和开始地址;STM32 则在 NVIC 控制器中提供了中断向量表偏移量的相关配置,程序可放置在 ROM 的任何位置运行。
- ROM 要支持 IAP:在 BL 获取到固件数据后,需要将其写入 ROM 的 APP 区,因此单片机需支持 IAP(In Application Programming)操作,即在程序运行过程中对自身 ROM 进行擦除和编程操作。支持串口 ISP 的单片机通常都支持 IAP 功能。
- APP 程序的配套修改:为使 BL 能顺利引导 APP 程序运行,APP 程序开发时需进行相应修改,主要包括修改中断向量表的开始地址和对中断控制器的配置。以 STM32 为例,使用不同开发环境时,需对相关文件进行修改,并配置 NVIC 的中断向量表偏移量。
- BL 中的跳转代码:跳转代码是 BL 的关键,直接影响 APP 程序能否正常运行。以 STM32 为例,其 jump_app 函数代码用于实现从 BL 到 APP 的跳转。
- BL 的实现与延伸(串口传输固件):在串口传输固件的过程中,会涉及串口通信协议、固件数据暂存和校验等问题。串口通信协议和文件传输实现的内容较为繁杂,可在相关章节深入学习。为保证固件数据的正确性,通常会对数据进行整体校验,并在文件中加入校验码。虽然可以不暂存固件直接实时烧写,但建议在成本允许的情况下对固件进行整体校验,并适当扩大 ROM 容量,以应对 APP 区固件损坏的情况。
- 10 米之内隔空烧录 OTA(On the Air):“隔空烧录” 源于一个 IoT 项目,用于解决空调外机硬件升级嵌入式程序的困难。通过改进的 AVRUBD 通信协议,结合版上位机软件,实现了用手机进行 “隔空烧录”。
- BL 的分散烧录:在复杂系统架构(如主 MCU + CPLD + 通信协处理器 + 采集协处理器)中,为解决批量生产时烧录程序繁琐的问题,引入了 “BL 的分散烧录” 机制。将所有固件拼装成一个大固件,预先烧录到外扩 ROM 中,主 MCU 烧录好 BL 后,在 PCBA 首次上电时,BL 从外扩 ROM 中读取大固件,并分离出各个小固件,分别烧录到各个部件中。
- Bootpatcher:一般情况下,Bootloader 在 ROM 中的位置位于 APP 区前面。但在某些特殊情况下,若 APP 必须放在 0X08000000 位置,可将 BL 放在 APP 后面,称为 Bootpatcher。APP 运行时,可跳转到 Bootpatcher 接收固件文件,校验后写入 APP 区,再跳转到 APP 区或重启。不过,这种做法有风险,APP 区烧录失败可能导致产品变砖。
- APP 反烧 BL:当 BL 需要升级时,除了使用 JLINK,还可在 APP 程序中实现接收固件文件、暂存校验并烧录到 BL 区。这种逆向思维的方法虽有一定风险,但通常可行。