1.3 通用架构的内核变化
在uClinux的发布中,/linux/mmnommu目录取代了/linux/mm目录。前者就是修改后的内存管理子系统被修改,去除了MMU硬件的依赖,并在内核软件自身提供基本的内存管理函数。
很多子系统需要被重新修改、添加或者重写。内核和用户内存分配和释放进程必须重新实现。对透明交互/页面调度的支持也被去除。
内核中,加入了支持“位置无关代码(PIC)”的程序加载模块,并使用了新的二进制目标码格式,称为“扁平”格式(flat),用来支持PIC(有非常紧凑的头部)。内核也提供了支持ELF格式的程序加载模块,用来支持使用固定基准地址的可执行程序。两种模式各有利弊,传统的PIC运行快,代码紧凑,但是有代码大小限制。例如Motorola 68K架构的16位相对跳转限制了PIC程序不能超过32kbyte大小。而采用运行期固定基址的方法使得没有了代码大小限制,不过当程序被内核加载后招致了较多的系统开销。
1.4 uCLinux的内核加载方式
uCLinux的内核有两种可选的运行方式:可以在flash上直接运行,也可以加载到RAM中运行。
Flash运行方式:把内核的可执行映像文件烧到flash上,系统启动时从flash的某个地址开始逐句执行。这种方法实际上是很多嵌入式系统采用的方法。
内核加载RAM方式:把内核的压缩文件存放在flash上,系统启动时读取压缩文件在内存里解压,然后开始执行,这种方式相对复杂一些,但是运行速度可能更快。同时这也是标准Linux系统采用的启动方式。
1.5 uCLinux的文件系统
uCLinux系统采用ROMFS文件系统,这种文件系统相对于一般的ext2文件系统要求更少的空间。空间的节约来自于两个方面:首先内核支持ROMFS文件系统比支持ext2文件系统需要更少的代码;其次ROMFS文件系统相对简单,在建立文件系统超级块(superblock)需要更少的存储空间。ROMFS文件系统不支持动态擦写保存,对于系统需要动态保存的数据采用虚拟RAM盘的方法进行处理(RAM盘将采用ext2文件系统)。
应用程序如果需要以文件方式交换数据,可以将它存储在/tmp目录下。这一目录实质上就是虚拟的RAM盘。不过在掉电时,这些数据就会丢失。
如果希望在掉电时,信息仍然可以保持,那么就要把它写到FLASH中。这时,就可以使用JFFS这一文件系统,在uClinux的发布中,文件“/linux/drivers/block/flash.c”中提供的JFFS代码可以参考。
另外,还需要修改/linux/.config和include/linux/autoconf.h中的有关内容,增加对FLASH和JFFS的编译。
2 uClinux程序设计要点
2.1 软件开发工具
可以免费获得的GCC(GNU C Compiler)无疑是uClinux上最佳的开发工具。
uClinux系统的软件开发需要在标准Linux平台上用编译工具来完成。除了前面所提到的一些涉及内存和系统调用的程序之外,在x86版本的gcc编译器下编译通过的软件通常不需要做大的改动就可以用交叉编译工具编译到uClinux上运行。
交叉编译器可以从下面网址获得:
http://www.uclinux.org/pub/uClinux/m68k-elf-tools/
目前最新的版本是2.95.3:m68k-elf-tools-20020410.tar.gz
交叉编译器直接解在根目录(/)下就行了:(注意当前目录是/,而且m68k-elf-tools-20020218.tar.gz要在/下)
tar xzf m68k-elf-tools-20020218.tar.gz
它会自动在/usr/local/下建立起整套m68k的ELF交叉编译器,要编译自己的简单C程序就可以用/usr/local/bin/m68k-elf-gcc,例如,源代码为test.c,那么可以这样编译:
/usr/local/bin/m68k-elf-gcc –Wall -elf2flt -m5307 test.c –lc –o test.out
参数“-Wall”指定产生全部的警告;-elf2flt指定自动调用elf转换flat格式的工具;-m5307指定了处理器的指令集;-lc指定了链接信息(ld);-o指定输出文件的名字。
编译成功后得到的test.out就可以在uClinux环境上运行(通过nfsmount、smbmount,或者直接放到内核映像中都可以)。
也可以建立一个简单的Makefile来做这件事情:
CC = /usr/local/bin/m68k-elf-gcc
all:
$(CC) -Wall -elf2flt -m5307 test.c -lc -o test.out
通过GDB可以调试目标板,Coldfire处理器可以通过Motorola的BDM作为调试接口,可以在不干扰程序正常运行的情况下调试目标板上的内核。如果处理器不支持,那么在内核中需要插桩(stub),GDB和stub通过串行口或者以太网通讯。
2.2 可执行文件格式
先解释几种可执行文件格式。
coff(common object file format):一种通用的对象文件格式;
elf(excutive linked file):一种为Linux系统所采用的通用文件格式,支持动态连接和重定位;
flat:扁平格式。elf格式有很大的文件头,flat格式对文件头和一些段信息做了简化,可执行程序小。
uCLinux系统目前支持flat和elf两种可执行文件格式。
2.3 uCLinux的应用程序库
uCLinux小型化的另一个做法是重写了应用程序库,相对于越来越大且越来越全的glibc库,uClibc对libc做了精简。
最新版本的程序库可以从这个网址获得:
http://uclibc.org/download/uClibc-0.9.10.tar.gz
uCLinux对用户程序采用静态链接的形式,这种做法会使应用程序变大,但是基于内存管理的问题,也就是基于没有MMU的特性,只能这样做,同时这种做法也更接近于通常嵌入式系统的做法。
uClibc提供大多数的类UNIX的C程序调用。如果应用程序需要用到uClibc中没有提供的函数,这些函数可以加到uClibc中、或者作为一个独立的库、或者加到应用程序上面来进行链接。
2.4 裁减uCLinux以适合自己的应用
不同的嵌入式系统之间的根文件系统内容差异很大。uClinux的发布包括一个根文件系统,实现了一个小型的类UNIX服务器,在串口上有控制台,telnet daemon,web server,NFS客户端支持和一些可选的常用工具。
但是,有的系统设计可能不需要控制台,例如,如果设计一个可以播放MP3的随身CD机,内核只需要支持CD驱动、并行I/O和音频DAC。而在用户空间可能只包括一个接口程序来驱动按钮、LED、来控制CD播放,并调用MP3的解码程序。
2.5 关于uClinux 2.4内核
2001年发布了uClinux 2.4,支持龙珠和coldfire处理器,基于2.4内核的一些增强特性同样做到了uclinux 2.0系列上。目前一些应用仍然基于2.0.x空间的。然而2.4内核使得开发者可以访问很多新的特性,例如支持USB、IEEE火线、IrDA和新的网络特点,例如带宽分配、QoS、IPv6等等。
如果在应用程序中需要使用2.4的新特性,可以在编译uClinux内核时,选择2.4的版本。不过,2.4毕竟是较新的内核,有可能不稳定的风险。
