Linux操作系统核心最早是由芬兰的Linus Torvalds 于1991年8月在芬兰赫尔辛基大学上学时发布的,后来经过众多世界顶尖的软件工程师的不断修改和完善,Linux得以在全球普及开来,在服务器领域及个人桌面系统得到越来越多的应用。近年来随着嵌入式系统的普及,Linux操作系统的装机量呈爆炸式增长,目前已经成为全球第二大操作系统。
随着后PC时代的到临,嵌入式操作系统的应用得到空前发展,成为新一轮的热点。目前市场上商用的操作系统有VxWorks、pSOS、Windows CE、LynxOS、QNX、Nucleus、嵌入式Linux等,其中嵌入式Linux正在兴起,越来越引起人们的注意,已经成为全球第二大操作系统。Linux系统的组成结构主要包括进程管理、内存管理、文件系统、设备驱动程序和系统调用等部分。Linux本质上是分时系统,在2.6版本之前,其进程调度是不可抢占的,也就是说高优先级进程并不能中断低优先级进程的运行,而是采用轮转法来调度,每个进程分配一个“时间片”,时间用完后轮转到下个进程。但是在开始新的一轮调度的时候,高优先级的进程会被优先执行,这就是Linux实时性能较差的本质原因。2.6版本的Linux系统在任务调度方面做了重大改进,开始支持抢占式任务调度,实时性有所提高。
标准的Linux版本是为x86系列处理器配置的,并不适合大多数的嵌入式应用。用户需要重新剪裁和配置内核以适应自己的处理器和存储器的大小。目前标准内核中已包括x86、ARM、MIPS、PowerPC、Blackfin等系列处理器的代码支持,因此用户可以从标准Linux版本开始剪裁,也可以从网络上获得一些别人已剪裁过的版本,然后再在此基础上进行剪裁和配置。基于嵌入式处理器的Linux移植主要包括四个层次的工作:CPU级移植、处理器级移植、处理器外设移植和板级移植。CPU部分一般是底层进程调度及时钟中断程序的移植以及建立交叉编译工具toolchain等,主要由汇编语言编写,对于Blackfin内核这部分已经包含在Linux发布的内核中。处理器级的移植主要是编写bootloader程序,修改处理器相关文件等。处理器外设移植和板级移植主要是指处理器外设驱动程序及电路板上其他外部设备驱动程序的编写。
嵌入式Linux系统之所以在嵌入式操作系统中脱颖而出,以下几个因素是很关键的:
•Linux系统遵循GPL协议,是没有版权费用的操作系统;
•Linux支持众多的处理器,如x86、PowerPC、MIPS、ARM、Blackfin等,均在支持之中;
•Linux最初用于服务器和桌面系统,稳定性已经得到验证,特别是网络协议栈,更是性能出色;
•全球范围内的Linux社区有众多的免费技术资料,工程师之间的交流非常密切。
嵌入式µClinux是Linux操作系统的一个版本,是在标准Linux版本基础上演变而来的,µClinux的含义是“micro-control-linux”,顾名思义,是专门为小型的微控制类处理器开发的Linux系统。Linux与µClinux系统最大的区别在于Linux是支持内存管理单元(Memory Management Unit,MMU)的,而µClinux是为没有MMU或者没有完整MMU的处理器而开发的。在Linux环境下,每个进程使用的是虚拟地址,可以任意使用而不用担心是否有足够的物理内存。例如硬件电路只有64 MB的物理内存,但是在应用程序中可以使用任意地址空间的地址,好像没有硬件限制一样。这中间其实是MMU在起作用,MMU负责把虚拟地址转换为物理地址。在用户空间看到的地址都是虚拟地址,无法直接操作硬件寄存器。在内核空间只能对物理地址映射后的虚拟地址进行操作。没有MMU的处理器无法支持虚拟地址和物理地址的转换,因此无法适应标准的Linux操作系统,µClinux的出现正是为了解决这一问题,除此之外µClinux与Linux并无本质不同。
嵌入式系统的软件开发包括四部分:Bootloader、内核、驱动程序和应用程序。驱动程序在结构上属于内核的一部分,但是由于内核功能越来越强,支持的外设驱动程序越来越多,导致内核的体积日益增大,不利于维护和开发。因此内核对驱动程序的管理出现了新的变化,即支持动态加载驱动程序。驱动程序被编译为模块,在需要的时候动态加载到内核中,如果不使用了还可以动态卸载,大大方便了外设驱动的开发和维护。驱动程序模块的编译虽然需要依赖µClinux内核,但是在物理位置上二者可以独立存在。从这个意义来说,动态加载的驱动程序的开发和内核之间又是相互独立,故单独列出。
嵌入式处理器通常在内存、外存、主频、接口等方面和x86处理器有较大区别,由于本身资源有限,嵌入式处理器无法承载庞大的开发环境,只能在主机环境下开发完成后才能下载到嵌入式处理器上运行。嵌入式系统的开发需要建立交叉编译(CrossingCompile)环境,交叉编译是相对本机编译(Native Compile)而言的,指在异种CPU上进行的编译。例如在x86机器上编译运行于DSP处理器上的程序就是交叉编译。与PC机开发软件一样,嵌入式系统软件开发同样需要开发工具,包括编辑器、编译器、链接器、调试器和运行支撑库。Linux环境下使用GNU工具完成编译、链接、调试等过程,包括编译器GCC、运行库Glibc和实用工具Binutils。
初次接触嵌入式系统开发的工程师通常会对交叉编译环境感到很神秘,而且手足无措,不知从何处下手进行开发。其实嵌入式系统的开发很简单,概括来讲包括两个环境的搭建,即PC环境的搭建和目标板环境的搭建。PC环境包括主机Linux系统以及交叉编译工具,就是一组用于程序编写、编译和调试的软件工具,Linux系统使用GNU工具包作为软件开发的工具。程序开发完毕后需要下载到目标板执行,目标板环境包括电路板、与PC的连接线缆和板上的支撑软件。嵌入式开发板上运行的软件包括Bootloader程序、µClinux操作系统以及用户程序。通常Bootloader是最早被执行的程序。针对裸板的开发,即板上并无基本的Bootloader程序的情况,用户要首先通过仿真器、编程器或者利用处理器内部的引导程序把Bootloader程序加载或者烧写到Flash中,一旦Bootloader正确运行后,开发者就可以在Bootloader环境中与PC交互。
在这里给出嵌入式开发的基本组成结构,如图3.1所示,用来说明交叉编译开发环境的组成。
图3.1 交叉开发环境的组成
交叉开发环境由PC、目标板、PC与目标板之间的连接线以及PC上的软件环境组成。嵌入式系统与PC之间的连接包括RS-232串口、USB、以太网接口,其中串口对于嵌入式系统的调试来说是非常重要的,特别是系统启动初期,在网络和USB等驱动程序还没有加载的时候,需要依靠串口输出调试信息。因此在开发嵌入式系统的时候要尽早地打通串口。
PC端需要的软件环境包括:
•Linux桌面系统;
•处理器对应的GNU工具包;
•串口终端;
•网络工具软件。
目标板端需要的软硬件环境:
•嵌入式µClinux发行包(在PC端编译);
•Bootloader;
•串口;
•以太网接口;
•仿真器。