基于Linux的Firmware,如何实现良好的更新方式?

发布于 2024-10-20 02:06:06 字数 574 浏览 4 评论 0原文

我正在使用 alix 2d13 开发基于 Linux 的设备。

我开发了一个脚本,负责创建映像文件、创建分区、安装引导加载程序(syslinux)、内核和 initrd,并且负责将根文件系统文件放入正确的分区。

配置文件位于 tmpfs 文件系统上,并在系统启动时由读取驻留在自己分区上的 XML 文件的软件创建。

我正在寻找一种更新文件系统的方法,我考虑了两种解决方案:

  • 固件更新是一个压缩文件,可以包含内核、initrd 和/或 rootfs 分区,这样,在重新启动时,initrd 将负责将 rootfs 映像添加到右侧分区;
  • 固件更新是一个压缩文件,可能包含两个 tar 存档,一个用于引导,一个用于根文件系统。

每个解决方案都有其自身的优点: - 文件系统映像可以让我删除任何未使用的文件,但需要大量时间,并且会快速耗尽紧凑型闪存; - 存档较小,更新需要的时间较少,但我会在短时间内在根文件系统上拥有caos。

另一种解决方案是将文件列表放入 tar 存档中,并将更新前/更新后脚本放入 tar 存档中,这样任何不驻留在文件列表中的文件都将被删除。

你怎么认为?

I'm developing a linux-based appliance using an alix 2d13.

I've developed a script that takes care of creating an image file, creating the partitions, installing the boot loader (syslinux), the kernel and the initrd and, that takes care to put root filesystem files into the right partition.

Configuration files are on tmpfs filesystem and gets created on system startup by a software that reads an XML file that resides on an own partition.

I'm looking a way to update the filesystem and i've considered two solutions:

  • the firmware update is a compressed file that could contain kernel, initrd and/or the rootfs partition, in this way, on reboot, initrd will takes care to dd the rootfs image to the right partition;
  • the firmware update is a compressed file that could contain two tar archives, one for the boot and one for the root filesystem.

Every solution has its own advantages:
- a filesystem image will let me to delete any unused files but needs a lot of time and it will kill the compact flash memory fastly;
- an archive is smaller, needs less time for update, but i'll have the caos on the root filesystem in short time.

An alternative solution could be to put a file list and to put a pre/post update script into the tar archive, so any file that doesn't reside into the file list will be deleted.

What do you think?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

七禾 2024-10-27 02:06:06

我使用了以下方法。它在某种程度上基于论文“构建 Murphy 兼容的嵌入式 Linux 系统”,可用 此处。我使用了该论文中描述的 versions.conf 内容,而不是 cfgsh 内容。

  • 使用引导内核,其作用是环回挂载“主”根文件系统。如果您需要更新的内核,请在环回安装后立即 kexec 进入该更新的内核。我选择将引导内核的完整 init 以及 busybox 和 kexec(都是静态链接的)放在 initramfs 中,而我的 init 是我编写的一个简单的 shell 脚本。
  • 一个或多个“主操作系统”根文件系统作为磁盘映像文件存在于“操作系统映像”文件系统上。引导内核根据 versions.conf 文件选择其中之一。我只维护两个主要操作系统映像文件,即当前文件和后备文件。如果当前内核失败(稍后将详细介绍故障检测),则引导内核将引导后备内核。如果两者都失败或者没有后备,引导内核将提供一个 shell。
  • 系统配置位于单独的分区上。通常不会升级,但没有理由不能升级。
  • 共有四个分区:引导、操作系统映像、配置和数据。数据分区用于用于频繁写入的用户应用程序内容。 boot 永远不会以读/写方式安装。操作系统映像仅在升级期间以读/写方式(重新)安装。仅当配置内容需要更改时(希望永远不会),配置才会挂载为读/写。数据始终以读/写方式安装。
  • 每个磁盘映像文件都包含一个完整的Linux 系统,包括内核、初始化脚本、用户程序(例如busybox、产品应用程序)以及在首次启动时复制到配置分区的默认配置。这些文件的大小可以满足其中的所有内容。只要我允许足够的增长空间,以便操作系统映像分区始终足够大以容纳三个主要操作系统映像文件(在升级过程中,我不会删除旧的回退,直到提取新的回退),我可以允许主操作系统映像根据需要增长。这些图像文件始终以只读方式(环回)安装。使用这些文件还可以消除处理 rootfs 中单个文件升级失败的痛苦。
  • 升级是通过将自解压 tarball 传输到 tmpfs 来完成的。该脚本的开头重新挂载操作系统映像读/写,然后将新的主操作系统映像提取到操作系统映像文件系统,然后更新 versions.conf 文件(使用“murphy”论文中描述的重命名方法)。完成此操作后,我触摸指示已发生升级的标记文件,然后重新启动。
  • 引导内核会查找此标记文件。如果找到它,会将其移动到另一个标记文件,然后启动新的主操作系统映像文件。主操作系统映像文件预计会在成功启动时删除标记文件。如果没有,看门狗将触发重新启动,然后启动内核将看到这一点并检测到故障。
  • 您会注意到升级过程中可能会出现一些故障:在升级过程中同步 versions.conf,以及触摸/删除标记文件(三个实例)。我找不到一种方法来进一步减少这些并实现我想要的一切。如果有人有更好的建议,我很想听听。写入操作系统映像时也可能发生文件系统错误或电源故障,但我希望 ext3 文件系统能够在这种情况下提供一些生存的机会。

