关于Linux内核的裁减

发 布 时 间 : 2008-11-18 来 源 : 来自网络 作 者 : 匿名 浏 览 :

最小的 Linux kernel

这篇文章有些奇怪,在文章的一开始,我就要宣称本文是没有太大意义的。

Linux 能有多小呢 ? 每一个做 embedded 系统的人都把小看成第一要务,其实这是不对的。如果我们对系统的好坏和大小作图,它应该长得像
|
|----
|
| -----
|
| --------
| ---
|-----------------------

小当然不会比较坏,但不一定比较好。如果系统使用 4MB 和 5MB 没有价格或性能上的差别,那 4MB 和 5MB 是一样好的。

到底有多小

废话说了一堆,那到底 Linux 有多小呢? 好吧,各位这么有小牛顿的精神。我也只好想办法生一个答案出来了。

首先我必须声明,我的不一定最小。不要说我在欺骗世人,你的核心比我小。我无意比较,我的数据只是给大家一个参考而己。不过我欢迎大家提出自己的心得,告诉大家怎么样做出更小的核心。

我使用的是 Mandrake 内付的 2.2.15,我没有修改任何一行程序码,完全只靠修改组态档得到这些数据。

首先,使用 make xconfig 把所有可以拿掉的选项都拿得。

不要 floppy
不要 SMP,MTRR
不要 networking,SCSI
把所有的 block device 移除,只留下 old IDE device
把所有的 character device 移除
把所有的 filesystem 移除,只留下 minix
不要 sound 支援
相信我,我己经把所有的选项都移除了。这样做之后,我得到了一个 188K 的核心。
还不够小吗? OK,再加上一招,请把下列二个档案中的 -O3,-O2 用 -Os 取代。
./Makefile
./arch/i386/kernel/Makefile

这样一来,整个核心水小了 9K,成为 179K。

不过这个核心恐怕很难发挥 Linux 的功能,因此我决定把网络加回去。把 General 中的 network support 加回去,重新编译,核心变成 189 K。10K 换个 TCP/IP stack,似乎是很上算的生意。

不过有 stack 没有 driver 也是惘然,所以我把 embedded board 常用的 RTL8139 的 driver 加回去,195K。

如果你需要 DOS 档案系统,那大小成为 213K。如果 minix 用 ext2 换代,则大小成长至 222K。

不过大家要注意,那里的大小指的是核心档的大小。那和所需要的随取记忆体是二回事。这个数字代表的意义是你需要多小的 ROM 来存放你的核心。

Linux 所需的记忆体大约在 600~800 K 之间。1MB 可能可以开机了,但可能不太有用。因为可能连载入 C 程序库都有困难。2MB 应该就可以做点事了,但可能要到 4MB 以上才可以执行一个比较完整的系统。


到底谁占了这些空间

看到这里,是不是觉得 Linux 真的有点大。好吧! 那我们就来看看谁占用了这些空间,下面这个列表是从 222K 这个核心做出来的。
# wc \
arch/i386/kernel/kernel.o arch/i386/mm/mm.o kernel/kernel.o mm/mm.o fs/fs.o \
ipc/ipc.o \
fs/filesystems.a \
net/network.a \
drivers/block/block.a \
drivers/char/char.a \
drivers/misc/misc.a \
drivers/net/net.a drivers/pnp/pnp.a \
/usr/src/smalllinux/arch/i386/lib/lib.a \
/usr/src/smalllinux/lib/lib.a \
/usr/src/smalllinux/arch/i386/lib/lib.a

 

结果如下 :


243 2250 81946 arch/i386/kernel/kernel.o
42 316 10569 arch/i386/mm/mm.o
173 1541 74660 kernel/kernel.o
266 2307 68053 mm/mm.o
222 3139 123193 fs/fs.o
49 602 21600 ipc/ipc.o
263 2940 106504 fs/filesystems.a
137 1510 65512 net/network.a
92 719 39178 drivers/block/block.a
230 2308 87556 drivers/char/char.a
1 1 8 drivers/misc/misc.a
83 721 25680 drivers/net/net.a
1 1 8 drivers/pnp/pnp.a
20 187 9526 /usr/src/smalllinux/arch/i386/lib/lib.a
23 150 7714 /usr/src/smalllinux/lib/lib.a
20 187 9526 /usr/src/smalllinux/arch/i386/lib/lib.a
1865 18879 731233 total

先说明一下,这里的大小和最终的大小有点差别,但大致还是可以做个参考。这边显示 730K 实际上大约在 600K 左右。

很显然的,filesystem 相当的大。大约在 230K 左右,占了 1/3 的体积。记忆体管理占了 80K,和核心其它部份的总合差不多。TCP/IP stack 占了 65K,驱动程序占了 120K。SysV IPC 占了 21K,必要的话可以拿掉,核心档应该可以再小个 10K 左右。

