星期日, 三月 11, 2007

嵌入式设备上的 Linux 系统开发(2)(zt)

嵌入式设备的文件系统

系统需要一种以结构化格式存储和检索信息的方法;这就需要文件系统的参与。Ramdisk(请参阅参考资料)是通过将计算机的 RAM 用作设备来创建和挂装文件系统的一种机制,它通常用于无盘系统(当然包括微型嵌入式设备,它只包含作为永久存储媒质的闪存芯片)。

用户可以根据可靠性、健壮性和/或增强的功能的需求来选择文件系统的类型。下一节将讨论几个可用选项及其优缺点。

第二版扩展文件系统(Ext2fs)
Ext2fs 是 Linux 事实上的标准文件系统,它已经取代了它的前任 — 扩展文件系统(或 Extfs)。Extfs 支持的文件大小最大为 2 GB,支持的最大文件名称大小为 255 个字符 — 而且它不支持索引节点(包括数据修改时间标记)。Ext2fs 做得更好;它的优点是:

  • Ext2fs 支持达 4 TB 的内存。
  • Ext2fs 文件名称最长可以到 1012 个字符。
  • 当创建文件系统时,管理员可以选择逻辑块的大小(通常大小可选择 10242048 4096 字节)。
  • Ext2fs 了实现快速符号链接:不需要为此目的而分配数据块,并且将目标名称直接存储在索引节点(inode)表中。这使性能有所提高,特别是在速度上。

因为 Ext2 文件系统的稳定性、可靠性和健壮性,所以几乎在所有基于 Linux 的系统(包括台式机、服务器和工作站 — 并且甚至一些嵌入式设备)上都使用 Ext2 文件系统。然而,当在嵌入式设备中使用 Ext2fs 时,它有一些缺点

  • Ext2fs 是为象 IDE 设备那样的块设备设计的,这些设备的逻辑块大小是 512 字节,1 K 字节等这样的倍数。这不太适合于扇区大小因设备不同而不同的闪存设备。
  • Ext2 文件系统没有提供对基于扇区的擦除/写操作的良好管理。在 Ext2fs 中,为了在一个扇区中擦除单个字节,必须将整个扇区复制到 RAM,然后擦除,然后重写入。考虑到闪存设备具有有限的擦除寿命(大约能进行 100,000 次擦除),在此之后就不能使用它们,所以这不是一个特别好的方法。
  • 在出现电源故障时,Ext2fs 不是防崩溃的。
  • Ext2 文件系统不支持损耗平衡,因此缩短了扇区/闪存的寿命。(损耗平衡确保将地址范围的不同区域轮流用于写和/或擦除操作以延长闪存设备的寿命。)
  • Ext2fs 没有特别完美的扇区管理,这使设计块驱动程序十分困难。

由于这些原因,通常相对于 Ext2fs,在嵌入式环境中使用 MTD/JFFS2 组合是更好的选择。

用 Ramdisk 挂装 Ext2fs
通过使用 Ramdisk 的概念,可以在嵌入式设备中创建并挂装 Ext2 文件系统(以及用于这一目的的任何文件系统)。

清单 6. 创建一个简单的基于 Ext2fs Ramdisk

mke2fs -vm0 /dev/ram 4096

mount -t ext2 /dev/ram /mnt
cd /mnt
cp /bin, /sbin, /etc, /dev ... files in mnt
cd ../
umount /mnt
dd if=/dev/ram bs=1k count=4096 of=ext2ramdisk

mke2fs 是用于在任何设备上创建 ext2 文件系统的实用程序 — 它创建超级块、索引节点以及索引节点表等等。

在 上面的用法中,/dev/ram 是上面构建有 4096 个块的 ext2 文件系统的设备。然后,将这个设备(/dev/ram)挂装在名为 /mnt 的临时目录上并且复制所有必需的文件。一旦复制完这些文件,就卸装这个文件系统并且设备(/dev/ram)的内容被转储到一个文件 (ext2ramdisk)中,它就是所需的 Ramdisk(Ext2 文件系统)。

上面的顺序创建了一个 4 MB 的 Ramdisk,并用必需的文件实用程序来填充它。

