本章研究基于代码分析的Linux系统剪裁。通过对Linux内核进行的需求分析,软件体系结构分析,图示方法的代码分析,可以更深入地对Linux和libc进行功能上的剪裁。
一般进行的软件剪裁是基于Linux程序员为剪裁者提供的内核条件编译系统。这种剪裁由于不需要代码分析,所能达到的程序是比较低的。原因大致有三:一是在Linux内核中安插了很多的条件编译语句,这样过多地利用条件编译,实际上损害了源代码的可读性和可维护性。多种编译路径的组合,也会导致调试和测试的复杂。所以原软件设计时不可能优先考虑可剪裁的问题。二是原软件设计时的运行环境不同于嵌入式环境。其使用的算法和数据结构都没有考虑到程序运行时的空间效率,三是为了可扩展的需要也会采用一些占用空间的接口设计。
本章在源代码分析基础上研究Linux系统的剪裁,简单介绍剪裁中采用的方法。
需求分析是功能裁剪的基础。做嵌入式Linux系统需求分析要分析其它两层:
(1)硬件层:考虑到嵌入系统的硬件配置。
(2)应用程序层:考虑到对应用软件及其相应的库文件的支持。
4.2 软件体系结构分析
软件体系结构分析阶段,面对的主要是软件设计的思想。剪裁者应该尽可能地了解原软件的背景知识。不同的软件对应不同的领域,不同的领域决定了软件的性质。同一领域也流行着不同的具体软件体系结构设计,要分析待剪裁的软件选择了哪一种,选择的依据何在,与其他经典设计相比优缺点如何评价。该种软件的结构依赖于剪裁否,如果答案是否,那得重新考虑清楚。看有没有其他选择,有可能要由零开始设计软件。
这一阶段,不似随后的阶段,剪裁者可以不多接触代码细节,以免过早陷入泥潭中。主要任务是进行软件体系结构分析。另外可以从无数可利用资源中获取信息。注意的是,软件开发者在软件中体现出来的指导设计思想,会一再地出现,不仅在软件体系的选择上,或者在设计模式、编码模式上。这是软件开发者的思维定势,剪裁者可以加以把握。
现在进入代码分析的阶段。目标是用一定的标记法表示软件子系统下的结构,具体说来就是文件、文件间的调用关系或者层次关系、该子系统提供给其他子系统或系统外的接口。
如果项目的预算充裕的话,严格的软件逆向工程可以考虑,但其通常耗费
巨大,周期较长,要走一个从实现而设计到分析再到需求,再从新需求而分析到设计再到实现的回路。也有另外的思路。从实现模型中得到代码的上层逻辑表述模型,这可以视为设计模型层和实现代码的中间层。如果我们将源代码组成的系统分解或者做如阅读、修改、增删的动作,那么文件是最自然的粒度。所以从软件的物理装配结构图(也即配置模型)着手,尽量快捷地得到代码模型的上层表述。
4.4 结构的调整技术
子系统的剪裁分结构的调整和功能的剪裁。结构调整是彩轻量级的结构和消除多余的代码。轻量级结构是模式可循的。通过改变一些被认为空间效率低的设计结构,有可能使整体软件规模变小。在嵌入式系统设计中,通常以事件驱动进行体系结构设计。这不似一般的分时系统过多地考虑用户用户程序界面的友好、硬件底层和多进程的保护等,贴近硬件和软件物理意义的设计风格使系统功能较少、但更为小巧。而消除多余代码主要靠需求分析和需求之上的功能剪裁。
对Linux系统而言可剪裁的功能包括各种驱动程序、各种文件的支持,和涉及到内核基本功能和系统调用和系统各个模块的剪裁。
Linux
是基于POSIX标准,并综合了不少流行Unix标准设计的系统调用。考虑到嵌入式应用程序的需要,应该可以加以剪裁,也可参考Unix的其他标准,如基本的V7,具有较少的系统调用。这样做,可能会让应用程序开发者感到不快,因为限制了其使用操作系统的能力。其次,这会给可能利用的第三方函数库造成困难。因此,对系统调用剪裁时一定要慎重。
一、libc的功能剪裁工具
libc
是与GNUC编译程序配合的库程序,功能是实现ANSIC库和某些扩展如POSIX、BSD、INET等等。libc可以以静态或动态形式与用户的C应用程序连接。libc动态库的概念主要的目的就是在有多个应用程序使用同一库文件时节约运行时空间。
当我们对整体Linux系统的大小进行分析时,会发现libc这个通用组件占用的空间很大。目前通行的Glibc2.1(即libc6)的动态库大约有1.5Mbytes,而旧的libc5的动态库也有大约700Kbytes。这些数字都跟内核的尺寸差不多。因此,许多做嵌入式Linux系统的组织都在对libc进行剪裁。相对于内核的剪裁来说,对libc的剪裁要小些。但是标准的libc本身并没有提供对剪裁的直接支持,这是与Linux内核相比的不方便的地方。
基于代码分析的剪裁过程可分为软件需求分析、软件体系结构分析、代码分析、子系统的调整和功能的剪裁几个步骤。但由于毕业设计时间有限,而且基于代码分析的剪裁难度较大,所以本文所实现的嵌入式系统没有进行内核剪裁,在这里只做简单介绍。