所以如果要减核心大小,应该动那里呢? 答案应该很明显,当然是档案系统。Linux 的 VFS 减化了档案系统的设计,buffer cache, directory cache 增加了系统的效率。但这些对整个系统都在 flash 上的 embedded 系统而言根本就用处不大。如果可以把它们对拿掉,核心可以马上缩小 20K 左右。如果跳过整个 VFS,直接将档案系统写成一个 driver 的型式,应该可以将 230K 缩减至 50K左右。整个核心缩到 100K 左右。

从上面的数据来看,ucLinux 所减小的 mm 部份反到省的不多,主要是 mm 除了 virtual memory 之外,也要处理 memory allocation 的部份,这部份是省不得的。如果二者齐做,则 100K 以下的 Linux 核心不是不可能的事。


结语

如果有人有闲的话,不妨拿 2.0 或 1.0 的核心来试试。看能做出多小的核心。看完本文后,143K 的核心不再是技术上的挑战了,是吗? 也许明天就有人宣称做了 120K 的核心了.....

不过,所为何来,省那几十K。不如好好想想 compressed filesystem 等更有用的技术吧!

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

接着XLinux的工程师回复:

我想我要来回应一下有关Kernel缩小化这个议题

1. 143K kernel 是我们研究这个议题的一个副产品而已,事实上,要缩小的是整个
Embedded系统,而不只是kernel而已.


2. 要缩减整个系统,所以我们开发了一些工具,可以scan 整个Embedded Linux系统,
包含kernel、library、application等,目的是作这三者间的最佳化.这些工具
将kernel无用到的System call移除,并藉由分析application来产生最精简的
Library.

3. 有时候连工具(Ex. gnu tools)本身,我们也要动一些手脚,例如一些最佳化的方式
是否适合Embedded System的需求,或是有些格式,如ELF的header是否可以缩减等.

4. Embedded 环境有时是比教特殊的,有时连Console都没有,那么把这些没用到的
程序码包含进来是没有意义的不是吗? 如果我们手边能有一些工具程序来帮我们
作这些缩减的工作,无疑是减轻系统开发人员的负担,在PC上,或许几MB或几十
MB不算什么,但在embedded中,或许这是否能拿到订单的关键.
5. 另外有一些缩减也是相当有趣的,例如printk中的Array! 仔细算算好几十K!
但也不能用手动缩减吧!

6. 总之,我们把Linux的缩小当作一个研究的issue看待,是有一些直得开发的空间,
曾经在一次embedded linux的研讨会上听到kernel小于500K是没有意义的,我想这要
看用途,不能一概而论.我们也不能只从kernel的configuration来看Embedded Linux
的缩小化.


由于您的文章中提到uCLinux,其实这个Project是 for 那些没有硬件实作MMU的CPU,
照理讲,硬件没有做,要由软件来实现的话,mm的程序会膨胀才对,就好像用软件
来模拟FPU一样.Lineo 是把这种SOC当作uC(micro-controller),所以不再用软件
实作一些mm该有的功能,看起来好像是non-MMU-->mm缩小,其实是错误的.

例如,本来由MMU来作memory的protection,在non-MMU的环境中,Linux的核心中
要增加一些程序来处理,但在uCLinux中完全没有实作.反正只是for controller
嘛,也不会load user program. It doesn't matter!
首先程序必须以PIC(position in-dependent code)选项编译,以便可以产生
relocation的程序码,然后kernel安排适当的记忆体,并且将之载入及执行,如此
才能在此无MMU的环境中执行 一个以上的程序 .

另外,程序的载入本身也是个问题,i.e. load 到那里,在有VM support的环境中
每个程序可以load到固定的位址,例如,位址0 .而不会产生冲突,因为每个VM
中的位址0, MMU 会帮忙mapping到不同的PM上.对于没有MMU 的CPU就比教麻烦了,


所以non-MMU对Linux的porting是一项吃力不讨好的工作,万一gnu tools的支援又
不够,那就有的图的,今天看到工商时报一项新闻中指出,详威已成功整合华邦
的PA-RISC CPU与其embedded linux.对于这棵源于HP但去掉FPU与MMU的SOC,
屈指算来我们也努力了一段时间了,从kernel的修改到gnu tools中软件FPU的支援,
的确吃掉不少engineer power. 最后在等HP在一两个月内完成一项gnu tools对此
PA-RISC的支援---pic选项.

想不到详威是如此的厉害,不但能够完成当初Cygnus在PA-RISC上未完成的gnu上
的加强,还能够在两三个月内完成porting,看来HP找LinuxCare来portig其工作站
版本的PA-RISC(W/MMU)至Linux,是找错对象了,将近两年了还搞不出一个
distribution,应该要找详威才是:)
==

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