一些要包含在 Ramdisk 中的重要目录是:

  • /bin保存大多数象 initbusyboxshell、文件管理实用程序等二进制文件。
  • /dev包含用在设备中的所有设备节点
  • /etc包含系统的所有配置文件
  • /lib包含所有必需的库,如 libclibdl

日志闪存文件系统,版本 2(JFFS2)
瑞 典的 Axis Communications 开发了最初的 JFFS,Red Hat 的 David Woodhouse 对它进行了改进。第二个版本,JFFS2,作为用于微型嵌入式设备的原始闪存芯片的实际文件系统而出现。JFFS2 文件系统是日志结构化的,这意味着它基本上是一长列节点。每个节点包含有关文件的部分信息 — 可能是文件的名称、也许是一些数据。相对于 Ext2fs,JFFS2 因为有以下这些优点而在无盘嵌入式设备中越来越受欢迎:

  • JFFS2 在扇区级别上执行闪存擦除/写/读操作要比 Ext2 文件系统好。
  • JFFS2 提供了比 Ext2fs 更好的崩溃/掉电安全保护。当需要更改少量数据时,Ext2 文件系统将整个扇区复制到内存(DRAM)中,在内存中合并新数据,并写回整个扇区。这意味着为了更改单个字,必须对整个扇区(64 KB)执行读/擦除/写例程这样做的效率非常低。要是运气差,当正在 DRAM 中合并数据时,发生了电源故障或其它事故,那么将丢失整个数据集合,因为在将数据读入 DRAM 后就擦除了闪存扇区。JFFS2 附加文件而不是重写整个扇区,并且具有崩溃/掉电安全保护这一功能。
  • 这可能是最重要的一点:JFFS2 是专门为象闪存芯片那样的嵌入式设备创建的,所以它的整个设计提供了更好的闪存管理。

因为本文主要是写关于闪存设备的使用,所以在嵌入式环境中使用 JFFS2 的缺点很少:

当文件系统已满或接近满时,JFFS2 会大大放慢运行速度。这是因为垃圾收集的问题(更多信息,请参阅参考资料)。

创建 JFFS2 文件系统
在 Linux 下,用 mkfs.jffs2 命令创建 JFFS2 文件系统(基本上是使用 JFFS2 的 Ramdisk)。

清单 7. 创建 JFFS2 文件系统

mkdir jffsfile

cd jffsfile
/* copy all the /bin, /etc, /usr/bin, /sbin/ binaries and /dev entries
that are needed for the filesystem here */
/* Type the following command under jffsfile directory to create the JFFS2 Image */
./mkfs.jffs2 -e 0x40000 -p -o ../jffs.image


上 面显示了 mkfs.jffs2 的典型用法。-e 选项确定闪存的擦除扇区大小(通常是 64 千字节)。-p 选项用来在映像的剩余空间用零填充。-o 选项用于输出文件,通常是 JFFS2 文件系统映像 — 在本例中是 jffs.image。一旦创建了 JFFS2 文件系统,它就被装入闪存中适当的位置(引导装载程序告知内核查找文件系统的地址)以便内核能挂装它。

tmpfs
当 Linux 运行于嵌入式设备上时,该设备就成为功能齐全的单元,许多守护进程会在后台运行并生成许多日志消息。另外,所有内核日志记录机制,象 syslogd、dmesg 和 klogd,会在 /var 和 /tmp 目录下生成许多消息。由于这些进程产生了大量数据,所以允许将所有这些写操作都发生在闪存是不可取的。由于在重新引导时这些消息不需要持久存储,所以这个 问题的解决方案是使用 tmpfs。

tmpfs 是基于内存的文件系统,它主要用于减少对系统的不必要的闪存写操作这一唯一目的。因为 tmpfs 驻留在 RAM 中,所以写/读/擦除的操作发生在 RAM 中而不是在闪存中。因此,日志消息写入 RAM 而不是闪存中,在重新引导时不会保留它们。tmpfs 还使用磁盘交换空间来存储,并且当为存储文件而请求页面时,使用虚拟内存(VM)子系统。

tmpfs 的优点包括:

  • 动态文件系统大小文件系统大小可以根据被复制、创建或删除的文件或目录的数量来缩放。使得能够最理想地使用内存。

