Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于Linux的固件,如何实现好的更新方式?_Linux_Firmware_Buildroot - Fatal编程技术网

基于Linux的固件,如何实现好的更新方式?

基于Linux的固件,如何实现好的更新方式?,linux,firmware,buildroot,Linux,Firmware,Buildroot,我正在使用alix 2d13开发一个基于linux的设备 我开发了一个脚本,负责创建映像文件、创建分区、安装引导加载程序(syslinux)、内核和initrd,并负责将根文件系统文件放入正确的分区 配置文件位于tmpfs文件系统上,在系统启动时由读取驻留在自己分区上的XML文件的软件创建 我正在寻找更新文件系统的方法,我考虑了两种解决方案: 固件更新是一个压缩文件,可能包含内核、initrd和/或rootfs分区,这样,在重新启动时,initrd将负责将rootfs映像添加到正确的分区 固件

我正在使用alix 2d13开发一个基于linux的设备

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

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

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

  • 固件更新是一个压缩文件,可能包含内核、initrd和/或rootfs分区,这样,在重新启动时,initrd将负责将rootfs映像添加到正确的分区
  • 固件更新是一个压缩文件,可能包含两个tar归档文件,一个用于引导,另一个用于根文件系统
每种解决方案都有其自身的优势: -文件系统映像将允许我删除任何未使用的文件,但需要大量时间,它将快速杀死紧凑型闪存; -归档文件更小,更新所需时间更少,但我会在短时间内将CAO放在根文件系统上

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


您觉得怎么样?

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

您可以使用单独的分区进行更新(例如Side1/Side2)。 现有内核rootfs位于Side1中,然后将更新放在Side2中并切换。
这样可以减少磨损并延长使用寿命,但设备的成本会更高。

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

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

嗯,如果我做dd,我真的不需要调整大小,因为文件系统会知道它的大小。。。我真正需要的是在mbr中调整分区的大小。无论如何,我可以避免调整大分区的大小(实际上我需要小于30mb的分区,所以64mb的分区就可以了)。我会选择tar+更新前/更新后脚本+文件列表解决方案可能我非常喜欢你的解决方案,最后我做了一些非常类似的事情,但没有启动失败检测,但我认为我会实现类似的事情:-我会为启动失败检测保留一个扇区wri