接着作者又争辩道:

:□ 引述《 Timothy Shyu 》的文章 :
:我想我要来回应一下有关Kernel缩小化这个议题
:
:1. 143K kernel 是我们研究这个议题的一个副产品而已,事实上,要缩小的是整个
: Embedded系统,而不只是kernel而已.


:2. 要缩减整个系统,所以我们开发了一些工具,可以scan 整个Embedded Linux系统,
: 包含kernel、library、application等,目的是作这三者间的最佳化.这些工具
: 将kernel无用到的System call移除,并藉由分析application来产生最精简的
: Library.

I understand. I have done the same thing before.
My point is that we can save much more space by reducing the library that kernel.

It's hard to steal 500K from kernel. However, it's not so hard to get 500K from other part of systems.

:3. 有时候连工具(Ex. gnu tools)本身,我们也要动一些手脚,例如一些最佳化的方式
: 是否适合Embedded System的需求,或是有些格式,如ELF的header是否可以缩减等.
:
:4. Embedded 环境有时是比教特殊的,有时连Console都没有,那么把这些没用到的
: 程序码包含进来是没有意义的不是吗? 如果我们手边能有一些工具程序来帮我们
: 作这些缩减的工作,无疑是减轻系统开发人员的负担,在PC上,或许几MB或几十
: MB不算什么,但在embedded中,或许这是否能拿到订单的关键.

Different applications have different requirements. Your point is true for some cases.

:5. 另外有一些缩减也是相当有趣的,例如printk中的Array! 仔细算算好几十K!
: 但也不能用手动缩减吧!
We have two different requirements, size of RAM and size of flash. Buffers are related to the size of RAM. However, it doesn't affect the size of flash.

:6. 总之,我们把Linux的缩小当作一个研究的issue看待,是有一些直得开发的空间,

It's insteresting. However, I don't think it's very valuable.

: 曾经在一次embedded linux的研讨会上听到kernel小于500K是没有意义的,我想这要
: 看用途,不能一概而论.我们也不能只从kernel的configuration来看Embedded Linux
: 的缩小化.
:
:
: 由于您的文章中提到uCLinux,其实这个Project是 for 那些没有硬件实作MMU的CPU,
: 照理讲,硬件没有做,要由软件来实现的话,mm的程序会膨胀才对,就好像用软件
: 来模拟FPU一样.Lineo 是把这种SOC当作uC(micro-controller),所以不再用软件
: 实作一些mm该有的功能,看起来好像是non-MMU-->mm缩小,其实是错误的.
:


You are right. My statement is a little bit misleading. My intension is to response to some guys who think they can save some space by removing VM from kernel since they think RTOS don't need VM.

: 例如,本来由MMU来作memory的protection,在non-MMU的环境中,Linux的核心中
: 要增加一些程序来处理,但在uCLinux中完全没有实作.反正只是for controller
: 嘛,也不会load user program. It doesn't matter!
: 首先程序必须以PIC(position in-dependent code)选项编译,以便可以产生
: relocation的程序码,然后kernel安排适当的记忆体,并且将之载入及执行,如此
: 才能在此无MMU的环境中执行 一个以上的程序 .
:
: 另外,程序的载入本身也是个问题,i.e. load 到那里,在有VM support的环境中
: 每个程序可以load到固定的位址,例如,位址0 .而不会产生冲突,因为每个VM
: 中的位址0, MMU 会帮忙mapping到不同的PM上.对于没有MMU 的CPU就比教麻烦了,
:
:
: 所以non-MMU对Linux的porting是一项吃力不讨好的工作,万一gnu tools的支援又
: 不够,那就有的图的,今天看到工商时报一项新闻中指出,详威已成功整合华邦
: 的PA-RISC CPU与其embedded linux.对于这棵源于HP但去掉FPU与MMU的SOC,
: 屈指算来我们也努力了一段时间了,从kernel的修改到gnu tools中软件FPU的支援,
: 的确吃掉不少engineer power. 最后在等HP在一两个月内完成一项gnu tools对此
: PA-RISC的支援---pic选项.
:
: 想不到详威是如此的厉害,不但能够完成当初Cygnus在PA-RISC上未完成的gnu上
: 的加强,还能够在两三个月内完成porting,看来HP找LinuxCare来portig其工作站
: 版本的PA-RISC(W/MMU)至Linux,是找错对象了,将近两年了还搞不出一个
: distribution,应该要找详威才是:)
:==



上一篇:基于uClinux的开发应用程序-Helloworld和跑马灯程序 下一篇:如何在嵌入式LINUX中增加自己的设备驱动程序