9嵌入式实例 第2部分

  • 格式:doc
  • 大小:398.00 KB
  • 文档页数:21

1

9.4 软件设计

嵌入式以太网测控系统软件包括μCLinux嵌入式操作系统基本内核、硬件设备驱动程序、TCP/IP通信协议程序、用户应用程序几大部分,其基本结构如图9.19所示。用户应用程序主要是实现微型Web服务器,系统其他的软件部分包含在经裁减和修改的μCLinux操作系统内。本节将在介绍μCLinux嵌入式操作系统的基础上,对本设计应用中μCLinux的移植、引导启动程序、设备驱动程序、Web网络服务器等进行详细分析。

uCLinux嵌入式操作系统基本内核硬件设备驱动程序TCP/IP等通信协议程序Web服务器等用户应用程序API应用程序接口

图9.19 嵌入式以太网测控系统软件基本结构图

9.4.1 μCLinux嵌入式操作系统的分析

μCLinux是Linux2.0/2.4内核派生的一种针对嵌入式微控制领域设计的操作系统,它适用于没有内存管理单元MMU的处理器,解决在狭小内存或FlashROM空间中实现操作系统应用的普遍问题。μCLinux很好地保留和继承了标准Linux大部分优点,具备优异的稳定性、良好的移植性、丰富的API接口程序、优秀的网络性能和完备的文件系统支持。同时,μCLinux还具备代码紧凑、内核精简、高度优化、工具完备和支持无MMU单元处理器等独有特色,已经被移植到Dragon Ball、ColdFire、Power PC、ARM7TDMI等常见处理器器件,成功使用于各种嵌入式应用场合。

μCLinux内核源文件采用树型目录结构组织,其根目录主要含以下子目录:

/bin 存放用户最常用的基本程序

/config 存放μCLinux的结构文件

/images 存放编译后生成的文件

/lib 存放各类库

/linux-2.0.x 存放linux-2.0.x版本的内核源文件

/linux-2.4.x 存放linux-2.4.x版本的内核源文件

/tools 存放工具说明文档和其他杂项

/uClibc 存放μCLinux的库文件

/user 存放用户的各种应用程序

/vendors 存放有关各种处理器的文件

其中,在/linux-2.4.x的最上层包含下面的基本模块:

/arch 包括所有和处理器体系有关的核心代码,其中ARMNOMMU/下是关于ARM7TDMI的内核。

/drivers 放置系统所有的设备驱动程序,每种驱动程序又各占用一个子目录,如/block目录

2

下是块设备驱动程序,其genhd.c中的device_setup()包含初始化文件系统设备的代码。

/fs 包含所有的文件系统代码和各种类型的文件操作代码,它的每一个子目录支持一个文件系统,例如fat和ext2。

/include 包括编译核心所需的大部分头文件。与处理器平台无关的头文件在include/Linux子目录下,与ARM7TDMI CPU相关的头文件在include/asm-armnommu子目录下。

/init 包括核心的内核启动代码,包含初始化代码文件main.c和Version.c。

/ipc 包含核心的进程间通信代码,/lib放置核心库代码。

/Kernel 主要的核心代码,包含如sched.c大多数实现μCLinux系统内核函数的文件。和体系结构相关的代码在arch/*/kernel中。

/Mm 包括所有独立于微处理器体系结构的内存管理代码,与体系结构相关的代码则位于arch/*/mm/,如arch/armnommu/mm/Fault.c。

/net 包含与网络相关的核心代码。

9.4.2 μCLinux系统的移植

操作系统的移植是软件平台实现的难点和关键,它与硬件系统结构、处理器体系密切相关,开发者需要根据硬件的差异需要作出不同的更改处理,以实现嵌入式系统正确运行的目的。

μCLinux在一些目录包含了与系统移植相关的文件:μCLinux的目录下的arch目录包含所有μCLinux目前所支持的体系结构的代码,在此体系结构目录下又包含四个主要子目录:kernel包含此特殊结构的内核代码、mm包含特殊结构的内存管理代码、lib包含库文件代码、目标平台目录包含和平台相关的代码。对于内核、内存管理和库文件已有类似的体系结构被支持,无需作大量改动,而平台目录下的文件就需要自己建立。

针对本设计所用的硬件平台,下面对μCLinux的移植中各重点部分作具体分析。

1.交叉编译移植开发环境的构建

将源文件转换成可执行代码需要经过编译、连接和重定位3个步骤,在嵌入式开发搭建交叉编译环境是指在宿主机中构造编译器、链接器和定址器,模拟出符合目标机体系结构的开发环境,生成目标机平台上可执行的目标代码并下载到目标机运行。

建立μCLinux交叉编译移植开发环境主要通过使用GNU开发套件实现,具体过程包括:

(1)因为Linux具备安装μCLinux交叉编译工具时所需要的驱动程序文件库(如控制台终端、基本串行设备和包含根文件系统的块设备)以方便应用,所以第一步先在宿主机上安装Redhat7.3版本的Linux操作系统。

