2,基于Flash的uClinux系统
传统意义上嵌入式系统的存储系统通常由Flash和RAM组成。Flash的成本通常又高于RAM的成本。因此系统的存储系统由多大容量的RAM多大容量的FLASH组成,通常根据产品的需求和成本的考虑来决定。
在基于uClinux的嵌入式系统中,Flash是整个系统代码和数据的储存器件。通常的做法是将uClinux核心的起始代码放在处理器加电所运行的地址处。这个地址必定是在FLASH中的。因为NOR Flash里面的代码可以直接执行。在很多的应用中采用了不使用RAM,直接让uClinux在Flash里面运行。而出于速度和成本的考虑更多的做法是将uClinux系统存放在Flash中根据系统运行的情况把要执行的部分拷贝到RAM中执行。
为了实现上述思想我们通常把Flash分区。当然这里分区的概念和我们给硬盘分区的含义大不一样。这里的分区十分简单,就是把Flash按照地址分成不同的区间在特定的区间中放入不同的代码或者数据。使得整个系统比较有序和容易调试开发。
一个典型的例子,比如:
块号 地址 用途
0 0x0—0x? 启动代码
1
2 0x….. uClinux 核心
3
4 0x… 根文件系统
5
在这个例子中第0个分区,也就是Flash的起始位置我们放置了系统启动代码。第1个分区我们可以放置一些配置数据之类的数据。接下来的一个分区我们存放着uClinux的核心。并且我们用另外的一些分区来放置系统的根文件系统。
以此可见,我们完全可以根据自己的需要把Flash分成不同的区来使用。在以后的讨论中我们可以直到uClinux的块设备驱动支持我们这样的操作。因此我们的焦点将集中在如何划分不同的区域来达到我们的应用。
通过上面的介绍我们知道Flash的擦写需要根据Flash的扇区来进行。一次擦写至少要擦除一个扇区内所有的内容。因此我们给Flash分区的时候最先要确定的是每个分区需要多少个Flash的扇区。从第几个到第几个,这样以后的操作才可*简单。
从上面的例子来看,uClinux的内核和根文件系统并不在一个分区。内核放在一个特定的地址。要访问内核必须从某个地址开始整个的访问。而不同于我们同用的桌面版或者服务器版的Linux可以把内核作为一个文件来存放在文件系统中。
那么这两种方法有什么不同呢?
在我们的例子,把内核单独放在一个分区中。这需要启动的时候启动程序把整个内核拷贝到RAM里面然后运行它。或者采用我们前面提到的XIP
技术在Flash里面运行。而传统的Linux则需要启动程序来确定内核的位置和需要把内核的那部分加载到RAM里面来运行(类似于台式机Linux系统上的LILO或者GRIUB)。
那么如何选择Flash的分区,以及各个分区存放的内容呢?我想这个要根据各自产品的特点和开发的周期来考虑。接下来我们列出在uClinux系统中常用的几种分区方法并且讨论它们各自的优劣。
a) 内核和根文件系统都在固定的分区固定的地址
b) 内核在根文件系统之后或者之前
c) 压缩的内核作为根文件系统下的一个文件
a的优势在与系统主要的组成部分都有各自固定的地址。启动程序可以直到内核所在的地址,而内核直到根文件系统的地址。这样启动程序加载内核或者内核挂装根文件系统的时候所进行的操作比较简单。并且我们可以很方便的升级这些组成部分。缺点就是将不可避免的造成内核和根文件系统之间Flash的浪费。
b的做法节约了一部分Flash的空间。但是它把内核同根文件系统一快编译成了一个二进制文件。这样你必须同时升级内核和根文件系统。不过这样作的好处是编译选项比较简单。容易维护。初次开发建议使用这种方法。
c的做法由于使用了压缩的核心所有节约了大量的空间。但是必须需要一个启动程序来把内核解压缩到RAM中。这样就需要一个比较充裕的RAM空间。启动程序增加了复杂度。不过一旦你写好这个驱动程序,你就可以不再修改它而将所有精力放在uClinux核心和根文件系统的开发上。
当然,根据产品需要我们不排除使用多个文件系统的选择。原因很简单,比如你需要对你的某个分区进行读/写操作而对其他一个区只要进行只读操作。由于Flash的读/写特性您就要作比较复杂的设计。对于这种情况,下文有所提及。
3,uClinux系统的bootloader
作为系统的启动程序,最先要考虑的是CPU在加电的时候运行那个地址的代码。有些CPU比如X86,ARM在加电的时候运行固定地址的代码;也有些CPU比如m68k, ColdFire,在加电的时候读取一个固定的地址,然后用这个地址的值作为最先执行代码的的地址。在现有的系统中这个地址是在Falsh里面的。
那么我们要考虑的就是在这个地址里面放入我们的代码,以便CPU加电后就执行这行代码。
我们允许CPU加电后直接运行uClinux的内核代码。这时候uClinux的代码需要作一系列的事情。比如初始化硬件,比如初始化RAM;把uClinux内核中的数据段拷贝到RAM中去;清空BSS段等。不过最重要的还是将它的首行代码放到合适的地方。
使用BootLoader我们就可以做根多的事情。比如我们可以初始化硬件,比如RAM和系统的I/O设备等。同时它还可以装载写在Flash上的不同内核,或者通过外部设备传输过一个内核并且装载运行它。
在现阶段的开发板上,很多都采用了这种方式通过串口或者网口加载Pc机上编译好的uClinux内核或者根文件系统。
除此以外,一个好的bootloader还能够保证内核影像的正确执行,防止新传输来的内核影像不完整等等。一般情况下bootloader 都是固定的烧写在Flash上面并且一般采用锁定的方法防止被擦除。 目前有很多成数的bootloader 可以在互联网上自由下载。它们支持各种开发板上的uClinux的开发。比较著名的有CoLilo, My Right Boot (MRB), PPCboot and Motorola dBUG。它们功能强大并且可以很方面的移植到你自己的开发板上。
[此贴子已经被作者于2005-12-6 14:06:49编辑过]
5,uClinux的文件系统
在uClinux下根文件系统有集中选择。 ROMfs是最常用的一种。它的特点是紧凑,只读。它把所有的文件按照一个文件的次序组合成一定的次序。并且它可以让它的应用程序直接在FLAH里面运行(XIP)。这样以来就减少了运行时对RAM尺寸的要求。在目前基于AMR和ColdFire等CPU的uClinux开发中绝大多数使用这种文件系统作为根文件系统。
Cramfs是在Linux内核2.4版本以后出现的新的文件系统,它的特点是把只读的文件系统进行压缩。从而可以在Flash上存储更多的应用程序。不过因为压缩它不能本地执行应用程序,而必须解压到RAM中运行。要求比较多的RAM。
在一些系统中需要可以读写的根文件系统。在uClinux系统中利用MTD驱动,我们可以实现一些基于Flash的日志文件系统比如JFFS 或者 JFFS2。这个文件系统的优点在于它可以避免突然断电对系统存储的影响(在标准Linux中ETX2文件系统掉电会造成数据丢失)。同时因为它们是和为Flash设计它可以保证在Flash中实现读写。如果你使用RAM disk 那么ETX2 就成为首选的文件系统。因为它是标准Linux的文件系统。所以很多操作非常方面。不过缺点是ETX2文件系统不是为嵌入式操作系统所作,所以并没有考虑存储空间的问题。由于RAM
disk的特性你在该文件系统上所作的改动下次启动后将不会再有。
当然Linux支持很多文件系统,你可以根据你的喜好随意选择。不过以上说说的是uClinux系统中最常用的。
那么我们怎么在Flash上建立一个根文件系统呢?
通常的做法是先在开发机上(通常是PC)作好这个文件系统的镜像。然后通过烧写Flash的工具直接烧写到Flash中去。也可以通过阅读一些文件系统自带的工具来进行构建。这里不一一赘述。
6,uClinux 的Flash工具
在uClinux的源码包中带有一些对Flash操作的应用程序。当你采用MTD的时候这些工具变得非常有用,它们分别是:
erase -- 擦除Flash的某些扇区
eraseall -- 擦除整个Flash
lock -- 锁住Flash(写不进去)
unlock -- 解锁
mkfs.jffs -- 建立一个目录结构的JFFS2文件系统
mkfs.jffs2 – 建立一个目录结构的JFFS2文件系统的镜像
除此之外,还有一些更为复杂的程序是和其他应用相关的。比如和JTAG相关,Net相关等等。可以根据这个工具的说明来加以应用。
[此贴子已经被作者于2005-12-6 14:09:07编辑过]
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |