分类: LINUX
2008-04-26 18:24:41
因为Linux最初是为桌面或服务器系统设计的,默认情况下,它没有为尺寸大小进行过优化,无论如何,Linux正被越来越多地用在嵌入式设备中,要让Linux变小不是一件容易的事情,这里有几个减少系统占用内存的方法。
许多工程师是从减少内核大小开始的,这里有个容易着手的方法,本文将详细介绍如何减少内核的大小,主要通过移除那些在一个典型的嵌入式系统中用不到的代码。
在一个系统中根文件系统(RFS)可能是内存资源最大的消耗者。根文件系统包括了应用程序和c库使用到的基础结构代码。为RFS选择文件系统对最后的大小有非常大的影响,标准是ext3,从一个嵌入式工程师的眼光来看它的效率是非常低的,但那是另一篇文章的主题了。
实际中,如何减小?
即使最小的Linux发行版至少也有两部分:内核和根文件系统。有时,这些部件驻扎在同一个文件中,但是它们仍然分成不同的部件。从内核中移除特征几乎差不多的所有代码,这样一个系统很容易就减少到不到1MB大小。但是,许多用户选择Linux支持网络和不同设备,因此这不是一个现实的做法。
内核
Linux内核非常有趣,尽管在编译时它依赖GCC,但运行时它却不依赖。那些工程师将目光转向Linux初始化RAM磁盘(所谓的initrd),它是内核运行时的附属物。Initrd首先是由内核加载的,程序运行时询问系统需要载入什么模块以便支持设备,这样真实的根文件系统才能被加载。实际上,有两步加载过程,加载initrd后再加载真实的根文件系统,很少发现嵌入式系统中有根文件系统,因为这样在一个系统中会增加灵活性,对这个系统做改动要花费额外的空间或时间,嵌入式系统一般不需要灵活性。但本文稍后将讨论根文件系统。
可载入模块支持
内核载入模块是重新定位运行时内核连接到它自身的代码,典型的可载入模块的例子是允许从用户空间载入驱动到内核中(某些探测进程执行后),以及不关闭系统升级设备驱动。对于大多数嵌入式系统而言,一旦它们处于该范围之外,修改根文件系统要么不现实要么不可能。因此系统设计者直接将模块连接到内核中,移除那些可载入的模块,节约出来的空间对于内核来说是很多的,无论如何,程序管理可载入的模块(如insmod\rmmod\lsmod)和shell脚本载入它们不是必需的。
Linux-tiny补丁
Linux-tiny补丁集已经变得时有时无的项目了,最初是由Matt Mackall在主持。消费电子Linux论坛(CLEF)正在努力恢复这个项目,CLEF开发者WiKi已经给2.6.22.5内核(写本文时的最新版本)发布了补丁,同时,Linux-tiny项目的许多改变已经包括在主线内核中,尽管许多原始的Linux-tiny补丁已经集成到内核中,但实质上节约空间的补丁还没有集成进去。
如:
1、 Fine-grain printk support【细粒度printk支持】:用户可以控制什么文件可以使用printk。工程师将从不使用printk的文件大小中受益。
2、 Change CRC from calculation to use table lookup【改变CRC算法从计算到使用表查询】:以太网数据包需要一个CRC来校验数据包的准确性。这个CRC算法实现使用表查询替换了计算,节约了大约2K。
3、 Network tweaking【网络调整】:几个补丁包减少支持的网络协议,缓存大小和打开的套接字。许多嵌入式设备仅支持少量的协议,不需要有成百上千连接的服务。
4、 No panic reporting【无应急报告】:如果设备有三个状态灯,一系列的连接,用户不能看到,更少的影响,应急信息显示在一个不存在的终端上。如果设备发生内核应急失效,用户只需要重新启动设备即可。
5、 Reduction of inlining【减少直接插入】:直接插入是编译器将代码作为宏拷贝到它调用的每个位置,而不是产生一个函数调用。GCC默认将直接插入任何函数。通过抑制直接插入函数,代码运行稍微慢一点,因为编译器需要为调用和返回产生代码,得到的报酬是对象文件更小了。
Linux-tiny补丁发布成一个tar包,它可以一起应用,也可以一个一个单独应用。