I used the following approach. It was somewhat based on the paper "Building Murphy-compatible embedded Linux systems," available here. I used the versions.conf stuff described in that paper, not the cfgsh stuff.

  • Use a boot kernel whose job is to loop-back mount the "main" root file system. If you need a newer kernel, then kexec into that newer kernel right after you loop-back mount it. I chose to put the boot kernel's complete init in initramfs, along with busybox and kexec (both statically linked), and my init was a simple shell script that I wrote.
  • One or more "main OS" root file systems exist on an "OS image" file system as disk image files. The boot kernel chooses one of these based on a versions.conf file. I only maintain two main OS image files, the current and fall-back file. If the current one fails (more on failure detection later), then the boot kernel boots the fall-back. If both fail or there is no fall-back, the boot kernel provides a shell.
  • System config is on a separate partition. This normally isn't upgraded, but there's no reason it couldn't be.
  • There are four total partitions: boot, OS image, config, and data. The data partition is for user application stuff that is intended for frequent writing. boot is never mounted read/write. OS image is only (re-)mounted read/write during upgrades. config is only mounted read/write when config stuff needs to change (hopefully never). data is always mounted read/write.
  • The disk image files each contain a full Linux system, including a kernel, init scripts, user programs (e.g. busybox, product applications), and a default config that is copied to the config partition on the first boot. The files are whatever size is necessary to fit everything in them. As long I allowed enough room for growth so that the OS image partition is always big enough to fit three main OS image files (during an upgrade, I don't delete the old fall-back until the new one is extracted), I can allow for the main OS image to grow as needed. These image files are always (loop-back) mounted read-only. Using these files also takes out the pain of dealing with failures of upgrading individual files within a rootfs.
  • Upgrades are done by transferring a self-extracting tarball to a tmpfs. The beginning of this script remounts the OS image read/write, then extracts the new main OS image to the OS image file system, and then updates the versions.conf file (using the rename method described in the "murphy" paper). After this is done, I touch a stamp file indicating an upgrade has happened, then reboot.
  • The boot kernel looks for this stamp file. If it finds it, it moves it to another stamp file, then boots the new main OS image file. The main OS image file is expected to remove the stamp file when it starts successfully. If it doesn't, the watchdog will trigger a reboot, and then the boot kernel will see this and detect a failure.
  • You will note there are a few possible points of failure during an upgrade: syncing the versions.conf during the upgrade, and touching/removing the stamp files (three instances). I couldn't find a way to reduce these further and achieve everything I wanted. If anyone has a better suggestion, I'd love to hear it. File system errors or power failures while writing the OS image could also occur, but I'm hoping the ext3 file system will provide some chance of surviving in that case.
林空鹿饮溪 2024-10-27 02:06:06

您可以有一个单独的分区用于更新(例如 Side1/Side2)。
现有的内核,rootfs在Side1,然后将更新放在Side2并切换。
通过这种方式,您可以减少磨损均衡并延长使用寿命,但设备会变得更加昂贵。

You can have a seperate partition for update(Say Side1/Side2).
The existing kernel,rootfs is in Side1, then put the update in Side2 and switch.
By this you can reduce wear leveling and increase the life but the device gets costlier.

葬﹪忆之殇 2024-10-27 02:06:06

您可以在提取 tar 文件之前快速格式化分区。或者使用图像解决方案,但使用尽可能小的图像,并在 dd 之后调整文件系统大小(尽管这对于只读存储不是必需的)

You can quick format the partitions before extracting the tar files. Or go with the image solution but use the smallest possible image and after dd do a filesystem resize (although that is not necessary for readonly storage)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文