嵌入式Linux-固件更新的机制是什么?

11

我考虑在嵌入式Linux项目(一个工业应用)中开发Yocto项目,并对具有嵌入式Linux经验的人有一些问题 - 如果有Yocto经验就更好了。只需要了解固件更新中通常正在进行的工作。

我有一些要求,包括身份验证、安全通信协议、如果更新失败需要回滚某种类型的功能。此外,如果有一种逐步释放整个设备批次的补丁的方法,那也很有趣,因为我想避免在现场出现被砖化的设备。

你们今天如何向现场设备部署更新/补丁 - 开发它需要多长时间?是否还有其他要考虑的因素?

3个回答

16

虽然你肯定可以使用rpm,deb或ipk进行升级,但我更喜欢的方式(至少适用于小到合理大小的镜像)是在闪存上存储两个镜像,并且只更新完整的rootfs镜像。

如果我要开始使用OpenEmbedded / Yocto Project来工作嵌入式Linux,今天我可能会看一下meta-swupdate。

我自己和多个客户使用的东西更像这样:

  • 一个容器升级文件,其中包含另一个tarball(以下称为升级文件),升级文件的md5sum以及通常是gpg签名。
  • 存储在运行映像中的更新程序脚本。此脚本负责解压缩升级文件的外层容器,使用md5sum验证升级文件的正确性并常常验证密码签名(通常基于gpg)。如果升级文件通过了这些测试,更新程序脚本将在升级文件中查找升级脚本,并执行它。
  • 升级文件中的升级脚本执行实际的升级,即通常重写非运行映像,提取和重写内核,并且如果这些步骤成功,则指示引导加载程序使用新编写的内核和映像代替当前运行的系统。

在升级文件中执行实际升级的脚本的好处是,您可以在未来的单个步骤中执行所需的任何操作。我制作了特殊的升级映像,用于升级附加调制解调器的FW,或从中提取一些额外的诊断信息而不是执行实际升级。这种灵活性将在未来得到回报。

为了使系统更加可靠,引导加载程序使用称为bootcount的功能,该功能可以记录启动尝试的次数,如果此数字超过阈值(例如3),则引导加载程序选择启动其他镜像(因为配置为启动的镜像被认为存在故障)。这确保了,如果映像完全损坏,则将自动启动存储的另一个镜像。

这种方案的主要风险是您升级到一个其升级机制已经损坏的镜像。通常,我们还会在引导程序中实现某种恢复机制,以便引导程序可以重新刷写全新的系统;虽然这种救援机制通常意味着数据分区(用于存储配置、数据库等)也将被擦除。这部分出于安全考虑(不泄露信息),另一部分是为了确保在进行此项操作后,系统状态将完全为我们所知(当此操作由远在他乡的经验不足的技术人员进行时,这是一个巨大的好处)。


我想在Edison上使用meta-swupdate,但这是我第一次使用任何更新代理。有没有步骤可以遵循来实现它? - Sandeep

1
如果你有足够的闪存,可以这样做。创建两个完全相同的分区,一个用于实时系统,另一个用于更新。让系统通过安全方法拉取更新的镜像,并直接将其写入另一个分区。可以简单地插入一个带有锁定板的USB闪存驱动器(物理安全),或者使用适当的主机和用户密钥进行ssh/scp。使用sfdisk交换分区,或仅在正确下载和写入镜像的情况下编辑引导加载程序设置。如果没有,则什么都不会发生,旧固件继续存在,稍后可以重试。如果您需要逐步发布,则让客户端根据其MAC地址的最后一个字节选择镜像。所有这些都可以在几个小时内使用几个简单的shell脚本实现。或者在实际测试中需要几天时间 :)

1

@Anders的回答非常完整详尽,非常好。我能添加的唯一建议是考虑以下几点:

  • 你的应用程序是否有互联网连接/USB/SD卡来存储完整的新rootfs?在Linux嵌入式系统中工作并不像在Cortex M3上编写128K固件那样简单。
  • 你的最终用户是否有能力进行更新工作?
  • 你的应用程序是否安装在可远程控制的可访问区域?

关于开发完整/稳健/稳定解决方案所需的时间并不是一个简单的问题,但请注意,这是应用程序影响市场感受的关键点。特别是在首次部署的早期阶段/月份,通常会发送更新以修复小/大青年错误。


@LP 感谢您的反馈。该设备将具有网络连接性(TCP/IP),并且rootfs映像大小约为50-100 MB。最终用户对于引导加载程序等低级技术细节不是很熟悉,但他将能够构建新的映像版本,并需要一种安全的部署方式。 - user5153351

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接