嵌入式系统设计与调优指南
1. 系统设计:PAM 安装与配置
1.1 PAM 安装步骤
在嵌入式设备中安装 PAM(Pluggable Authentication Modules),可按以下步骤操作:
1. 解压 PAM 源码包:
$ tar xzf Linux-PAM-1.1.0.tar.gz
- 进行交叉编译配置:
$ CC=arm-linux-gcc ./configure --host=arm-linux \
--prefix=$ROOTFS
- 编译并安装:
$ make ; make install
1.2 空间优化
上述过程会将完整的 PAM 安装到根文件系统中,但对于嵌入式设备而言,可能存在多余的部分。因此,需要移除 PAM 配置文件中未使用的模块,例如
/lib/security
目录下未使用的 PAM 模块。同时,对剩余部分进行剥离处理,以进一步减少空间需求。另外,若不使用 PAM 的访问控制功能,可移除
etc/security
目录下安装的一组文件。
1.3 Flex 编译问题
在配置 PAM 时,可能会遇到编译问题,提示找不到
yywrap
符号。这是因为 PAM 使用 Flex 来解析其配置文件,而
yywrap
是 Flex 分词器包的一部分。若出现此问题,需为工具链交叉编译 Flex,具体步骤如下:
1. 下载 Flex 源码包:
$ wget http://prdownloads.sourceforge.net/flex/flex-2.5.35.tar.gz?download
- 解压源码包:
$ tar xzf flex-2.5.35.tar.gz
- 进行交叉编译配置:
$ CC=arm-linux-gcc ./configure –host=arm-linux –prefix=/path/to/sysroot
其中,
/path/to/sysroot
是工具链的 sysroot 路径。这些文件可安装在开发机的任何目录,只要链接器能够找到它们即可,但不要安装到目标设备的根文件系统中,因为它们仅用于构建 PAM 库和辅助程序。
1.4 服务配置
PAM 安装并构建完成后,目标设备上的软件即可开始使用 PAM 进行身份验证。以运行 Samba 的设备为例,若要使用不同于 “other” 的配置,需在
pam.conf
文件中添加相应条目。同时,还需对 Samba 进行正确配置,使其知道使用 PAM 进行身份验证。在项目开发过程中,需确保每个期望使用 PAM 的服务都得到正确配置,因为这是特定于软件包的设置。
2. 系统调优:概述与资源分类
2.1 调优目标与资源分类
对于嵌入式设备,RAM 和存储资源通常是固定的,因此在某些项目中,有很大的压力需要减少系统对这些资源的使用。系统调优的目标包括减小系统大小和加快系统启动速度。嵌入式系统可大致分为三类:
-
存储容量仅为几兆字节的系统
-
存储容量在 16 - 32MB 左右的系统
-
配备数 GB 硬盘的系统
本文主要关注前两类系统,因为当系统的存储介质超过几百兆字节时,通常无需过于关注系统大小的优化,不过可能会对缩短系统启动时间感兴趣。
2.2 系统大小优化方面
在 Linux 系统中,可从以下三个方面减小系统大小:
-
内核
-
根文件系统
-
应用程序本身
虽然从技术上讲,应用程序是根文件系统的一部分,但从逻辑角度看,它是系统的一个独立部分。作为应用程序的开发者,对代码的控制程度要比对开源项目的控制程度高。不过,要在开源项目中进行必要的更改以减小其大小,可能需要学习不同的代码库,这在项目的时间预算内可能不可行。
2.3 运行时内存优化方面
系统在存储中的大小与应用程序运行时的大小是不同的概念。指令数量少的代码在运行时可能占用更多内存。编写在运行时能有效利用内存的代码,是软件工程师在大小与速度之间的经典权衡,因为增加的内存大小代表了缓存的信息,而不是在需要时进行计算。
2.4 不同资源系统特点分析
| 资源分类 | 特点 | 设备示例 | 调优目标 |
|---|---|---|---|
| 3MB 及以下 | 应用需求略高于微控制器,可能连接低功耗网络,通常采用电池供电,处理器时钟频率低,用户界面简单 | 连接 ZigBee 的设备,使用部分 IP 网络栈 | 消除所有非必要的文件系统、网络和输入设备,精简内核和根文件系统,确保应用程序简单高效 |
| 16 - 32MB | 能执行更复杂的任务,如运行小型全彩 LCD 并配备触摸屏,可能具备网络或语音处理功能,常为电池供电,处理器需低时钟频率以节省电量 | 消费类设备、DVR、家用路由器/网关 | 尽可能减小应用程序大小,加快设备开机后可用时间,确保内核只包含必要组件,优化启动顺序,识别并解决性能瓶颈 |
| 大于 1GB | 配备硬盘,存储容量大,减少操作系统大小对可用存储空间比例提升不明显,但可能关注缩短设备启动时间 | 自动售货机、零售亭、自助零售 POS 系统 | 减少设备启动时间 |
3. 系统调优:不同存储容量系统特点
3.1 3MB 及以下系统
这类系统的应用需求略高于微控制器,可能连接低功耗网络,如 ZigBee,并使用部分 IP 网络栈。其特点包括:
-
供电与性能
:通常采用电池供电,因此配备低时钟频率的处理器。
-
用户界面
:用户界面可能仅由几个 LED 或小型 LCD 显示屏组成,输入方面除了开/关开关外,可能还有几个按钮。
-
系统优化
:由于资源有限,创建小型发行版相对容易。可通过消除所有文件系统、网络和输入设备,大幅缩减内核。同时,根文件系统中的应用程序也应尽量精简,通常该设备在启动时只运行一个程序,若程序失败则应重新启动。
3.2 16 - 32MB 系统
这是一个较为特殊的内存范围,设备能执行更复杂的任务,如运行小型全彩 LCD 并配备触摸屏,可能具备网络或语音处理功能。其特点和挑战如下:
-
设备类型与需求
:许多消费类设备属于此范围,面临降低单位成本和为最终用户提供更多功能的双重压力。此外,这些设备常为电池供电,处理器需以低时钟频率运行以节省电量。
-
优化目标与方法
:优化此类设备时,目标是尽可能减小应用程序大小,并加快设备上电后可使用的时间。关键在于确保内核只包含必要的组件,重新排序启动顺序以使应用程序更快运行,并通过测量来识别问题点。值得注意的是,该内存范围的下限为 16MB,因为这是常见的内存组件,且更小的内存通常比单个 16MB 组件更昂贵。在系统设计过程中,由于巧妙的经济和电气工程设计,可能会获得比预期更多的资源。
3.3 大于 1GB 系统
这类设备配备硬盘,无论是传统的盘片和主轴设备,还是带有作为闪存转换层的硬件(可能是微控制器)的固态硬盘,其存储容量都非常大。因此,减少操作系统大小对可用存储空间比例的提升并不显著,但可能对缩短设备启动时间有较大兴趣。例如,自动售货机、零售亭或自助零售 POS 系统等设备,启动时间的长短对其业务运营至关重要。与 16 - 32MB 设备类似,许多此类嵌入式设备拥有较多资源,是因为获取更大内存组件或采购具有该内存量的完整电路板更便宜。
3.4 不同存储容量系统调优流程
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B{存储容量大小?}:::decision
B -->|3MB 及以下| C(消除非必要组件):::process
B -->|16 - 32MB| D(优化应用程序与启动顺序):::process
B -->|大于 1GB| E(缩短启动时间):::process
C --> F(精简内核和根文件系统):::process
D --> G(确保内核必要且优化启动):::process
E --> H(优化启动流程):::process
F --> I([结束]):::startend
G --> I
H --> I
4. 系统调优:根文件系统优化
4.1 从零开始构建根文件系统
优化根文件系统是一个很好的起点,因为它最有可能存在浪费空间的情况。从零开始构建根文件系统,能促使你仔细思考每个新组件的添加,并理解添加的原因。以下是创建最小根文件系统内容的步骤:
1. 创建并进入最小根文件系统目录:
$ mkdir ~/minimal-rfs; cd minimal-rfs
- 创建必要的目录:
$ mkdir ./proc ./tmp ./dev
- 创建设备节点:
$ sudo mknod ./dev/console c 5 1
$ sudo mknod ./dev/null c 1 3
4.2 根文件系统与应用程序特点
应用程序应位于文件系统的根目录,并且必须持续运行,否则系统将停止,因为在 Linux 系统中至少要有一个进程在运行。该根文件系统可构建为 initramFS,并与内核组装在一起,包含在部署到设备的内核映像文件中。应用程序应进行静态链接,无需额外的文件。这种根文件系统在应用程序的基础上仅增加约 3KB 的空间,对于只有几兆字节的闪存驱动器来说,剩余空间看起来非常充裕。此类应用程序通常较为简单,例如读取测量值、等待用户扫描条形码并执行查询等。
4.3 内核参数设置与启动速度
使用这种方法时,需将内核的
init=
参数设置为应用程序,或将应用程序命名为
linuxrc
,以便系统启动时运行。实际上,这个系统非常小,只要应用程序代码效率合理,系统启动速度也会非常快。一般来说,从零构建的系统启动速度快,因为追求小型化会将系统精简到最基本的组件,甚至舍弃用于脚本编写的 shell。
4.4 最小根文件系统常见疑问解答
| 疑问 | 解答原因 |
|---|---|
| 需要登录方式 | Linux 运行 init 时以用户 ID 0 和组 ID 0 执行,即具有所有系统权限的根用户,登录仅用于开发或维护的后门 |
需要
/etc/passwd
和
/etc/groups
| 由于无需登录,用户名和组名均为空字符串 |
| 需要 shell(如 sh 或 bash) | 没有 shell 脚本,因此不需要 shell |
需要特殊的启动程序(如 init)和
/etc/init.d
目录
| init 程序可以是任何可执行文件,在小型系统中,初始化程序是唯一运行的程序,因此它就是 init |
需要
/lib
中的内容
| 只要应用程序是静态链接的,就无需将库复制到目标设备 |
| 需要网络初始化脚本 | 网络可以在核启动时使用静态地址进行配置,也可以从 BOOTP/DHCP 服务器请求地址,还可以在应用程序中进行配置,而无需通过 shell 脚本 |
| 需要内核模块 | 在最小的计算机中,内核将所有模块直接编译到自身中,因此不需要模块或加载它们的脚本 |
需要
/dev
目录的内容
|
该目录中的大多数设备是运行 udev 的结果,udev 会扫描
/sys
文件系统以按需创建设备节点,此系统的所有设备节点都是手动创建的
|
需要
/var/log/messages
| 该文件由内核日志记录程序创建,该程序读取共享内存区域并将数据存入此文件,若不运行此日志记录功能,日志数据将保留在共享内存中,当区域填满时,最旧的数据将被覆盖 |
4.5 挂载小型文件系统
挂载存储在闪存驱动器上的小型文件系统时,有一个额外的注意事项:设备没有 MTD 块设备的额外文件节点,创建该文件会浪费几字节的内存,因此应尽量节省。过去挂载根文件系统时,通常使用设备的符号名称,如
root=/dev/mtdblock3
。为了不浪费任何字节,可以使用设备的主设备号和次设备号来挂载,这是内核用于确定使用哪个驱动程序的数字标识符。例如,设备的标识符可能看起来像
root=6703
,其中前两个整数是
/dev/mtdblock3
的主设备号和次设备号的十六进制表示。可以使用
ls -l
命令在板上打印出这些值:
$ ls -l /dev/mtdblock3
crw------- 1 root root 90, 3 2009-10-02 07:41 console
对于此设备,标识符为
5A03
,因为
5A
是 90 的十六进制值,
03
是 3 的十六进制值,为了正确解析该值,字段需要用零填充。最终,在内核命令行上的根设备设置为
root=5A03
。
4.6 共享库处理
更复杂的应用程序会使用共享库,这意味着需要从工具链中收集这些库,并将它们放置在目标机器的根文件系统中。共享库需要一个加载器才能正常工作,加载器会在程序运行前执行动态链接步骤。共享库加载器体积小且为静态链接,必须位于可执行文件指定的位置。可以使用
strings
命令找出加载器的名称:
$ strings <your program> | grep ld
你要查找的文件名为
/lib/ld-linux.so.X
或
/lib/ld-uClibc.so.X
,其中 X 是版本号。该文件必须在目标文件系统上位于可执行文件中包含的相同路径,无法进行重定位。还可以通过
strings
命令强行获取可执行文件使用的共享库。以下示例中,
<your program>
是一个字体管理程序
fc-list
,不同程序使用的库会产生不同的结果:
$ strings <your program> | grep “lib*”
/lib/ld-uClibc.so.0
libfontconfig.so.1
libiconv.so.2
libfreetype.so.6
libz.so.1
libexpat.so.1
5. 系统调优:工具与策略总结
5.1 调优工具概述
在对嵌入式系统进行调优时,有一些工具可以帮助我们确定优化的重点方向。虽然每个系统都存在资源限制,但在嵌入式领域,这些限制在日常编程中更为突出。在开始调优之前,了解系统在资源受限范围内的大致位置非常重要,因为这会影响整个系统调优的策略。
5.2 不同资源系统调优策略总结
| 资源分类 | 调优策略重点 |
|---|---|
| 3MB 及以下 |
- 消除非必要的文件系统、网络和输入设备,精简内核和根文件系统。
- 确保应用程序简单高效,通常只运行一个程序。 - 手动创建设备节点,避免使用动态设备节点创建机制。 |
| 16 - 32MB |
- 尽可能减小应用程序大小,采用静态链接等方式。
- 优化启动顺序,确保内核只包含必要组件。 - 通过测量找出性能瓶颈并解决。 |
| 大于 1GB | - 重点放在缩短设备启动时间上,优化启动流程。 |
5.3 调优流程回顾与强调
回顾之前提到的不同存储容量系统调优流程:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B{存储容量大小?}:::decision
B -->|3MB 及以下| C(消除非必要组件):::process
B -->|16 - 32MB| D(优化应用程序与启动顺序):::process
B -->|大于 1GB| E(缩短启动时间):::process
C --> F(精简内核和根文件系统):::process
D --> G(确保内核必要且优化启动):::process
E --> H(优化启动流程):::process
F --> I([结束]):::startend
G --> I
H --> I
这个流程清晰地展示了针对不同存储容量的系统,应该采取的主要调优步骤。对于 3MB 及以下的系统,核心是消除非必要组件并精简内核和根文件系统;16 - 32MB 的系统着重优化应用程序和启动顺序;大于 1GB 的系统则聚焦于缩短启动时间。
5.4 调优的综合考量
在实际的系统调优过程中,不能仅仅关注某一个方面,而需要综合考虑多个因素。例如,在减小系统大小的同时,要确保应用程序的功能不受影响,并且系统的性能不会显著下降。同时,在优化启动时间时,也要注意不要过度牺牲系统的稳定性和可靠性。
6. 总结与最佳实践建议
6.1 总结回顾
本文详细介绍了嵌入式系统设计与调优的相关内容。在系统设计方面,阐述了 PAM 的安装与配置过程,包括安装步骤、空间优化、解决 Flex 编译问题以及服务配置等。在系统调优方面,对不同存储容量的嵌入式系统进行了分类,分析了它们的特点和调优目标,并针对根文件系统的优化提供了具体的方法和步骤,如从零开始构建根文件系统、挂载小型文件系统以及处理共享库等。
6.2 最佳实践建议
-
系统设计阶段
- 在安装 PAM 时,及时进行空间优化,移除不必要的模块和文件,避免资源浪费。
-
遇到编译问题时,如找不到
yywrap符号,要及时为工具链交叉编译 Flex。 - 确保每个期望使用 PAM 的服务都得到正确配置,根据不同服务的需求进行个性化设置。
-
系统调优阶段
- 根据系统的存储容量,选择合适的调优策略。对于资源有限的系统,要坚决消除非必要组件;对于资源相对充足的系统,可在保证功能的前提下,优化启动时间和应用程序大小。
- 从零开始构建根文件系统,仔细思考每个组件的添加,避免引入不必要的开销。
- 在处理共享库时,准确找出加载器的名称和路径,并将其正确放置在目标文件系统中。
- 定期使用工具对系统进行测量和分析,及时发现并解决性能瓶颈问题。
通过遵循这些最佳实践建议,可以有效地提高嵌入式系统的性能和资源利用率,使系统在满足功能需求的同时,更加高效、稳定地运行。
超级会员免费看
2864

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