速度 — 因为 tmpfs 驻留在 RAM,所以读和写几乎都是瞬时的。即使以交换的形式存储文件,I/O 操作的速度仍非常快。

tmpfs 的一个缺点是当系统重新引导时会丢失所有数据。因此,重要的数据不能存储在 tmpfs 上。

挂装 tmpfs
诸如 Ext2fs 和 JFFS2 等大多数其它文件系统都驻留在底层块设备之上,而 tmpfs 与它们不同,它直接位于 VM 上。因而,挂装 tmpfs 文件系统是很简单的事:

清单 8. 挂装 tmpfs

/* Entries in /etc/rc.d/rc.sysinit for creating/using tmpfs */

# mount -t tmpfs tmpfs /var -o size=512k
# mkdir -p /var/tmp
# mkdir -p /var/log
# ln -s /var/tmp /tmp

上面的命令将在 /var 上创建 tmpfs 并将 tmpfs 的最大大小限制为 512 K。同时,tmp/ 和 log/ 目录成为 tmpfs 的一部分以便在 RAM 中存储日志消息。

如果您想将 tmpfs 的一个项添加到 /etc/fstab,那么它可能看起来象这样:

tmpfs /var tmpfs size=32m 0 0

这将在 /var 上挂装一个新的 tmpfs 文件系统。

图形用户界面(GUI)选项
从 用户的观点来看,图形用户界面(GUI)是系统的一个最至关重要的方面:用户通过 GUI 与系统进行交互。所以 GUI 应该易于使用并且非常可靠。但它还需要是有内存意识的,以便在内存受限的、微型嵌入式设备上可以无缝执行。所以,它应该是轻量级的,并且能够快速装入。

另一个要考虑的重要方面涉及许可证问题。一些 GUI 分发版具有允许免费使用的许可证,甚至在一些商业产品中也是如此。另一些许可证要求如果想将 GUI 合并入项目中则要支付版税。

最 后,大多数开发人员可能会选择 XFree86,因为 XFree86 为他们提供了一个能使用他们喜欢的工具的熟悉环境。但是市场上较新的 GUI,象 Century Software 的 Microwindows(Nano-X)和 Trolltech 的 QT/Embedded,与 X 在嵌入式 Linux 的竞技舞台中展开了激烈竞争,这主要是因为它们占用很少的资源、执行的速度很快并且具有定制窗口构件的支持。

让我们看一看这些选项中的每一个。

Xfree86 4.X(带帧缓冲区支持的 X11R6.4)
XFree86 Project, Inc. 是一家生产 XFree86 的公司,该产品是一个可以免费重复分发、开放源码的 X Window 系统。X Window 系统(X11)为应用程序以图形方式进行显示提供了资源,并且它是 UNIX 和类 UNIX 的机器上最常用的窗口系统。它很小但很有效,它运行在为数众多的硬件上,它对网络透明并且有良好的文档说明。X11 为窗口管理、事件处理、同步和客户机间通信提供强大的功能 并且大多数开发人员已经熟悉了它的 API。它具有对内核帧缓冲区的内置支持,并占用非常少的资源 这非常有助于内存相对较少的设备。X 服务器支持 VGA 和非 VGA 图形卡,它对颜色深度 1、2、4、8、16 和 32 提供支持,并对渲染提供内置支持。最新的发行版是 XFree86 4.1.0。

它的优点包括:

  • 帧缓冲区体系结构的使用提高了性能。
  • 占用的资源相对很小大小在 600 K 700 K 字节的范围内,这使它很容易在小型设备上运行。
  • 非常好的支持:在线有许多文档可用,还有许多专用于 XFree86 开发的邮递列表。
  • X API 非常适合扩展。

它的缺点包括:

  • 比最近出现的嵌入式 GUI 工具性能差。
  • 此外,当与 GUI 中最新的开发象专门为嵌入式环境设计的 Nano-X QT/Embedded — 相比时,XFree86 似乎需要更多的内存。

Microwindows
Microwindows 是 Century Software 的开放源代码项目,设计用于带小型显示单元的微型设备。它有许多针对现代图形视窗环境的功能部件。象 X 一样,有多种平台支持 Microwindows。

