嵌入式 Linux 系统在线升级策略-固件升级-升级固件-系统升级

2023-11-07

如果你认为本系列文章对你有所帮助,请大家有钱的捧个钱场,点击此处赞助,赞助额1元起步,多少随意

锋影

email:174176320@qq.com


嵌入式 Linux 系统在线升级策略

对于运行 Linux 系统的嵌入式产品,很多时候我们发现了当前版本内核、驱动、或者应用程序的 bug 并对之修复之后,或者研发出了功能更丰富、性能更突出的应用软件时,想要对当前运行的设备进行相应程序替换和升级。很多人的做法是通过对每一台设备烧写新版软件的方式进行软件版本更新,如果产品数量少且分布地点比较集中,这种方案具有一定的实效性。但是当设备数量庞大且地点分散时,这种本地烧写的升级方式将会变得非常难以操作,且升级结果可视化具有一定难度,需要通过串口等终端才能确认。

针对采用 Linux 系统且具有互联网接入能力的嵌入式设备,不论这种接入方式是有线网络、wifi、2G 或者 4G,本文将为其提供一种通过服务端后台对在线的所有或者部分设备进行远程批量升级的高效、可靠、直观的升级策略。升级内容可以是内核、驱动、文件系统、应用程序或者某些配置文件。接下来,将首先展示该方案的架构图,紧接着一步步讲述各个功能或者逻辑模块的细节。

方案概述

此升级方案由后台服务端程序、web 页面、终端升级程序三部分组成。如图 1 展示了升级方案 的架构图。

图 1. 升级方案架构图

自动草稿

自动草稿

服务端程序

服务端程序用来监测终端设备状态,管理升级包,升级流程控制并且提供 web 端响应以及数据库访问。本策略中的服务端为 apache-tomcat,程序采用 java servlet,数据库为 MySQL,web 页面为 JSP 编写。您可以使用任何一种后台语言(如 php、python 等)实现本文所描述的服务端功能。

服务端功能有:

  • 终端消息处理
  • 升级包管理
  • 升级指令处理

终端消息处理

服务端程序通过 getParameter("version")获得终端软件版本号,通过 queryLatestVersion()查询数据库中最新软件版本号,然后将二者进行对比。如果相同,则证明该终端设备软件版本已经是最新,返回 latest 指令;如果不同且服务端没有收到 web 端用户的升级指令,则通过 queryAddress()从数据库中查询最新升级包的地址,将之返回给终端,以便终端设备从该地址下载升级包,另外,如果此时用户在 web 界面执行了升级命令,则返回 update 指令给终端,终端设备执行升级操作。详细请查看清单 1。

清单 1. 终端消息处理代码片段
public void doGet(HttpServletRequest request, HttpServletResponse response)\
throws ServletException, IOException {
    String msg = null;
    String version_latest = null;
    String address_latest = null;
    String version = request.getParameter("version");

    PrintWriter out = response.getWriter();
    version_latest = queryLatestVersion();
    if(version.equals(version_latest)){ 
        msg = "|latest|null|null|";
    }else if(UpdateServlet.update_status){
        msg = "|update|"+version_latest+"|null|";
        UpdateServlet.update_status = false;
    }else{
        address_latest = queryAddress();
        msg = "|download|172.x.x.x"+address_latest+"|"+MD5+"|";
    }
    out.print(msg);
    out.flush();
    out.close();
}

升级包管理

服务端程序处理 web 端上传的升级包,首先确认存放升级包的路径是否存在,没有则创建。升级包接收完成之后,从升级包文件名中截取版本号,然后将文件名、版本号、升级包在服务端的存放路径信息插入到数据库中。类似的,服务端程序也响应 web 端用户对升级包的更改、删除等操作。详细的升级包管理请查看清单 2。

清单 2. 升级包管理代码片段
protected void doPost(HttpServletRequest request,\
    HttpServletResponse response) throws ServletException, IOException {
    String uploadPath = "/xx/xx";
    File uploadDir = new File(uploadPath);
    if (!uploadDir.exists()) {
        uploadDir.mkdir();
    }
    try {
    List<FileItem> formItems = upload.parseRequest(request);
    if (formItems != null && formItems.size() > 0) {
         for (FileItem item : formItems) {
             if (!item.isFormField()) {
                 String fileName = new File(item.getName()).getName();
                 Patternp=Pattern.compile("update_package-(.*?).tar.gz");
                 Matcherm=p.matcher(fileName);
                 while(m.find()){
                     version = m.group(1);
                 }
                String filePath = uploadPath + File.separator + fileName;
                sql = "INSERT INTO package(name,version,address)\
                VALUES('"+fileName+"','"+version+"','"+filePath+"');";
                dbOperate(sql);
                File storeFile = new File(filePath);
                item.write(storeFile);
                request.setAttribute("message",\
                "Package Has beed uploaded successfully!");
            }
        }
   }
   } catch (Exception ex) {
        request.setAttribute("message","error info: " + ex.getMessage());
    }
}

升级指令处理

如果用户从 web 端选择了升级设备并且点击了升级按钮,服务端程序则会记录该指令,当下一次收到终端设备的 POST 消息时,则会对指定的终端下发 update 升级指令,终端收到 update 命令后执行升级程序。升级完成之后终端会再次周期性上报其版本号,通过 web 端设备列表即可查看所有设备升级结果,做到升级流程、结果的可视化。

终端升级程序

终端升级程序由升级管理程序和升级执行程序两部分组成。本文所描述的升级策略先决条件是构建合理的磁盘、Flash 分区,以便支持本策略中各种程序的正常运行。

终端磁盘分区示例

图 2. 终端设备磁盘分区图

自动草稿

自动草稿

图 2 是一个针对本策略的基本 Flash 分区示例。Flash 的总容量为 128M,第一个分区为启动分区,用来存放启动 Linux 系统的引导程序,容量 2M;第二个分区为 Linux 内核分区,用来存放 Linux 内核镜像文件,容量 8M;第三个分区为根文件系统分区,用来存放根文件系统镜像文件且作为运行时用户操作空间,容量 100M;第四个为备份分区,用来存放想要备份的内容,以便升级完成后被拷贝到新的文件系统中,容量 16M;最后一个为固化信息分区,用来存放设备软件版本号、设备类型、设备 id 等信息,容量 2M。该分区信息仅作为参考,分区数量、大小需要根据具体项目做相应修改。当然如果项目没有特殊性,且硬件资源与该示例匹配,此分区方案亦可直接被沿用。

升级管理程序

升级管理程序功能如下:

  • 管理软件版本信息
  • POST 设备信息给服务端
  • 从服务端下载升级包
  • 校验,管理升级包
  • 启动升级执行程序

升级管理程序随着系统开机启动且作为守护进程运行。第一次运行时从宏定义中读取软件版本号并固化到 info 分区中,每隔一段时间从 info 分区中读取设备类型、设备 id、软件版本号。并将这些信息通过 HTTP POST 给服务端。服务端收到设备信息之后解析出其中的软件版本号,并和数据库中的最新升级包版本号进行对比。如果升级包版本号高于设备版本号,则返回 download 指令以及升级包地址、升级包 MD5 码给终端设备。

表 1. 终端设备信息消息格式
设备 id 设备类型 软件版本
000001 家庭网关 1.0.1
000002 摄像头 1.0.2
表 2. 服务端返回消息格式
指令 参数 1 参数 2
download <ip>/dir/update_package.<version>.tar.gz <MD5 code>
update <update package version> null
latest null null

表 1、表 2 分别展示了终端设备发送、服务端返回的消息格式以及内容。

升级管理程序收到服务端返回消息对其解析,根据不同指令做如下响应:

  • 指令为 download,则根据参数 1 提供的地址下载对应的升级包到终端设备本地的 tmp 目录中。下载完成之后取得升级包的 MD5 码和参数 2 中的进行对比,完成升级包校验。
  • 指令为 update,则把参数 1 中的版本号和本地 tmp 目录中的升级包版本号进行对比,如果相同才会启动升级执行程序进行升级。
  • 指令为 latest,则证明当前终端设备的软件版本和服务端中的最新升级包版本相同,已经是最新版本,不予理会。

升级执行程序

升级执行程序功能如下:

  • 解压升级包
  • 备份文件
  • 格式化内核、文件系统分区
  • 加载升级包中的文件到内核、文件系统分区
  • 重启操作系统
  • 拷贝备份文件到文件系统中

当升级执行程序被升级管理程序启动之后,首先解压升级包,并对之校验、检测。如果检测通过则开始备份用户文件,需要说明的是 backup 分区挂载在文件系统根目录 backup 文件夹上,因此备份方式是将需要备份的文件拷贝到 backup 文件夹中且记录其原始路径。下一步进行内核、文件系统分区格式化操作,此后将升级包中新版的内核镜像、文件系统镜像写到内核、根文件系统分区中,完成新老替换。然后自动重启操作系统,启动成功之后,将备份文件拷贝到对应的文件系统路径中。此时的终端设备升级完毕,运行新版系统和软件。如果升级内容仅仅为应用程序或者配置文件,则只需进行相应文件的替换即可。

