在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。
在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader程序。
启动过程
Bootloader启动大多数都分为两个阶段。
第一阶段主要包含依赖于CPU的体系结构硬件初始化的代码,通常都用汇编语言来实现。这个阶段的任务有:基本的硬件设备初始化(屏蔽所有的中断、关闭处理器内部指令/数据Cache等)。为第二阶段准备RAM空间。
如果是从某个固态存储媒质中,则复制Bootloader的第二阶段代码到RAM。
设置堆栈。
在第一阶段中为什么要关闭Cache?通常使用Cache以及写缓冲是为了提高系统性能,但由于Cache的使用可能改变访问主存的数量、类型和时间,因此Bootloader通常是不需要的。
跳转到第二阶段的C程序入口点。
第二阶段通常用C语言完成,以便实现更复杂的功能,也使程序有更好的可读性和可移植性。这个阶段的任务有:
初始化本阶段要使用到的硬件设备。
检测系统内存映射。
将内核映像和根文件系统映像从Flash读到RAM。
为内核设置启动参数。
调用内核。
引导加载程序是系统加电后运行的第一段软件代码,称之为Bootloader。BootLoader是Booter和Loader的合写:前者意味着要初始化嵌入式系统硬件使之运行起来,至少是部分运行起来,与PC机中的BIOS作用相似;后者意味着将嵌入式操作系统映像加载到内存中,并跳转过去运行。
将硬盘MBR中的BootLoader读到系统的RAM中,然后将控制权交给OS BootLoader。BootLoader的主要运行任务就是将内核映象从硬盘上读到 RAM 中,然后跳转到内核的入口点去运行,也即开始启动操作系统。
看门狗,又叫watchdog timer,是一个定时器电路,一般有一个输入,叫喂狗(kicking the dog/service the dog),一个输出到MCU的RST端,MCU正常工作的时候,每隔一段时间输出一个信号到喂狗端,给 WDT清零,如果超过规定的时间不喂狗(一般在程序跑飞时),WDT定时超过,就会给出一个复位信号到MCU,使MCU复位。防止MCU死机. 看门狗的作用就是防止程序发生死循环,或者说程序跑飞。
主引导记录(MBR,Master Boot Record)是位于磁盘最前边的一段引导(Loader)代码。它负责磁盘操作系统(DOS)对磁盘进行读写时分区合法性的判别、分区引导信息的定位,它由磁盘操作系统(DOS)在对硬盘进行初始化时产生的。
固件(firmware)一般存储于设备中的电可擦除只读存储器EEPROM(Electrically Erasable Programmable ROM)或FLASH芯片中,一般可由用户通过特定的刷新程序进行升级的程序。一般来说,担任着一个数码产品最基础、最底层工作的软件才可以称之为固件,比如计算机主板上的基本输入/输出系统BIOS(Basic Input/output System),在以前其实更多的专业人士叫它固件。
Nordic文档总结
基本引导加载程序将启动位于内存中特定位置的应用程序,因此您可以使用此类引导加载程序,例如,在启动应用程序之前在多个应用程序之间切换或初始化设备。
引导加载程序模块提供的最重要功能是设备固件更新(DFU)功能。 DFU的主要特点是:
- 更新应用程序,SoftDevice和bootloader,
- 来自经过身份验证的来源(签名更新)的更新
- 降级预防,
- 硬件兼容性验证,
- 各种运输:(BLE,UART,USBD),
- 支持使用和不使用SoftDevice进行应用程序更新,
- 支持使用SoftDevice独立固件替换SoftDevice相关固件,
- 支持使用SoftDevice相关固件替换SoftDevice独立固件。
下图显示了引导加载程序模块的层架构:、
(BootLoader)引导加载程序模块负责:
- 启动到应用程序,
- 激活新固件,
- 可选地,进入DFU模式,激活DFU传输并传送新固件,
- 喂养看门狗定时器
Bootloader Settings页面
非易失性存储器中的页面(请参阅存储器布局)用于保存引导加载程序和DFU信息。 设置页面包含以下信息:
- 当前固件 - 大小,CRC-32,
- 待定固件 - 尺寸,CRC-32,
- 固件更新的进度,
- 固件激活的进度,
- 当前固件版本(应用程序和引导程序),
- 运输特定的数据。
固件激活
固件激活是固件更新过程的最后一步。 根据启动期间读取的设置页面中的信息触发激活。 固件激活涉及复制新固件以代替退出的固件,并更新设置页面以允许新固件启动。 引导加载程序可确保复制是电源故障安全的。 在更新引导加载程序的情况下,MBR功能用于执行电源故障安全复制(SD_MBR_COMMAND_COPY_BL)。
DFU模式(Device Firmware Upgrade)
在DFU模式下,引导加载程序激活DFU传输,设备已准备好接收新固件。引导加载程序在以下条件下进入DFU模式:
- 没有有效的应用程序。
- SoftDevice已激活,并且存在有效的应用程序。在这种情况下,引导加载程序期望主机可以请求应用程序更新。
- 进入DFU模式由其中一个可选来源触发:
- 按钮(NRF_BL_DFU_ENTER_METHOD_BUTTON)
- 引脚复位(NRF_BL_DFU_ENTER_METHOD_PINRESET)
- GPREGRET寄存器中的特殊值(NRF_BL_DFU_ENTER_METHOD_GPREGRET),
- 从写入设置页面的应用程序请求(NRF_BL_DFU_ENTER_METHOD_BUTTONLESS)。
进入DFU模式后,将启动不活动计时器。在计时器到期时,引导加载程序将重置。在任何DFU活动上重新启动不活动计时器。默认情况下,不活动超时设置为NRF_BL_DFU_INACTIVITY_TIMEOUT_MS。如果在SoftDevice激活后进入DFU模式,则超时设置为NRF_BL_DFU_CONTINUATION_TIMEOUT_MS。
启动应用程序
根据设置页面中的信息,引导加载程序确定应用程序是否存在以及它位于何处。 引导加载程序在启动之前检查应用程序的完整性。 可选地,在某些情况下可以跳过完整性检查以减少启动时间(NRF_BL_APP_CRC_CHECK_SKIPPED_ON_GPREGRET2,NRF_BL_APP_CRC_CHECK_SKIPPED_ON_SYSTEMOFF_RESET)。 如果出现下列情况之一,则引导加载程序进入DFU模式:
- 没有安装应用程序,
- 完整性检查失败,
- 没有设置页面。
编程引导加载程序
在系统启动期间,如果安装了引导加载程序,则主引导记录(MBR)负责启动引导加载程序。 为此,MBR必须知道引导加载程序的起始地址。 此起始地址在MBR本身或UICR.BOOTLOADERADDR中定义。 编程引导加载程序时,必须将其设置为正确的值。 有关更多详细信息,请参阅S132 SoftDevice规范。
对引导加载程序进行编程需要执行以下步骤:
- 擦除设备。
- 编写SoftDevice。 有关说明,请参阅编程SoftDevices。
- 编译引导加载程序。
- 编程引导加载程序并写入UICR.BOOTLOADERADDR。 有关Segger Embedded Studio,Keil,IAR和nrfjprog的说明,请参阅以下部分(如果您使用的是GCC)。
设备固件更新过程
执行设备固件更新需要两个设备:DFU目标和DFU控制器。 DFU目标是使用新固件映像更新的设备,该固件映像可以包含新应用程序,SoftDevice,引导加载程序或SoftDevice和引导加载程序的组合。 DFU控制器是传输镜像的设备。 例如,DFU控制器可以是运行app的移动电话,也可以是与nrfutil一起使用的nRF5开发套件。
DFU目标是运行具有至少一个活动DFU传输的DFU的设备。 它可以是DFU模式下的引导加载程序,也可以是后台运行DFU的应用程序(DFU over TFTP示例)。 然后,DFU控制器可以启动固件映像的传输,该固件映像由DFU目标接收和验证。 如果映像有效,则设备将重置,引导加载程序将激活映像以替换现有固件。 根据映像的类型,它可能会替换应用程序,SoftDevice,甚至是接收更新的当前引导加载程序。 有关图像存储位置及其复制方式的详细信息,请参阅双库和单库更新。
作为DFU控制器,您可以使用以下Nordic工具:
- nrfutil (version 2.2.0 or later)
- nRF Connect for Desktop
- Nordic's mobile apps, such as nRF Connect for Mobile.
以下流程图显示了必须在DFU目标中实现的固件更新所需的步骤:
固件更新过程的事件和过程与所使用的传输协议无关。 DFU模块包含BLE,UART和USB CDC的实现(请参阅DFU协议)。 DFU控制器可以通过在DFU传输上发送相应的消息来触发事件。
DFU程序
nrfutil工具生成一个包含一个或两个更新的zip文件(请参阅使用nrfutil创建固件包)。 单个更新包含具有新固件详细信息和二进制数据的init数据包。 DFU控制器发送init数据包并等待DFU目标的确认。 DFU目标验证init数据包并以结果响应。 成功验证后,DFU控制器发送二进制数据。 一旦DFU目标接收到二进制数据,就会执行后验证。 成功验证后,DFU目标将重置,引导加载程序将激活新固件。 如果zip文件包含两个更新,则DFU控制器期望DFU目标进入DFU模式并尝试通过建立连接并发送第二个init数据包来执行第二次更新。 从DFU控制器应用程序的用户的角度来看,即使以两个步骤执行,这种更新也被视为单个更新。
单个更新可能包含以下元素:
- 应用程序,
- 一个SoftDevice,
- 引导程序,
- 引导程序和SoftDevice。
如果update必须包含应用程序和SoftDevice(以及引导加载程序),则zip包中包含两个更新。 如果引导加载程序依赖于Softdevice(请参阅Bootloader依赖项),则包含Softdevice update的软件包可能包含引导加载程序。
完成第一步后,激活新的SoftDevice(和引导加载程序),应用程序可能仍然有效但由于SoftDevice依赖性损坏而无法运行。 必须在第二步中更新它。 使用SoftDevice激活软件包后,引导加载程序将进入期望应用程序更新的DFU模式。 由于应用程序更新是可选的(在SoftDevice次要版本更新后不需要),因此引导加载程序中的不活动超时设置为与默认值(NRF_BL_DFU_CONTINUATION_TIMEOUT_MS)不同(更短)的值。