Microwindows 体系结构是基于客户机/服务器的并且具有分层设计。最底层是屏幕和输入设备驱动程序(关于键盘或鼠标)来与实际硬件交互。在中间层,可移植的图形引擎提供对线的绘制、区域的填充、多边形、裁剪以及颜色模型的支持。

在 最上层,Microwindows 支持两种 API:Win32/WinCE API 实现,称为 Microwindows;另一种 API 与 GDK 非常相似,它称为 Nano-X。Nano-X 用在 Linux 上。它是象 X 的 API,用于占用资源少的应用程序。

Microwindows 支持 1、2、4 和 8 bpp(每像素的位数)的 palletized 显示,以及 8、16、24 和 32 bpp 的真彩色显示。Microwindows 还支持使它速度更快的帧缓冲区。Nano-X 服务器占用的资源大约在 100 K 到 150 K 字节。

原始 Nano-X 应用程序的平均大小在 30 K 到 60 K。由于 Nano-X 是为有内存限制的低端设备设计的,所以它不象 X 那样支持很多函数,因此它实际上不能作为微型 X(Xfree86 4.1)的替代品。

可以在 Microwindows 上运行 FLNX,它是针对 Nano-X 而不是 X 进行修改的 FLTK(快速轻巧工具箱(Fast Light Toolkit))应用程序开发环境的一个版本。本文中描述 FLTK。

Nano-X 的优点包括:

  • Xlib 实现不同,Nano-X 仍在每个客户机上同步运行,这意味着一旦发送了客户机请求包,服务器在为另一个客户机提供服务之前一直等待,直到整个包都到达为止。这使服务器代码非常简单,而运行的速度仍非常快。
  • 占用很小的资源

Nano-X 的缺点包括:

  • 联网功能部件至今没有经过适当地调整(特别是网络透明性)。
  • 还没有太多现成的应用程序可用。
  • X 相比,Nano-X 虽然近来正在加速开发,但仍没有那么多文档说明而且没有很好的支持,但这种情形会有所改变。

Microwindows 上的 FLTK API
FLTK 是一个简单但灵活的 GUI 工具箱,它在 Linux 世界中赢得越来越多的关注,它特别适用于占用资源很少的环境。它提供了您期望从 GUI 工具箱中获得的大多数窗口构件,如按钮、对话框、文本框以及出色的"赋值器"选择(用于输入数值的窗口构件)。还包括滑动器、滚动条、刻度盘和其它一些构件。

针 对 Microwindows GUI 引擎的 FLTK 的 Linux 版本被称为 FLNX。FLNX 由两个组件构成:Fl_Widget 和 FLUID。Fl_Widget 由所有基本窗口构件 API 组成。FLUID(快速轻巧的用户界面设计器(Fast Light User Interface Designer, FLUID))是用来产生 FLTK 源代码的图形编辑器。总的来说,FLNX 是能用来为嵌入式环境创建应用程序的一个出色的 UI 构建器。

Fl_Widget 占用的资源大约是 40 K 到 48 K,而 FLUID(包括了每个窗口构件)大约占用 380 K。这些非常小的资源占用率使 Fl_Widget 和 FLUID 在嵌入式开发世界中非常受欢迎。

优点包括:

  • 习惯于在象 Windows 这样已建立得较好的环境中开发基于 GUI 的应用程序的任何人都会非常容易地适应 FLTK 环境。
  • 它的文档包括一本十分完整且编写良好的手册。
  • 它使用 LGPL 进行分发,所以开发人员可以灵活地发放他们应用程序的许可证。
  • FLTK 是一个 C++ 库(Perl Python 绑定也可用)。面向对象模型的选择是一个好的选择,因为大多数现代 GUI 环境都是面向对象的;这也使将编写的应用程序移植到类似的 API 中变得更容易。
  • Century Software 的环境提供了几个有用的工具,诸如 ScreenToP ViewML 浏览器。

它的缺点是:

  • 普通的 FLTK 可以与 X Windows API 一同工作,而 FLNX 不能。它与 X 的不兼容性阻碍了它在许多项目中的使用。