设备和服务端的交互

终端设备通过 HTTP 协议与服务端进行交互。终端程序每隔 10 秒向服务端 HTTP POST 发送一次设备信息,服务端根据版本号对比结果以及 web 端升级指令状态返回三种不同指令给终端设备。终端通过解析指令做出相应响应。其中下载功能调用 libcurl 库,具有断点续传能力。10 秒的请求频率可根据具体项目应用场景做出调整,如果终端数量比较少且服务端能够承受连接压力,想要响应更加快速、及时,可考虑将 HTTP 改为 socket 长连接的通信方式。

web 端

Web 端提供用户进行升级操作的人机接口,显示、接收、跟踪整个升级过程。采用 JSP 编写。其功能如下:

  • 显示设备状态。显示设备在线、离线状态、设备类型、设备 id、软件版本号。
  • 升级包管理。显示所有升级包,对已有的升级包进行修改、删除等操作。上传新的升级包。
  • 升级操作管理。用户可通过设备列表多选、全选设备,点击升级按钮生成升级指令。

总结

本文提供了一种远程在线方式对嵌入式 Linux 设备进行批量升级的策略,升级内容包括内核、驱动、文件系统、应用程序、配置文件等。能够快速、稳定完成升级操作。描述了服务端程序、终端设备升级程序、web 端功能、设备和服务端交互方式,完整地展示了升级流程的细节,供开发者参考。

需要注意的是,该策略的实施过程中,需要确保升级设备具有足够电量以保证升级程序的顺利执行。该策略仅仅提供功能性的描述,为了确保可靠性和适应更加复杂的环境,开发者需要增加双分区启动备份机制。此外,由于升级包存放在 tmp 目录中,因此可支持的升级包大小受限于内存物理空间,开发者可将升级包存放在指定磁盘分区对该功能进行优化。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