(2)下载和安装GNU工具包等安装文件,主要包括μCLinux-Samsung-20020318.tar.gz操作系统源代码文件、arm-elf-gcc-2.95.3-2.i386.rpm编译器文件、arm-elf-gdb-5.0-Li386.rpm调试器文件、arm-elf-binutils-2.11-5.i3 86.rpm二进制应用文件工具(包含反汇编,反编译、链接器工具)、genromfs-0.5.1-1.i386.rpm romfs文件生成工具。

GNU工具包必须安装在Linux的/usr/local/gnu目录下,需要以boot身份登陆Linux操作系统,将/usr/local/gnu/bin添加到系统的查找路径。

(3)下载μCLinux的应用程序库,使用交叉编译工具重新编译uClibc和uClibm源码,生成libc应用程序库和libm数学库。

(4)最后下载和解压缩μCLinux内核,生成μCLinux-Samsung目录,目录下具体的内容如上文6.4.1所述。

3

2.μCLinux内核及文件系统的配置和编译

在生成的μCLinux-Samsung目录下运行make menuconfig,将分三步进行μCLinux内核和文件系统的配置编译。make menuconfig首先是选择平台、内核代码版本、应用程序函数库,并决定是否进行内核编译参数配置和应用程序的选择,然后是配置内核编译参数,最后则是进行应用程序的选择,选择需要编译入最终image文件的程序。

μCLinux的配置和标准Linux的配置相似,而要优化内核及文件系统的配置则要求定制编译的内核运行更快(代码更小)、系统拥有内存更多以及尽量减少功能模块数目。针对本文设计的硬件平台,内核加载的主要模块是网络功能、控制平台功能、串口功能和文件系统(其余不必要模块将作删除),而与标准Linux配置的区别主要在于必须预先制定系统存储空间,并针对硬件平台修改、添加必要的参数和文件。

μCLinux编译过程会根据Makefile指示的顺序编译所需要的文件,然后使用二进制转化工具把elf格式的文件化为linux.bin二进制文件,最后将在μCLinux-Samsung的images子目录下生成两个文件image.rom和image.ram。其中image.rom是用于烧录到FlashROM的压缩内核,使用该文件代码从FlashROM处启动,将把image解压缩到SDRAM的0x8000运行。image.ram是直接下载到SDRAM运行的包含调试信息的内核,使用ICE可把image.ram放到SDRAM地址为0x8000的地方进行开发调试,该方式使开发调试更为便捷易行。

以上是μCLinux操作系统移植的基本过程,而关于设备驱动程序、用户应用程序和系统启动代码Boot

Loader的具体实现将在下面详细分析。

3.引导程序的构建及启动

完整的操作系统包含Boot Loader引导程序、内核和init守护进程3个必不可少的基本组成部分。Boot Loader是在内核运行前启动的一段小型代码,它的作用是初始化硬件设备、建立内存空间的映射关系,将系统的软硬件环境引入正确的状态,为下一步执行start_kernel程序调用内核做好准备。

根据引导程序对微处理器硬件结构的依赖情况,Boot Loader分为两部分。一部分是与微处理器相关的代码(如设备初始化代码),此处代码使用高效短小的汇编语言编写。另一部分是与微处理器无关的代码,此处代码采用具有更好可读性和可移植性的C语言编写,实现复杂的功能。

μCLinux操作系统的启动前后分为三个阶段。第一阶段先是完成S3C4510B及存储器件的硬件初始化,在系统RAM中建立程序堆栈和数据段,建立程序运行环境。在Boot Loader执行完毕后,程序转入0x08000地址开始执行bzImage文件,执行arch\armnommu\boot\compressed\head.S,把操作系统内核解压到0X0C300000开始的RAM地址,接着从head_armv.S开始执行call_kernel,保存与系统相关的信息,然后执行内核start_kernel程序。

在接着的第二阶段中,μCLinux内核取得S3C4510B的控制权,开始执行建立RAM中断矢量表、加载设备驱动程序、加载内存管理模块等操作,完成操作系统自身的初始化。内核程序start_kernel在第一步调用setup_arch,完成与微处理器体系结构相关的设置,具体包括硬件寄存器初始化、根设备标识、系统中可用的DRAM标识、FlashROM数量的标识、系统中可用页面数目的指定、文件系统大小的指定。所有这些信息都以参数形式从引导装载程序传递到内核。完成与微处理器体系结构相关的设置后,程序就返回到初始化系统其余部分的start_kernel函数,继续初始化的 其他任务。

在最后的第三阶段,μCLinux创建kernel thread启动一个最初的init守护线程,根据配置文件加载文件系统,配置网络、服务进程、终端等。如果在/bin、/sbin或/etc中没有init程序,那么内核将执行文件系统的/bin中的shell,此时内核己经正常运行,外围模块也都准备就绪。