嵌入式系统现场更新指南
在嵌入式系统开发与维护过程中,现场更新是一项至关重要的任务,它能够确保系统具备最新的功能、性能和安全性。本文将详细介绍几种常见的现场更新方法,包括 apt 库的构建、ipkg 包管理器的使用、initramfs 根文件系统的更新以及内核的更新策略。
1. 构建 apt 库
若尚未使用 Python,可通过以下步骤获取 apt 库的源代码:
$ apt-get source apt
此命令会将 apt 源代码解压至
apt - 0.7.20.2ubuntu6
目录。由于 apt 项目采用 autoconf 工具进行构建,因此为目标板创建相应的构建环境是一个熟悉的过程。为确保编译过程顺利进行,还需要为工具链安装 curl 库。若该库不存在,可按以下步骤下载并构建:
$ wget http://curl.netmirror.org/download/curl-7.17.0.tar.gz
$ CC=arm-linux-gcc ./configure \
--host=arm-linux-gnu \
--prefix=<toolchain sysroot> \
--disable-ldap --disable-ldaps
$ make
$ make install
Curl 是一个用于高级 URL 处理的工具。上述配置命令禁用了 LDAP 和 LDAPS 认证方案,因为大多数工具链中不包含这些认证方案,且构建它们需要额外的步骤。若不打算使用 LDAP 认证,可省略这些选项以节省空间。安装完成后,可按以下步骤构建 apt 库:
$ cd apt-0.7.20.2ubuntu6
$ CC=arm-linux-gcc CXX=arm-linux-g++ \
CPPFLAGS=”-I <path to your toolchain sysroot>”
./configure --host=arm-linux-gnu \
–prefix=<path to your rfs>
$ make
$ make install
安装到目标机器后,需在目标机器的
/etc/apt/sources.list
文件中添加条目,告知 apt-get 在更新时使用自定义的仓库。示例条目如下:
deb file:///tmp/apt edasich
此条目表示检查
file:///tmp/apt
仓库,该仓库包含
edasich
发行版的软件包。
2. 使用 ipkg 包管理器
Itsy 包管理器(ipkg)是 Open Handhelds 项目的一部分,专为低资源机器设计。它最初是一组用于解压 tar 文件的 shell 脚本,现在已用 C 语言重写,在保留低资源特性的同时,增加了一些大型包管理工具的功能。
2.1 获取源代码
标准 Linux 桌面发行版中通常不包含 ipkg 工具,因此需要下载源代码并在开发机器上进行编译。可从 Open Handhelds 网站下载快照文件:
$ wget http://www.handhelds.org/download/packages/ipkg/ipkg-0.99.163.tar.gz
$ tar zxf ipkg-0.99.163.tar.gz
$ ./configure
$ make
$ sudo make install
部分快照可能未将 ipkg 使用的库文件复制到
/usr/lib
目录,导致程序安装后无法正常工作。可通过以下命令手动复制:
$ sudo cp ./.libs/libipkg.so /usr/lib
$ sudo ln /usr/lib/libipkg.so /usr/lib/libipkg.so.0
此外,还需要用于创建 ipkg 包的工具。可从镜像站点下载:
$ wget ftp://ftp.cerias.purdue.edu/pub/os/gentoo/distfiles/ipkg-utils-1.7.tar.gz
这些文件是 shell 和 Python 脚本的组合,无需编译。为方便访问,可将其复制到
/usr/bin
目录或添加到搜索路径中。
2.2 创建 ipkg 包
创建 ipkg 包的过程与 Debian 包的创建过程类似,需在
CONTROL/control
目录下创建一个特殊文件。示例
CONTROL/control
文件内容如下:
Package: embedded-app
Priority: required
Version: 1.1
Section: base
Architecture: arm
Source: none
Maintainer: Valued Resource 1<vresource1@yourdomain.here>
Description: Primary application.
Comment remarking about the new electrons
added at the behest of marketing.
创建文件后,使用
ipkg - build
命令创建包文件:
$ ipkg-build build-ipkg
2.3 创建 Feed
ipkg 系统支持从远程位置(称为 Feed)获取软件包。创建 Feed 的步骤如下:
1.
创建目录
:在可通过 FTP 或 HTTP 访问的位置创建目录。示例中,假设 Web 服务器的文档根目录为
DOCROOT
:
mkdir $DOCROOT/ipkg-feed
- 复制包文件 :将需要包含在 Feed 中的 ipkg 文件复制到该目录:
cp <package dir>/ipkg-feed/embedded-app_1.1_arm.ipk \
$DOCROOT/ipkg-feed
-
生成索引文件
:运行索引器工具生成索引文件,使目标机器能够查看可用的软件包。由于大多数系统使用 Python 2.4 或更高版本,需要修改
ipkg - make - index脚本的第一行:
原第一行:#!/usr/bin/python
修改后:#!/usr/bin/env python
修改后,执行以下命令生成索引文件:
$ cd $DOCROOT/ipkg-feed
$ ipkg-make-index -v . > Packages
2.4 在目标机器上运行 ipkg
在目标机器上运行 ipkg,需交叉编译 ipkg 工具并将其安装到根文件系统。可在解压 ipkg 文件的目录中执行以下命令:
$ make clean
$ CC=arm-linux-gcc ./configure \
--host=arm-linux-gnu \
--prefix=<target board rfs>
$ make ; make install
目标机器需要一个配置文件
/etc/ipkg.conf
来指定 ipkg 文件的位置。示例配置文件内容如下:
src edasich http://<some host>/ipkg-feed
dest root /
3. initramfs 根文件系统
部分用户选择使用 initramfs 文件系统作为根文件系统。该文件系统以 cpio 存档的形式与内核一起存储,在启动时解压到文件系统缓存中,类似于 RAM 磁盘。它是读写文件系统,但系统重启后所有更改都会丢失。若使用 initramfs 作为根文件系统,需要通过替换整个内核来进行更新。
4. 内核更新
内核更新是系统现场更新的另一个重要方面。虽然内核更新的风险与根文件系统更新相当,但更新需求相对较少。在桌面系统中,用户可能会为了使用新外设、提升性能或获取安全补丁而更新内核;而在嵌入式系统中,由于硬件固定且通信受严格控制,这些需求通常较少出现。不过,随着消费电子设备的开放性增加,安全更新的需求变得更加普遍。
4.1 基本策略
内核更新的策略与根文件系统更新的策略类似,最终选择取决于应用的具体情况。以下是两种常见的策略:
-
更新内核模块
:使用内核模块可以为内核提供极大的灵活性。内核模块本质上是包含可重定位目标代码的文件,在运行时链接到内核中。在开发内核时,如果某些模块在产品发布后可能会发生变化,应将其作为模块放在根文件系统中。以下是一些考虑创建内核模块的因素:
-
开发过程中存在问题
:开发过程中遇到困难的模块,在发布后可能仍然会带来麻烦。
-
支持新硬件
:启用新硬件的代码是一个很好的候选,因为硬件文档可能不清晰或不完整。接近发布日期时更改的硬件也是一个指标,因为测试时间可能不足。
-
频繁更改的硬件
:设备上支持的硬件来自多个不同的供应商,并且在生产过程中可能会发生变化。例如,LCD 显示屏价格波动较大,买家会不断寻找更优惠的选择。
-
预期升级
:任何可能在内核运行时进行升级的内核功能都是候选对象,因为这些模块可以卸载、更新并重新加载。
-
叉车式升级
:类似于根文件系统的更新,将包含内核的闪存分区内容擦除并更新为新的内核映像。这种方法对于资源受限的设备是最实用的。即使系统使用内核模块,有时也可能需要替换核心内核,从而需要采用叉车式升级方法。
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(内核更新):::process --> B(更新内核模块):::process
A --> C(叉车式升级):::process
B --> B1(开发中问题模块):::process
B --> B2(支持新硬件模块):::process
B --> B3(频繁更改硬件模块):::process
B --> B4(预期升级模块):::process
内核更新的具体实现方法
5. 内核模块更新
内核模块更新可以将其视为对根文件系统上其他文件的更新,因此可以使用包管理器(如 Debian、ipkg 或 RPM)将内核模块部署到目标机器。系统可以通过重启或卸载并重新加载模块来应用更新。在管理内核模块时,有两种常见的方法:使用 modprobe 工具和手动管理。
5.1 使用 Modprobe
Modprobe 工具通过配置文件
/etc/modprobe.conf
来管理内核模块,它可以简化模块的加载和管理过程。以下是一个典型的
/etc/modprobe.conf
文件示例:
alias network eepro1000
alias gpio-input gpio-keys-2
options eepro1000 irq=4
在这个示例中,
alias
行允许通过别名加载磁盘上的模块,例如
modprobe network
会尝试加载
eepro1000
模块。
options
行用于定义内核模块加载时的默认选项。Modprobe 期望模块位于
/lib/modules/
uname - r
` 目录中,其中
uname - r` 是内核版本号。
使用 Modprobe 的好处是可以通过配置文件实现模块名称的间接引用,方便在更新模块时保持系统脚本中模块名称的一致性。例如,在更新前,根文件系统中可能存在以下文件:
/lib/modules/2.6.11-yourkernel/
somemodule-rev1.ko
更新后,文件系统中会增加新的模块版本:
/lib/modules/2.6.11-yourkernel/
somemodule-rev1.ko
somemodule-rev2.ko
同时,
modprobe.conf
文件也需要相应更新:
更新前:alias somemodule somemodule-rev1.ko
更新后:alias somemodule somemodule-rev2.ko
在更新模块时,可以使用
modinfo
工具快速检查模块是否存在且格式正确:
MODULE_LIST="module1 module2"
ERRORS=0
for m in $MODULE_LIST ; do
if ! modinfo $m > /dev/null ; then
let "ERRORS = $ERRORS + 1"
fi
done
if $ERRORS == 0 ; then
update_modules_conf
fi;
5.2 手动管理模块加载
如果模块加载需求较为复杂,例如需要根据条件加载模块或从非标准位置加载模块,Modprobe 工具可能无法满足需求。此时,可以使用
insmod
工具手动加载模块。
使用
insmod
工具需要手动管理模块的加载顺序。一种常见的方法是将需要加载的模块放在一个目录中,并编写一个小的 shell 脚本按正确顺序加载这些模块。例如:
/var/modules-rev1
somemodule.ko
anothermodule.ko
loadmodules
/var/modules-rev2
somemodule.ko
anothermodule.ko
athirdmodule.ko
loadmodules
/var/modules-current -> /var/modules-rev2
其中,
loadmodules
脚本可能包含以下内容:
insmod somemodule
insmod anothermodule
当有新的模块集添加到系统时,将其放在一个单独的目录中,避免覆盖现有模块。通过符号链接
/var/modules-current
指向当前要加载的模块集,这样加载模块的脚本可以保持不变。当新模块经过检查并确认可用后,更新符号链接指向新的模块目录。
6. 叉车式内核更新
叉车式内核更新类似于根文件系统的更新,即擦除包含内核的闪存分区内容,并使用新的内核映像进行更新。与根文件系统更新不同的是,内核加载到内存后不依赖于分区,因此更新过程中无需担心分区数据的完整性。
以下是一个执行内核更新的示例脚本:
KERNEL_FILE=uimage.new
FLASH_DEVICE=/dev/mtd1
这个脚本定义了新内核文件的名称和要更新的闪存设备。在实际使用中,需要根据具体情况调整这些参数。
总结
现场更新是嵌入式系统维护的重要组成部分,包括 apt 库的构建、ipkg 包管理器的使用、initramfs 根文件系统的管理以及内核更新等方面。每种更新方法都有其适用场景和操作步骤,开发者需要根据系统的具体需求和资源限制选择合适的更新策略。在进行内核更新时,无论是更新内核模块还是采用叉车式更新,都需要谨慎操作,确保系统的稳定性和可靠性。通过合理运用这些更新方法,可以使嵌入式系统始终保持最佳性能和安全性。
嵌入式系统现场更新指南
7. 现场更新方法对比
为了更清晰地了解不同现场更新方法的特点,下面对 apt、ipkg、内核模块更新和叉车式内核更新这几种方法进行对比:
| 更新方法 | 适用场景 | 优点 | 缺点 |
| — | — | — | — |
| apt 库构建 | 有一定资源且支持 apt 包管理的嵌入式系统 | 与 Linux 系统集成度高,方便管理软件包 | 需要一定的系统资源和网络环境 |
| ipkg 包管理器 | 低资源嵌入式系统 | 轻量级,适合资源受限设备 | 功能相对较少,社区支持可能不如 apt |
| 内核模块更新 | 内核部分功能需要灵活更新的场景 | 灵活性高,可在不重启内核的情况下更新部分功能 | 需要额外管理模块加载和依赖关系 |
| 叉车式内核更新 | 资源受限设备或需要全面更新内核的场景 | 简单直接,能确保内核完全更新 | 风险较高,更新失败可能导致系统无法启动 |
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(现场更新方法):::process --> B(apt 库构建):::process
A --> C(ipkg 包管理器):::process
A --> D(内核模块更新):::process
A --> E(叉车式内核更新):::process
B --> B1(高集成度):::process
B --> B2(资源要求高):::process
C --> C1(轻量级):::process
C --> C2(功能少):::process
D --> D1(灵活性高):::process
D --> D2(管理复杂):::process
E --> E1(简单直接):::process
E --> E2(风险高):::process
8. 现场更新的注意事项
在进行现场更新时,需要注意以下几个方面,以确保更新过程的顺利进行和系统的稳定性:
8.1 备份数据
在进行任何更新操作之前,务必对系统中的重要数据进行备份。特别是在进行内核更新或根文件系统更新时,一旦出现问题,备份数据可以帮助恢复系统到之前的正常状态。可以使用外部存储设备或网络存储来保存备份数据。
8.2 测试环境
在将更新应用到生产环境之前,应先在测试环境中进行充分的测试。测试环境应尽可能模拟生产环境的硬件和软件配置,以确保更新在实际使用中不会出现兼容性问题或其他故障。可以使用虚拟机或开发板来搭建测试环境。
8.3 网络稳定性
如果更新需要通过网络进行下载,确保网络连接的稳定性至关重要。不稳定的网络可能导致下载中断或文件损坏,从而影响更新的成功率。可以在更新前检查网络连接,或者选择在网络状况较好的时间段进行更新。
8.4 更新顺序
在进行多个组件的更新时,需要注意更新的顺序。例如,在更新内核模块之前,可能需要先更新内核本身;在更新软件包时,需要确保依赖关系正确。遵循正确的更新顺序可以避免因依赖问题导致的更新失败。
9. 未来发展趋势
随着嵌入式系统的不断发展,现场更新技术也在不断演进。以下是一些未来可能的发展趋势:
9.1 无线更新
随着无线通信技术的不断进步,如 5G、LoRa 等,无线更新将变得更加普及和高效。无线更新可以实现远程设备的实时更新,无需人工干预,大大提高了更新的便捷性和及时性。
9.2 智能更新策略
未来的现场更新系统可能会采用智能更新策略,根据设备的使用情况、性能指标和环境条件等因素,自动判断是否需要更新以及更新的内容。这种智能更新策略可以减少不必要的更新,提高系统的稳定性和可靠性。
9.3 安全更新机制
随着嵌入式系统在安全敏感领域的应用越来越广泛,安全更新机制将成为现场更新的重要组成部分。未来的更新系统可能会采用更加严格的身份验证、加密和完整性检查等技术,确保更新过程的安全性和可靠性。
10. 结论
现场更新对于嵌入式系统的正常运行和持续发展至关重要。通过本文介绍的 apt 库构建、ipkg 包管理器使用、initramfs 根文件系统管理和内核更新等方法,开发者可以根据系统的具体需求和资源限制选择合适的更新策略。在进行更新时,需要注意备份数据、测试环境、网络稳定性和更新顺序等方面,以确保更新过程的顺利进行和系统的稳定性。同时,随着技术的不断发展,未来的现场更新技术将朝着无线更新、智能更新策略和安全更新机制等方向发展,为嵌入式系统的更新带来更多的便利和保障。
总之,掌握现场更新技术是嵌入式系统开发者必备的技能之一,合理运用这些技术可以使嵌入式系统始终保持最佳性能和安全性,满足不断变化的应用需求。
超级会员免费看
2862

被折叠的 条评论
为什么被折叠?