嵌入式 Linux 系统在线升级策略-固件升级-升级固件-系统升级 的相关文章

  • Linux 中 m 标志和 o 标志将存储在哪里

    我想知道最近收到的路由器通告的 m 标志和 o 标志的值 从内核源代码中我知道存储了 m 标志和 o 标志 Remember the managed otherconf flags from most recently received R
  • 有没有一种快速方法可以从 Jar/war 中删除文件,而无需提取 jar 并重新创建它?

    所以我需要从 jar war 文件中删除一个文件 我希望有类似 jar d myjar jar file I donot need txt 的内容 但现在我能看到从 Linux 命令行执行此操作的唯一方法 不使用 WinRAR Winzip
  • 适用于 Linux 的轻量级 IDE [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • docker 非 root 绑定安装权限,WITH --userns-remap

    all 尝试让绑定安装权限正常工作 我的目标是在容器中绑定安装卷 以便 a 容器不以 root 用户身份运行入口点 二 docker daemon 配置了 userns remap 这样容器 主机上没有 root c 我可以绑定挂载和读 写
  • 如何在 Ubuntu 中创建公共 HTML 文件夹?

    简单的问题 但由于某种原因我无法在谷歌上找到确切的答案 我在 Slicehost 上安装了全新的 Ubuntu 并且想在我的主目录中为包含一堆静态 HTML 文件的简单网站创建一个公共目录 我该怎么做呢 只是打字的问题吗mkdir publ
  • 从 ttyUSB0 写入和读取,无法得到响应

    我对 Linux tty 不太有经验 我的环境是带有丰富 USB 串行的 Raspbian 什么有效 stty F dev ttyUSB0 38400 cu l dev ttyUSB0 s 38400 cu to dev ttyUSB0作品
  • GMail 421 4.7.0 稍后重试,关闭连接

    我试图找出为什么它无法使用 GMail 从我的服务器发送邮件 为此 我使用 SwiftMailer 但我可以将问题包含在以下独立代码中
  • 尽管 if 语句,Visual Studio 仍尝试包含 Linux 标头

    我正在尝试创建一个强大的头文件 无需更改即可在 Windows 和 Linux 上进行编译 为此 我的包含内容中有一个 if 语句 如下所示 if defined WINDOWS include
  • 添加文件时运行 shell 命令

    我的 Linux 机器上有一个名为 images 的文件夹 该文件夹连接到一个网站 该网站的管理员可以向该网站添加图片 但是 当添加图片时 我想要一个命令来运行调整目录中所有图片的大小 简而言之 我想知道当新文件添加到特定位置时如何使服务器
  • 如何获取 (Linux) 机器的 IP 地址?

    这个问题和之前问的几乎一样如何获取本地计算机的IP地址 https stackoverflow com questions 122208 get the ip address of local computer 问题 但是我需要找到一个的I
  • CMake 链接 glfw3 lib 错误

    我正在使用 CLion 并且正在使用 glfw3 库编写一个程序 http www glfw org docs latest http www glfw org docs latest 我安装并正确执行了库中的所有操作 我有 a 和 h 文
  • 如何让R使用所有处理器?

    我有一台运行 Windows XP 的四核笔记本电脑 但查看任务管理器 R 似乎一次只使用一个处理器 如何让 R 使用全部四个处理器并加速我的 R 程序 我有一个基本系统 我使用它在 for 循环上并行化我的程序 一旦您了解需要做什么 此方
  • .net-core:ILDASM / ILASM 的等效项

    net core 是否有相当于 ILDASM ILASM 的功能 具体来说 我正在寻找在 Linux 上运行的东西 因此为什么是 net core ildasm 和 ilasm 工具都是使用此存储库中的 CoreCLR 构建的 https
  • 从 Xlib 转换为 xcb

    我目前正在将我的一个应用程序从 Xlib 移植到 libxcb 但在查找有关我有时使用的 XInput2 扩展的信息时遇到了一些麻烦 libxcb 中有 XInput2 实现吗 如果是的话 在哪里可以找到文档 目前我在使用此功能时遇到问题
  • 内核的panic()函数是否完全冻结所有其他进程?

    我想确认内核的panic 功能和其他类似kernel halt and machine halt 一旦触发 保证机器完全冻结 那么 所有的内核和用户进程都被冻结了吗 是panic 可以被调度程序中断吗 中断处理程序仍然可以执行吗 用例 如果
  • 绕过 dev/urandom|random 进行测试

    我想编写一个功能测试用例 用已知的随机数值来测试程序 我已经在单元测试期间用模拟对其进行了测试 但我也希望用于功能测试 当然不是全部 最简单的方法是什么 dev urandom仅覆盖一个进程 有没有办法做类似的事情chroot对于单个文件并
  • Linux/POSIX:为什么 fork() 不分叉*所有*线程

    众所周知 POSIX下创建新进程的默认方式是使用fork 在 Linux 下 这在内部映射到clone 我想知道的是 众所周知 当一个人打电话时fork 子进程是用单个线程创建的 调用的线程fork cf https linux die n
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • 检查已安装的软件包,如果没有找到则安装

    我需要检查已安装的软件包 如果未安装则安装它们 RHEL CentOS Fedora 示例 rpm qa grep glibc static glibc static 2 12 1 80 el6 3 5 i686 如何在 BASH 中进行检
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读

随机推荐

  • hive 表中常用的 增加/修改/替换列操作

    1 语法 更新列 ALTER TABLE table name CHANGE COLUMN col old name col new name column type COMMENT col comment FIRST AFTER colu
  • C++ 仿函数(二)

    在上一篇里我们讲了仿函数是什么 以及一元谓词 二元谓词的概念 C 仿函数 一 小梁今天敲代码了吗的博客 CSDN博客 这篇是讲 内建函数对象 主要包括 算术仿函数 关系仿函数 逻辑仿函数 目录 一 算术仿函数 示例 二 关系仿函数 示例 举
  • windows 开机启动脚本(亲测可用)

    1 打开计划任务 2 创建任务 3 添加一个启动触发器 4 添加一个脚本操作 5 点击确认 输入登录管理员密码即可 重启试试吧
  • 部署 Exsi 7.0.3

    文章目录 1 下载介质 2 u盘引导安装启动盘 3 硬件连接 4 安装 EXSI 7 0 3 1 下载介质 下载 VMware VMvisor Installer 7 0U3l 21424296 x86 64 iso 安装 EXSI 7 0
  • vue H5页面跳转微信小程序以及生成二维码跳转小程序

    研究了两种H5跳转小程序的方法 同时携带参数 1 手机浏览器打开H5页面 点击按钮拉起微信小程序 2 H5页面上生成小程序二维码 手机微信扫码跳转目标小程序 为了开发方便 以上两种均借助了微信小程序云函数来实现 事前准备 在vue工程的in
  • Oracle数据库的导入&导出

    1 权限配置及导入导出 1 1 配置导入导出目录及设置相应权限 SQL gt select from dba directories dir where dir DIRECTORY NAME in DUMPDIR DATA PUMP DIR
  • 百万youtube高清视频数据集采集

    HD VILA 100M是什么 HD VILA 100M是一个大规模 高分辨率 多样化的视频语言数据集 有助于多模态表示学习 数据统计 该数据集共包含330万个视频 视频质量较高 均衡分布在15个类别中 下载 Download 您可以通过此
  • 详解34家银行对公账号编码规则及其编码分析

    1 工商银行 账号位数19位 地区代码4位 13为安徽 网点号4位 账户性质应用号2位 09基本户 19一般户 29专户 39临时户 账号顺序号7位 校验码2位 编码分析攻略 中国工商银行对公账户共19位 其中1 4位为地区代码 详见代码表
  • 树莓派教程 - 1.0 树莓派GPIO库wiringPi 点亮LED

    Git例程源码仓库 https github com ZhiliangMa raspberry git 电脑需要提前安装的工具 SSH 串口 终端神器 MobaXterm 官网下载链接 https mobaxterm mobatek net
  • java.sql.sQLException: No suitable driver found for jdbc:mysql

    用Maven构建父工程后 再搭建DAO模块 执行测试类测试StudentDao java查询数据库功能报错 定位到相应的类中 发现是数据库连接问题 之前我也遇到类似的问题 解决方案为 jdbc url jdbc mysql localhos
  • YOLO系列目标检测算法-Scaled-YOLOv4

    YOLO系列目标检测算法目录 文章链接 YOLO系列目标检测算法总结对比 文章链接 YOLOv1 文章链接 YOLOv2 文章链接 YOLOv3 文章链接 YOLOv4 文章链接 Scaled YOLOv4 文章链接 YOLOv5 文章链接
  • 主业工资5000,靠“爬虫技术”月入20000:会赚钱的人,从不靠拼命

    因为我们主行业的一个内卷以及薪资问题 现在已经有很多人都在从事一个副业 副业往往比主业更自由 轻松 甚至有的副业工资比他的一个主业工资还高 现在 只要你会python的爬虫技术 网上接单副业的项目更是多的供过于求 现在业界对Python爬虫
  • Python和OpenCV 提取图像特定目标区域-图像分割【原创】

    在OpenCV中 一般转换图像格式为HSV格式 默认格式为BGR 再进行指定颜色的提取 直接使用RGB提取颜色不推荐 HSV格式的介绍 HSV 为色相 饱和度 明度 1 将一副图像从rgb颜色空间转换到hsv颜色空间 hsv cv2 cvt
  • <Visual Studio 2019安装及环境配置教程>

    目录 1 Visual Studio 2019下载安装 1 1 进入官网 1 2 选择所需Visual Studio 2019安装包 1 3 Visual Studio 2019 版本说明 1 4 点击下载 安装 1 5 登录账户 1 6
  • 2022年华中杯数学建模挑战赛B题量化投资问题求解全过程文档及程序

    2022年华中杯数学建模 B题 量化投资问题 原题再现 量化投资是指通过数量化方式及计算机程序化发出买卖指令 以获取稳定收益为目的的交易方式 投资者通过数据分析探索市场运行规律 并预测市场走势 从而进行决策交易 随着大数据技术的发展 量化投
  • windows11安装wsl

    wsl2 简单点说 就是可以在Windows上用Linux 并且支持docker 管理员身份打开powerShell win x 输入下面命令 wsl install dism exe online enable feature featu
  • 算法(C++)金币阵列问题

    题目描述 有m n m 100 n 100 个金币在桌面上排成一个m 行n 列的金币阵列 每一枚金币或正面朝上或背面朝上 用数字表示金币状态 0 表示金币正面朝上 1 表示背面朝上 金币阵列游戏的规则是 1 每次可将任一行金币翻过来放在原来
  • 从mpeg ts文件中提取I帧(3):pes包的解析

    本系列的第一篇文章讲解了如何把ts包拼装为pes包 本章主要讲解如何解析pes包 一 pes包的格式如下图所示 二 相关字段解析 packet start code prefix 标识包起始端的包起始码 固定值为 0000 0000 000
  • 沟通——职场生存的润滑剂

    我们每天都有和别人沟通互动 但经常不经意地话不投机或语出伤人都不自知 在工作中 沟通也是必不可少的 经常听到企业的领导强调沟通 上下级沟通 同事间沟通 的确 沟通可以大大提升工作效率 沟通是一种技能 是一个人对本身知识 表达能力 行为能力的
  • 嵌入式 Linux 系统在线升级策略-固件升级-升级固件-系统升级

    如果你认为本系列文章对你有所帮助 请大家有钱的捧个钱场 点击此处赞助 赞助额1元起步 多少随意 锋影 email 174176320 qq com 嵌入式 Linux 系统在线升级策略 对于运行 Linux 系统的嵌入式产品 很多时候我们发