为嵌入式Linux设备实现更新/升级系统
我有一个在嵌入式 Linux 设备上运行的应用程序,并且时不时地对软件进行更改,有时还会对根文件系统甚至安装的内核进行更改。
在当前的更新系统中,只需删除旧应用程序目录的内容,然后将新文件复制到其上。当对根文件系统进行更改时,新文件将作为更新的一部分提供,并简单地复制到旧文件上。
现在,当前方法存在几个问题,我正在寻找改善这种情况的方法:
- 用于创建文件系统映像的目标的根文件系统没有版本控制(我认为我们甚至没有原始版本)根文件系统)。
- 进入更新的 rootfs 文件是手动选择的(而不是差异)
- 更新不断增长并成为皮塔饼。现在更新/升级之间存在分歧,其中升级包含更大的 rootfs 更改。
- 我的印象是,更新中的一致性检查如果真的实施的话,也是相当脆弱的。
要求是:
- 应用程序更新包不能太大,并且在修改的情况下还必须能够更改根文件系统。
- 升级可能会更大,并且只包含进入根文件系统的内容(例如新库、内核等)。更新可能需要安装升级。
升级是否可以包含整个根文件系统,并且只需在目标的闪存驱动器上执行dd
? - 创建更新/升级包应尽可能自动进行。
我绝对需要某种方法来对根文件系统进行版本控制。这必须以某种方式完成,以便我可以从中计算某种 diff
,该差异可用于更新目标设备的 rootfs。
我已经研究过 Subversion,因为我们将其用于源代码,但这对于 Linux 根文件系统(文件权限、特殊文件等)不合适。
我现在创建了一些 shell 脚本,可以为我提供类似于 svn diff 的东西,但我真的很想知道是否已经存在一个有效且经过测试的解决方案。
使用这样的diff
,我猜升级将简单地成为一个包含基于已知根文件系统状态的增量更新的包。
您对此有何想法和想法?您将如何实施这样的系统?我更喜欢一个可以在短时间内实施的简单解决方案。
I have an application that runs on an embedded Linux device and every now and then changes are made to the software and occasionally also to the root file system or even the installed kernel.
In the current update system the contents of the old application directory are simply deleted and the new files are copied over it. When changes to the root file system have been made the new files are delivered as part of the update and simply copied over the old ones.
Now, there are several problems with the current approach and I am looking for ways to improve the situation:
- The root file system of the target that is used to create file system images is not versioned (I don't think we even have the original rootfs).
- The rootfs files that go into the update are manually selected (instead of a diff)
- The update continually grows and that becomes a pita. There is now a split between update/upgrade where the upgrade contains larger rootfs changes.
- I have the impression that the consistency checks in an update are rather fragile if at all implemented.
Requirements are:
- The application update package should not be too large and it must also be able to change the root file system in the case modifications have been made.
- An upgrade can be much larger and only contains the stuff that goes into the root file system (like new libraries, kernel, etc.). An update can require an upgrade to have been installed.
Could the upgrade contain the whole root file system and simply do add
on the flash drive of the target? - Creating the update/upgrade packages should be as automatic as possible.
I absolutely need some way to do versioning of the root file system. This has to be done in a way, that I can compute some sort of diff
from it which can be used to update the rootfs of the target device.
I already looked into Subversion since we use that for our source code but that is inappropriate for the Linux root file system (file permissions, special files, etc.).
I've now created some shell scripts that can give me something similar to an svn diff
but I would really like to know if there already exists a working and tested solution for this.
Using such diff
's I guess an Upgrade would then simply become a package that contains incremental updates based on a known root file system state.
What are your thoughts and ideas on this? How would you implement such a system? I prefer a simple solution that can be implemented in not too much time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我相信您对这个问题的看法是错误的 - 任何非原子更新(例如添加文件系统映像,替换目录中的文件)都会被设计破坏 - 如果在更新过程中断电,则系统是一个对于砖块和嵌入式系统,电源可能会在升级过程中断电。
我写了一篇关于如何在嵌入式 Linux 系统上正确进行升级/更新的白皮书 [1]。它在 OLS 上发表。您可以在此处找到该论文:https://www. kernel.org/doc/ols/2005/ols2005v1-pages-21-36.pdf
[1] 本-尤瑟夫,吉拉德。 “构建 Murphy 兼容的嵌入式 Linux 系统。” Linux 研讨会。 2005年。
I believe you are looking wrong at the problem - any update which is non atomic (e.g. dd a file system image, replace files in a directory) is broken by design - if the power goes off in the middle of an update the system is a brick and for embedded system, power can go off in the middle of an upgrade.
I have written a white paper on how to correctly do upgrade/update on embedded Linux systems [1]. It was presented at OLS. You can find the paper here: https://www.kernel.org/doc/ols/2005/ols2005v1-pages-21-36.pdf
[1] Ben-Yossef, Gilad. "Building Murphy-compatible embedded Linux systems." Linux Symposium. 2005.
我绝对同意更新必须是原子的 - 我最近启动了一个开源项目,其目标是为软件管理提供一种安全且灵活的方式,包括本地和远程更新。我知道我的答案来得很晚,但它可能会对您接下来的项目有所帮助。
您可以在
github.com/sbabic/swupdate
。斯特凡诺
I absolutely agree that an update must be atomic - I have started recently a Open Source project with the goal to provide a safe and flexible way for software management, with both local and remote update. I know my answer comes very late, but it could maybe help you on next projects.
You can find sources for "swupdate" (the name of the project) at
github.com/sbabic/swupdate
.Stefano
目前,有相当多的开源嵌入式Linux更新工具不断涌现,每个工具都有不同的侧重点。
另一个值得一提的是 RAUC,它专注于在目标上处理签名更新包的安全和原子安装,同时您可以非常灵活地使其适应您的应用程序和环境。来源位于 GitHub 上:https://github.com/rauc/rauc
总的来说,这是一个很好的概述您可以在 Yocto Project Wiki 页面上找到有关系统更新的当前更新解决方案的比较:
https://wiki.yoctoproject.org/wiki/System_Update
Currently, there are quite a few Open Source embedded Linux update tools growing, with different focus each.
Another one that is worth being mentioned is RAUC, which focuses on handling safe and atomic installations of signed update bundles on your target while being really flexible in the way you adapt it to your application and environment. The sources are on GitHub: https://github.com/rauc/rauc
In general, a good overview and comparison of current update solutions you might find on the Yocto Project Wiki page about system updates:
https://wiki.yoctoproject.org/wiki/System_Update
原子性对于嵌入式设备至关重要,其中突出的原因之一是功耗;但可能还有其他问题,例如硬件/网络问题。
原子性可能有点被误解;这是我在更新程序上下文中使用的定义:
使用双 A/B 分区布局的完整映像更新是最简单的以及实现这一目标的最行之有效的方法。
对于嵌入式 Linux,您可能需要更新多个软件组件,并有不同的设计可供选择;这里有一篇关于此的较新论文: https://mender.io/resources/Software% 20Updates.pdf
文件移至:https://mender.io/resources/guides-and-whitepapers/_resources/Software%2520Updates.pdf
如果您正在使用 Yocto 项目,您可能会对Mender.io - 我正在从事的开源项目。它由客户端和服务器组成,目标是使更新程序更快、更容易地集成到现有环境中;无需太多重新设计或花时间进行自定义/自制编码。它还允许您通过服务器集中管理更新。
Atomicity is critical for embedded devices, one of the reasons highlighted is power loss; but there could be others like hardware/network issues.
Atomicity is perhaps a bit misunderstood; this is a definition I use in the context of updaters:
Full image update with a dual A/B partition layout is the simplest and most proven way to achieve this.
For Embedded Linux there are several software components that you might want to update and different designs to choose from; there is a newer paper on this available here: https://mender.io/resources/Software%20Updates.pdf
File moved to: https://mender.io/resources/guides-and-whitepapers/_resources/Software%2520Updates.pdf
If you are working with the Yocto Project you might be interested in Mender.io - the open source project I am working on. It consists of a client and server and the goal is to make it much faster and easier to integrate an updater into an existing environment; without needing to redesign too much or spend time on custom/homegrown coding. It also will allow you to manage updates centrally with the server.
您可以记录更新并将更新闪存分为两个插槽。电源故障总是让您返回到当前正在执行的插槽。最后一步是修改日志值。非原子的,没有办法把它变成砖。即使它在写入日志标志时失败。不存在原子更新这样的事情。曾经。我一生中从未见过它。 Iphone、adroid、我的网络交换机——它们都不是原子的。如果您没有足够的空间进行此类设计,请修复设计。
You can journal an update and divide your update flash into two slots. Power failure always returns you to the currently executing slot. The last step is to modify the journal value. Non atomic and no way to make it brick. Even it if fails at the moment of writing the journal flags. There is no such thing as an atomic update. Ever. Never seen it in my life. Iphone, adroid, my network switch -- none of them are atomic. If you don't have enough room to do that kind of design, then fix the design.