什么是允许在嵌入式系统中进行安全软件升级的技术

时间:2009-05-18 12:35:39

标签: embedded reliability

升级嵌入式设备的软件通常可能会“破坏”设备,例如:如果在将软件写入FLASH的过程中电源发生故障。两个问题:

  1. 实施升级机制的最佳做法是什么,以尽量减少设备被“砖砌”的可能性?
  2. 使升级过程成为故障安全的最佳做法是什么,以便在将软件安装到FLASH时发生电源故障等事件可以从中恢复?

9 个答案:

答案 0 :(得分:11)

这完全取决于应用程序的重要程度。有时也会将两种基本方法(备份和引导加载程序)组合在一起。

许多系统都有一个只读引导加载程序(如redboot),然后有两组闪存(在同一芯片上,最常见)。然后,引导加载程序有一个标志来选择从哪个存储区引导。然后,该标志将根据升级(失败或成功)等事件进行更改。

因此,在升级时,正在运行的版本会将新负载复制到备份库中,检查校验和,切换引导标志,然后重新启动设备。设备将使用新负载重新启动新银行。重新启动后,新负载可以将自身复制到备份库中。

通常还有一个带硬件复位的看门狗定时器。这样,如果固件发生故障,它就无法启动看门狗,硬件复位将重启设备,引导加载程序将寻找合理的负载。

Open Mesh项目就是这种方法的一个很好的例子。

答案 1 :(得分:4)

更具体地说......

将替换图像下载到内存区域,而不会覆盖当前程序空间的任何内容。等到下载完成,然后计算并比较CRC。

如果空间确实存在问题,你可以进行'默认备份'AKA'恢复模式'之类的事情,但是不要破坏性地做这件事更加光滑。

如果你真的很光滑......你可以对FLASH进行一次写更新,以指示设备从新的代码位置启动。这将在两个完全独立的代码段之间ping / pong。这是最安全的方法:

  • 总是有一个不可更新的恢复引导加载程序(Nano-loader),如果一切都出错,可以通过信号加载新代码。
  • 两个单独的程序空间
  • 每个程序空间都有一个“CRC”字段,一个“刻录号”(高于其他代码页的号码)和一个“无效”字(所有Fs - 不需要擦除来更新“无效”标记物)
  • 下载完成后,请验证CRC。如果它很好,请在旧版本的程序空间中刻录“无效”标记。
  • Nano-loader检查“无效”标记以了解要引导到哪个标记。如果它们都有效,请进行CRC校验。如果它们仍然有效,则采用更高的刻录号条目

哦,当人们说校验和时...不要'检查总和'......做一个正确的CRC。

答案 2 :(得分:2)

内部闪存上的

校验和,如果CRC /校验和无效,则使用默认备份。这样,如果设备获得了错误的校验和,那么它就知道升级不完整,并且可以重置为存储在另一台设备上的默认/以前的固件。

这需要一些预启动(可能在引导加载程序中)来检查校验和。静态的代码。

修改:继续在其他地方发表评论。如果你想检查错误的固件,而不仅仅是损坏固件,你的checsum / checkdata也可以封装版本信息(并检查那个标题)我认为Linksys路由器会这样做,这会使他们在使用自定义固件重新刷新时出现问题。

答案 3 :(得分:2)

校验和很好但只能避免您在损坏的数据中闪烁。如果您在具有有效校验和的图像文件中闪存但是针对不同的产品模型,该怎么办?一个只读的默认启动加载程序,可以在紧急损坏的情况下访问,这是我见过的最好的事情。

答案 4 :(得分:2)

  1. 无论什么
  2. ,都要在内存中保留只读引导加载程序
  3. 在引导加载程序中,允许从可用的输入源(SD卡,RS232,等等)重新加载新程序存储器的故障保护方法(例如,在重启期间按住按钮X)。

答案 5 :(得分:2)