Qt/Embedded
Qt/Embedded 是 Trolltech 新开发的用于嵌入式 Linux 的图形用户界面系统。Trolltech 最初创建 Qt 作为跨平台的开发工具用于 Linux 台式机。它支持各种有 UNIX 特点的系统以及 Microsoft Windows。KDE 最流行的 Linux 桌面环境之一,就是用 Qt 编写的。

Qt/Embedded 以原始 Qt 为基础,并做了许多出色的调整以适用于嵌入式环境。Qt Embedded 通过 Qt API 与 Linux I/O 设施直接交互。那些熟悉并已适应了面向对象编程的人员将发现它是一个理想环境。而且,面向对象的体系结构使代码结构化、可重用并且运行快速。与其它 GUI 相比,Qt GUI 非常快,并且它没有分层,这使得 Qt/Embedded 成为用于运行基于 Qt 的程序的最紧凑环境。

Trolltech 还推出了 Qt 掌上机环境(Qt Palmtop Environment,俗称 Qpe)。Qpe 提供了一个基本桌面窗口,并且该环境为开发提供了一个易于使用的界面。Qpe 包含全套的个人信息管理(Personal Information Management (PIM))应用程序、因特网客户机、实用程序等等。然而,为了将 Qt/Embedded 或 Qpe 集成到一个产品中,需要从 Trolltech 获得商业许可证。(原始 Qt 自版本 2.2 以后就可以根据 GPL 获得 。)

它的优点包括:

  • 面向对象的体系结构有助于更快地执行
  • 占用很少的资源,大约 800 K
  • 抗锯齿文本和混合视频的象素映射

它的缺点是:

  • Qt/Embedded Qpe 只能在获得商业许可证的情况下才能使用。

结束语
嵌 入式 Linux 开发正迅速地发展着。您必须学习并从引导装载程序和分发版到文件系统和 GUI 中的每一个事物的各种选项中作出选择。但是要感谢有这种选择自由度以及非常活跃的 Linux 社区,Linux 上的嵌入式开发已经达到了新的境界,并且调整模块以适合您的规范从未比现在更简单。这已经导致出现了许多时新的手持和微型设备作为开放盒,这是件好事 因为事实是您不必成为一个专家从这些模块中进行选择来调整您的设备以满足您自己的要求和需要。

我们希望这篇对嵌入式 Linux 领域的介绍性概述能激起您进行试验的欲望,并且希望您将体会摆弄微型设备的乐趣以满足您的爱好。为进一步有助于您的项目,请参阅下面的"参考资料",链接到有关我们这里已经概述的技术的更深入的信息。

参考资料

· 引导

· 小型分发版

· 工具链

  • Wiki 工具链页面包含到本文提到的所有三个工具链的链接,还有对它们的评论。

· 设备驱动程序

· 有用的工具

  • 请查看 LART 上的 Jflash-linux
  • BinutilsGCC Glibc 都可从 Free Software Foundation 下载获得。
  • 许多有用的下载都可从 Netwinder.org 获得,这是一个致力于 NetWinder 平台上开发工作的志愿者站点。
  • 请在 Mark Nielsen 写得非常棒的 How to use a Ramdisk for Linux 一文中阅读有关 Ramdisk 的所有信息。
  • FLNX 是以 FLTK(快速轻巧的工具箱)为基础的。

· 文件系统

· GUI

· 一般参考资料

关于作者
Anand K Santhanam 在印度 Madras 大学获得计算机科学工学学士学位。自 1999 7 月以来他一直在印度为 IBM Global Services(软件实验室)工作。他是 IBM Linux 小组的成员,这个小组主要致力于嵌入式系统中的 ARM-Linux、设备驱动程序和电源管理的研究和开发。他感兴趣的其它领域是 O/S 本质和联网。可以通过 asanthan@in.ibm.com 与他联系。


Vishal Kulkarni 从印度 Maharashtra 的 Shivaji 大学获得电子工程的学士学位。自 1999 年 3 月以来他一直在印度为 IBM Global Services(软件实验室)工作。在此之前,他曾在美国 IBM Austin 工作了一年半多。他是 IBM Linux 小组的成员,这个小组主要致力于嵌入式设备上的 ARM-Linux、设备驱动程序和 GUI。他感兴趣的其它领域是 O/S 本质和联网。可以通过 kvishal@in.ibm.com 与他联系。

没有评论: