一、 Device Management Update client
- 本节介绍如何通过Device Management Update client 来接收更新。为了设置设备上的客户端,我们需要准备好 固件镜像 和 引导程序,同时还需要一个独一无二的ID和证书。
固件镜像应该包括:操作系统、更新客户端、用户程序。
引导程序会读取更新客户端写在设备上的新的固件镜像,然后检查该镜像是否有错误。
引导程序会检查每个新固件镜像的完整性,然后把最新的那一个复制到active application memory region。 - 如果设备是受支持的参考设备,我们可以使用Git 中的客户端软件、引导程序以及示例代码为该设备创建合适的映像。
如果您的设备不是受支持的参考设备之一,则必须先将设备管理客户端移植到设备。 - 除了固件镜像和引导程序之外,我们还需要一个证书。如果只是用于开发,我们可以使用清单工具、通过我们提供的一个私钥来生成一个开发人员证书。
- 更新客户端需要两种类型的设置:
①匹配于设备类型的、独一无二的ID
②用于验证更新的整数 - 真实性证书:
更新客户端要验证证书和该证书“指纹”用于授权更新。这两者存储为一个证书,并且以“指纹”作为密钥。
真实性证书包括一个设备信任的公钥。这个公钥仅用于设备管理更新(安全考虑,万一该公钥泄露,不安全的只限制于设备管理更新)。 - 清单工具可以用于在开发过程中生成真实性证书,但不应该把这些证书用于实际生产过程。
- 在接受一次更新之前,设备的更新客户端会用公钥来计算是否信任更新源(它会通过公钥签名分析更新清单)。为此我们需要有一个公钥用于分析,因此在设备制造时或初始化固件中安装一个公钥。
- 您可以通过以下两种方式之一安装设备标识符和真实性证书:
①使用update_default_resources.c以开发者模式编码。
②在出厂中安装。 - 为了存储更新镜像,更新客户端使用块设备存储(即扩展SD卡)来存储,该SD有使用软件一次性编程(Software One Time Programmed)编号生成的信任根。
- 满足更新的设备的要求:
设备必修实现平台抽象层(PAL),包括:
①设备管理客户端运行于设备上
②存储区的定义:
a. 要运行Bootloader,而不是常规的Mbed OS程序
b. 用户申请
c. 申请前要有用于存储新固件映像的一个或多个位置。可以在外部存储上。 - 移植Bootloader参考。
- 为了保证更新适用于设备,设备更新管理用两种附加的独一无二的ID来标识设备类型。
①供应商ID(Vendor ID):
用供应商ID的有:设备更新管理在分析清单时;设备更新管理服务,用于验证只有与特定域名关联的帐户才能签署相应供应商ID的清单。
供应商ID是静态的,它不会在固件的生命周期中发生变化,因此通常可以将其构建到固件映像中。
②类ID(Class ID):
设备管理更新与供应商ID一起使用设备类来检查清单是否与设备兼容。
- 更新一个固件,我们需要这三样东西:
①Bootloader:
当MCU启动的时候,它会自动从起始地址处开始执行。在多数Mbed板上该地址为闪存起始处0x0。Bootloader就放在这个地方,以便设备启动的时候它可以获得控制权。BootLoader从来不会更新。
②元数据头(metadata header):
包括固件的一些信息,让BootLoader在加载固件前分析固件。
在两个条件下从固件镜像生成元数据头:
a. 构建初始固件镜像时,构建工具会生成元数据头,并将固件镜像、BootLoader、元数据头合并为一个大型二进制文件。
b. 当更新客户端进行固件更新时,更新客户端会为新的候选固件镜像生成元数据头。
③固件镜像:包括操作系统、更新客户端、用户应用程序
- 更新客户端把新的固件写到一个BootLoader能访问的地方。BootLoader首要任务是检查当固件写入的时候,没有发生任何错误。为此,BootLoader要进行以下操作:
①通过计算镜像的哈希值,并且将其和元数据头中的对比,来检查活动固件的完整性。
②处理新固件:
a. 通过哈希值来检查新固件镜像的完整性。
b. 如果存在更加新、可用的镜像,BootLoader将最新的镜像拷贝到激活应用的内存区域。
③将控制权交给二进制应用程序的开头。新的应用程序和更新客户端获得控制权,并且可以接受下一次更新。 - 应用程序中的更新客户端一般处于非激活状态,直到收到来自它一个更新源的通知。我们将LwM2M用于清单,HTTP用于固件。可以从设备管理更新服务器推送一个通知,该通知是这次更新的清单。接着,更新客户端会进行以下操作:
①下载新的清单(如果通知没有清单)
②验证清单的真实性,更新可用性。
③解析清单获得固件的URI。
④从更新源中的一个获取固件。
⑤将固件写进存储器中的一个空闲固件位置。
⑥重启并且把控制权交给BootLoader。 - Bootloader所做的:
①在重启之后接管控制权。
②检查当前活动固件完整性(通过哈希值)。
③查找系统中的可用固件。
④选择时间戳最近的那一个固件。
⑤检查存储空间中的镜像的完整性。
⑥如果存储空间中的镜像可用,将镜像拷贝到激活应用的区域。
⑦将控制权交给当前激活固件。 - 当更新功能可用时,固件中的更新客户端做以下操作:
①从它更新源中的一个接收通知。
②下载新的清单,解析得到固件URI。
③从一个更新源获取固件。
④将固件写进SD卡中的存储区域,作为候选固件镜像。
⑤重启,将控制权交给BootLoader。 - 如果使用的是SOTP,BootLoader期望有如下内存布局:
+--------------------------+ | | | | | | +--------------------------+ | | | | | | | Active App | | | | | | | +--------------------------+ <-+ application-start-address | | |Active App Metadata Header| | | +--------------------------+ <-+ update-client.application-details | SOTP_2 | +--------------------------+ <-+ sotp-section-2-address | SOTP_1 | +--------------------------+ <-+ sotp-section-1-address | | | Bootloader | | | | | +--------------------------+ <-+ 0
二、 Server side
- 本节介绍固件清单,清单工具和更新活动。
固件清单编码设备用于决定更新的信息,例如是否信任和接受更新,以及何时以及如何应用更新。
清单工具用于创建,签名和上传这些清单。
您可以使用更新活动来定义哪些设备接收特定更新以及安装的固件镜像。 - 清单工具根据以下数据创建:
用于清单签名和匹配证书的私钥
使用的签名和加密类型
当前时间戳
制造商ID
设备类ID
有效负载(例如固件),清单工具据此来创建有效负载的摘要
设备能够获得该有效负载的URL
设备存储有效负载的存储标识符 - 清单已签名,以便设备可以验证是否是他们信任更新的作者; 固件更新的权限,完整性和真实性不依赖于传输。
- 清单工具可以轻松创建,签署和上传清单。
- 一个更新操作(Update campaign)定义那个或哪些设备可以收到固件更新。更新操作围绕发送到设备的清单和过滤器构建,该过滤器确定哪些设备接收清单。
- 更新操作过程中可能遇到的问题排查。
三、 Security
- ARM 提供安全的固件更新解决方案,该安全模型描述了系统内的这些职责和关系。
- Trust Anchor:在生产时安装在设备上的公钥,设备完全信任特定任务。您不应该替换,撤销或过期Trust Anchor。
- Trust Delegate:由Trust Anchor或Trust Delegate签名的公钥。最终,每个授权链必须以Trust Anchor结束。您可以随时替换,撤销或终止Trust Delegate。