回答这两个问题,无论任何特定的硬件资源如何:

  • 确保在运行任何应用程序代码之前(启动时或下载完成后),引导加载程序会对应用程序执行CRC检查。如果它无效,则引导加载程序不会运行代码。

  • 如果引导加载程序确定它无法运行应用程序代码,则它必须能够向用户发出信号并再次开始下载。

如果处理器没有足够的闪存来存储备份应用程序,或者在完成下载之前存储新的RAM不足,这些显然会变得更加重要。

在这些情况下,下载的文件有一个小标题是有意义的,它允许引导加载程序确定该文件适合系统。此标头也可以有CRC。如果标头对该系统有效,并且CRC正确,则引导加载程序可以擦除闪存(但不能擦除!),然后继续下载。如果没有,它会在不触及现有应用程序代码的情况下中止。

答案 6 :(得分:2)

根据我的经验,它取决于您的成本点,如果您可以根据需要在设备上拥有两倍的代码/数据空间并且可以重新启动,那么简单,将新版本存储在您的所有额外空间中,对新的想象进行适当的校验和检查,我还建议深入检查新的固件映像,因为如果不这样做可能会被欺骗,例如某种加密密钥保证新想象的起源。您也可以使用外部存储器执行此操作,例如在使用PIC的一个项目中,我有一个用于新固件映像的外部EEPROM,以及一个标志,如果在启动时设置将从EEPROM加载新的想象。

如果你不是那么幸运,也就是说你买不起这个空间,那么生活会变得更加有趣,并且可能无法保证在更新过程中完全避免失败的可能性。在所有情况下,引导加载程序应该在写保护的内存中,如果你能负担得起空间,应该有一些基本的外部连接形式,我已经在引导加载程序中使用非常简单的USB驱动程序完成系统,并且系统具有真正简单的UDP只有网络堆栈。如果在更新期间出现故障,则至少可以让您至少获得设备的新想象。在这些情况下,我强烈建议将引导加载程序放在只读存储器区域中,您将失去更新它的能力,但是干扰线更新也不会让您使用完全砖块的设备。在这种情况下,引导加载程序足够小,您可以非常确定其正确性。

最后一种可能性是一个系统需要在运行时更新其代码的某些部分......这非常棘手,并且通常需要对内存中的函数位置进行复杂控制,并在内存布局中实现主要规划。它不是太有趣,但它可行。

答案 7 :(得分:1)

我知道这个Q已经回答,但有些人需要更高的可靠性。 如果您的项目真的是关键任务,那么您可以走这条路。

基本计划是始终有一个不能失败的备份计划。

  1. 有PIC或其他微控制器可以编程真实处理器的闪存。 你让它在数据块上使用校验和,并通过串行,usb甚至以太网连接它(不要笑它不是那么难)这个设备不能在现场重新编程(或者甚至可能是偶数)所以你总是有备份计划。 PIC可以通过PPP / SLIP或ehternet运行Web服务器,因此与它连接并不是必要的尴尬。 Google TCP-Lean。尽量不要滴滴答滴。 (网站 适合工作)。将progrmming端口放在其他位置。安全性得不到保障。

  2. 程序在主CPU上运行并运行它自己的引导加载程序。 您有三个程序:引导加载程序,维护程序和真实程序。

  3. 这允许升级引导程序进程以及程序。 您可以在一些额外的闪存中运行备份引导加载程序,并使用监视程序重置您,并在您不启动时使用备份。

    因此,您可以升级嵌入式应用程序,可升级的引导加载程序和可升级的维护模式。 和一个不能失败的备份模式。

    希望没有人需要找到这个有用的。

答案 8 :(得分:0)

在一些实验室(而非消费者)设备上,我看到用编程器电路构建的电路板。在最坏的情况下,你使用可以打开机箱,插入程序员并重新加载默认软件---或发回它为你做同样的事情。 “当然,这需要真正的钱。

我的一些项目中使用的某些自定义板具有可替换的ROM。这是更干净,但不太方便。