嵌入式Linux的OTA更新,基础知识和实现
嵌入式Linux的OTA更新,第1部分-基础知识和实现
OTA updates for Embedded Linux, Fundamentals and implementation
更新的需要
一旦嵌入式Linux产品离开实验室进入现实世界,如何更新设备的问题将成为重要的考虑因素。
更新并不总是必要的,但是很难想象任何一个软件都没有在某个时刻被发现的bug。即使您的软件是完美的,如果设备在网络或internet上与任何开放源代码库通信,安全更新也可能成为必要。
以CVE-2104-01650(心血)为例。此漏洞影响了OpenSSL加密库,并扩展到网络上三分之二的网站。即使在三年后的今天,仍有许多嵌入式Linux设备运行着OpenSSL的不设防版本,完全可以被攻击。
阻止vs文件更新
当谈到更新Linux时,您可能会看到提到了“块”和“文件”更新系统。这是指通过直接写入块设备或更新单个文件来执行更新,一次更新整个分区。您可能熟悉桌面或服务器Linux的文件更新系统(“例如sudo apt get upgrade”)。
在嵌入式Linux中,基于块的升级是可行的,因为它们具有原子性,而且整个文件系统通常都是嵌入式Linux构建系统的输出。对于特定的产品,我们希望每个嵌入式设备上的存储空间是恒定的,所以我们每次都创建相同大小的分区。这种类型的更新与某种回退或恢复映像密切相关。
故障时的恢复
我们绝不希望设备处于不可用状态(例如,如果发生停电)。我们可以通过确保在更新过程中发生任何错误时始终可以“退回”到另一个分区来解决这个问题。
更新的需要
一旦嵌入式Linux产品离开实验室进入现实世界,如何更新设备的问题将成为重要的考虑因素。
更新并不总是必要的,但是很难想象任何一个软件都没有在某个时刻被发现的bug。即使您的软件是完美的,如果设备在网络或internet上与任何开放源代码库通信,安全更新也可能成为必要。
以CVE-2104-01650(心血)为例。此漏洞影响了OpenSSL加密库,并扩展到网络上三分之二的网站。即使在三年后的今天,仍有许多嵌入式Linux设备运行着OpenSSL的不设防版本,完全可以被攻击。
阻止vs文件更新
当谈到更新Linux时,您可能会看到提到了“块”和“文件”更新系统。这是指通过直接写入块设备或更新单个文件来执行更新,一次更新整个分区。您可能熟悉桌面或服务器Linux的文件更新系统(“例如sudo apt get upgrade”)。
在嵌入式Linux中,基于块的升级是可行的,因为它们具有原子性,而且整个文件系统通常都是嵌入式Linux构建系统的输出。对于特定的产品,我们希望每个嵌入式设备上的存储空间是恒定的,所以我们每次都创建相同大小的分区。这种类型的更新与某种回退或恢复映像密切相关。
故障时的恢复
我们绝不希望设备处于不可用状态(例如,如果发生停电)。我们可以通过确保在更新过程中发生任何错误时始终可以“退回”到另一个分区来解决这个问题。
图2. 发生故障时的恢复-Board Management Controller
这当然是一个复杂的解决方案,需要一个额外的微控制器、一套新的固件和更复杂的硬件设计(它用于某些设备,例如那些包含独立的智能平台管理接口(IPMI)控制器的设备)。因此,您应该致力于构建一个功能强大、范围小、因此不需要更新的引导加载器。
U-Boot环境变量
U-boot实现了一个可以存储变量的非易失性“环境”。甚至可以从Linux访问这些文件。
这是实现上述“开关”的最明显的方法。它还可以用来存储有关以前引导成功或失败的信息,以便在引导失败的情况下可以反转交换机并恢复工作分区。
图3. U-boot环境变量
设置看门狗
处理器的硬件看门狗应该通过U-Boot(CONFIG_-watchdog)设置,然后在引导完成后由Linux进行维护。这将导致整个系统挂起时重置。
正在检查引导失败
一旦您的任务关键型应用程序正在运行,它应该在u-boot环境中设置一个变量,指示完成引导。然后,U-boot将能够在下次引导时检查是否已设置了此选项,并在引导失败时采取措施(有时仅在连续几次失败之后)。
具体的体系结构将取决于您的应用程序和产品;您需要对其进行一点定制,以满足您的需要。您将需要确定所有可能的故障模式,并对所有模式执行恢复。
实施更新
正如我们之前所说的,更新应该是一个单独的加密签名文件。私钥签名确保其来源于制造商您。现在,系统只需要将其解压并运行一个脚本,该脚本将自行执行更新。它将覆盖要更新的分区;轻触任何需要的开关并重新启动。这应该尽快进行,以尽量减少停机时间。
保护更新
我们要确保我们提供给设备的更新文件来自我们制造商,而不是来自其他人。为此,更新文件使用制造商持有的私钥进行签名。相应的公钥是设备上保存的,它将验证请求它执行更新的任何更新文件。如果提供的文件被视为无效,则更新将失败。
正在获取更新
更新如何到达是另一回事。这里有四种可能性:
最明显、最简单的一点是,更新是由一个拥有根用户登录设备的工程师应用的。他运行更新脚本并更新设备。这充满了安全问题,可能只适合于开发中的系统,或者工程或工业环境中使用的系统。
将物理介质插入包含所需更新的设备(U盘)中。板上的软件将通过轮询守护程序或udev规则自动检测和安装。
通过某种方法(例如web应用程序)将更新文件上载到单个计算机。
无线更新,如下一节所述。
无线更新
“空中传送”(OTA)更新通常指通过安全通道从中央服务器更新的设备。它通常指物联网设备、移动电话、汽车ECU等。在本文中,我将描述一种可以在任何连接到互联网的设备上工作的更新类型,这可能是通过Wi-Fi(空中传送)、以太网(铜缆)或其他协议。
正在检查更新
首先要做的是检查更新。在设备上运行的守护进程可以向预先确定的服务器发送请求,提供其当前版本和硬件版本。然后,服务器可以根据这些信息,向设备发送一个签名的更新文件,以便在必要时进行安装,或者报告没有可用的或需要的更新。
复杂性可以通过多种方式增加,从仅根据各种标准向设备子集提供更新,到对更新文件进行完全加密,再到向中央服务器报告更新状态或其他信息。
现成与内部解决方案
有许多现成的更新机制可以与您的嵌入式Linux系统集成,而不必像上面描述的那样重新发明轮子。在yocto项目中可以找到其中一些的比较。
这些可能需要一些时间和精力来与当前的嵌入式Linux构建系统集成,但是它可能比内部开发一个自定义方法要少,而且它可能更健壮,因为其中一些项目已经投入了数百个小时。 您可能不需要现成解决方案的原因:
你希望为你的董事会在每一个层次上定制东西
在接受一个相对较新的、未被广泛使用或认可的大型代码库时,您可能会有安全问题
在ByteSnap Design,我们为各种不同的客户提供完整的硬件和软件解决方案。我们创建了两个内部定制更新系统,同时集成了现成的更新系统,如NXP iMX和TI OMAP系列芯片组上的Mender。