嵌入式操作系统—构建嵌入式Linux系统李春杰参考书:BuildingEmbeddedLinuxSystemsByKarimYaghmour,Publisher:O'Reilly,April2003主要内容一、嵌入式Linux开发综述二、Linux的配置和编译一、嵌入式Linux开发综述1.建立目标板Linux的基本步骤2.开发嵌入式Linux系统最常用的主机类型3.主机/目标机的开发体系结构4.主机/目标板的调试方式5.嵌入式Linux系统的一般架构6.嵌入式Linux系统的启动过程7.嵌入式Linux系统的引导配置的类型1、建立目标板Linux的基本步骤建立目标板Linux系统有4个重要的步骤:(1)决定系统组件Linux具有大量可选软件,应当为目标系统列出必须的功能清单(2)配置并建立内核选择合适的Linux内核版本与适当的配置建立内核(3)建立根文件系统(4)设置引导软件与配置2、开发嵌入式Linux系统最常用的主机类型开发嵌入式Linux系统最常用的主机类型(1)Linux工作站通常就是一台安装了某个标准的Linux发行套件的PC机,如Debian、Mandrake、RedHat等。需约2、3G或更多的磁盘空间进行嵌入式Linux开发建议具有128或以上的RAM及交换空间(2)Unix工作站由于Linux与Unix非常相似,对Linux适用的通常对Unix也适用(3)Windows工作站许多开发者比较习惯Windows平台,并希望在Windows平台上开发嵌入式Linux系统Cygwin:可在Windows平台上建立跨平台开发工具链VMWare:可在虚拟环境中执行Linux,并在Linux上进行嵌入式Linux的开发3、主机/目标机的开发体系结构在嵌入式Linux系统开发中,存在3种主机/目标机开发体系结构(1)连接式(2)使用可移动存储设备(3)独立开发式(1)连接式目标板和主机通过一个物理线路(如串行线或者以太网连接)永久的连接在一起好处:目标代码的传送无需物理存储设备参与,只需要上述连接就足够了在这种方式中,主机包含了跨平台开发环境,而目标板则包含了适当的引导加载程序、可用的内核以及最起码的根文件系统*跨平台开发环境主机*引导加载程序*内核*根文件系统目标机另一种做法是,以远程组件来简化目标板的开发工作,例如通过TFTP下载内核此外,根文件系统还可以通过NFS安装,而不必在目标板中使用存储介质还可以使用连接进行调试通常使用以太网连接进行下载功能,而使用RS232串口连接进行调试*跨平台开发环境*内核*根文件系统主机*引导加载程序目标机下载/NFS(2)使用可移动存储设备主机和目标板之间没有实际的连接。先由主机将数据写入存储设备,然后将存储设备转接到目标板,并使用该存储设备引导目标板同样的,在主机上包含了跨平台开发环境。而目标板则只包含了最起码的引导加载程序。其余的组件被存放在可移动存储设备上。*跨平台开发环境主机*引导加载程序目标机*第二个引导加载程序*内核*根文件系统一种通常的操作方式使用易插拔的flash芯片:先在主机上使用flash编程器将数据写入芯片,然后再将该芯片插入目标板上的插座中(3)独立开发系统在这种设置中,目标板是个独立的开发系统,它包含了引导、操作以及开发额外软件所必须的任何软件。不需要跨平台开发环境,不必在主机和目标板之间传送任何数据适合以PC为主的高级嵌入式系统的开发*引导加载程序*内核*完整的根文件系统*固有的开发环境目标机4、主机/目标板的调试方式用来连接目标板与主机进行调试的接口基本上有3种类型:(1)串行线、(2)网络接口、(3)特殊的调试硬件JTAG(1)使用串行线进行调试这是从主机对目标板进行调试的最简单的做法缺点:串行连接的速度比较有限当嵌入式系统中只有一个串行串口,或者串行连接是嵌入式系统对外唯一的接口,那么在对系统调试的同时,以终端仿真器跟系统交互有些困难。(2)使用网络接口进行调试这种方式与串行线连接相比,可以提供较高的带宽由于可以在相同的物理网络连接上使用多重网络连接,可以兼顾调试与终端仿真交互缺点:无法使用网络连接对Linux内核进行调试。因为网络协议栈本身在Linux内核里。相对而言,内核的调试通常可以通过串行连接来进行(3)使用特殊的调试硬件通常会使用BDM或JTAG接口。这些接口依靠的是CPU芯片中内嵌的BDM或JTAG特殊功能。只要将一个特殊的调试器连接到CPU上的JTAG或BDM相关管脚,就可以完全控制CPU的行为。因此,当遇到新的嵌入式目标板、或者对目标板上的Linux内核进行调试时,通常会使用JTAG和BDM5、嵌入式Linux系统的一般架构如图所示,包含4个部分:(1)硬件(2)内核(3)文件系统等(4)应用程序/库库应用程序Linux内核高层抽象底层接口层文件系统网络协议硬件(1)硬件目标板的硬件。至少32位CPU一般情况下必须配备MMU(对于不配备MMU的考虑使用uClinux)RAM容量必须满足系统的需要一些最起码的I/O能力,以便在线调试具有某种形式的永久性或网络存储设备以便内核加载及(或)存取根文件系统库应用程序Linux内核高层抽象底层接口层文件系统网络协议硬件(2)Linux内核Linux内核是Linux操作系统的中心组件。使用内核的目的是希望以一致的方式管理硬件,以及为用户软件提供高层抽象层。内核大致可以分成两个部分:底层接口层和高层抽象层库应用程序Linux内核高层抽象底层接口层文件系统网络协议硬件底层接口层专属于硬件配置,内核运行其上,并以硬件无关的高层抽象层提供对硬件资源的直接控制。比如,对于PPC和ARM系统,尽管其寄存器或内存分页的处理方式不同,但却可以使用通用的API来存取内核里高层的组件通常底层部分会处理CPU特有的操作、架构特有的内存操作以及设备的基本I/O在Linux内核的底层接口层与高层抽象层之间,内核有时会用到与特定设备上的结构化数据交互的组件,例如文件系统和网络协议。通常,Linux内核至少需要一个具有合适结构的根文件系统。Linux内核会从中加载第一个应用程序、加载模块并为进程提供工作目录。库应用程序Linux内核高层抽象底层接口层文件系统网络协议硬件(4)应用程序/库内核上面是应用程序和工具程序。链接库通常与应用程序动态链接在一起(glibc和uClibc)库应用程序Linux内核高层抽象底层接口层文件系统网络协议硬件6、系统启动过程在系统启动过程里,有3个主要软件组件参与其中:(1)引导加载程序(2)内核(3)Init进程(1)引导加载程序引导加载程序是系统启动过程中执行的第一个软件,它与目标板的硬件有高度的依赖关系。Linux有许多引导加载程序可用。引导加载程序在完成底层硬件初始化工作后会接着跳到内核的启动程序代码执行(2)内核内核一开始的启动程序代码会因架构不同而有很大的差异,而且在为C程序代码设置合适的执行环境之前,它会先为自己进行初始化工作。完成以上工作后,内核会跳到与架构无关的start_kernel函数执行,此函数会初始化高层内核功能,安装根文件系统,以及启动init进程(3)Init进程启动各种应用程序(根据相关启动脚本设置)Init进程首先进行一系列的硬件初始化,并挂载根文件系统。最后init进程会执行用户传递过来的“init=”启动参数执行用户指定的命令,或者执行以下几个进程之一,由内核态变为用户态:execve(/sbin/init,argv_init,envp_init);execve(/etc/init,argv_init,envp_init);execve(/bin/init,argv_init,envp_init);execve(/bin/sh,argv_init,envp_init)。7、引导配置的类型Linux系统的引导配置与所选用的引导加载程序、它的配置以及主机中软硬件的类型有非常密切的关系。(1)固态存储媒体(2)磁盘(3)网络(1)固态存储媒体固态存储媒体用于存放最初的引导加载程序配置参数内核根文件系统嵌入式Linux系统在开发的不同阶段可能会使用不同的引导配置,但大部分在开发完成后使用固态存储媒体(2)磁盘磁盘引导配置方式广泛应用于工作站及服务器中,此时内核和根文件系统位于磁盘上最初的内核加载程序不是从磁盘上加载,第二个内核加载程序就是直接从磁盘获得内核本身,然后在磁盘上有一个被用作根文件系统的文件系统可以用于嵌入式系统的开发阶段要求:目标板上能够使用硬盘或者具有模仿硬盘的装置(3)网络网络引导配置方式中,存在两种情况:(1)内核位于固态存储设备上或磁盘上,需要通过NFS安装根文件系统(2)只有内核加载程序位于目标板的存储设备上,需要通过TFTP下载内核和根文件系统(或NFS)往往用于开发初期总结1:嵌入式系统与PC设备名称嵌入式系统PC机CPU嵌入式处理器(ARM,MIPS)CPU(Intel的Pentium、AMD的Athlon等)内存SDRAM芯片SDRAM,DDR内存条存储设备Flash芯片硬盘输入设备按键、触摸屏鼠标、键盘输出设备LCD显示器声音设备音频芯片声卡接口MAX232等芯片主板集成其他设备USB芯片、网卡芯片主板集成或外接卡嵌入式系统与PC(2)嵌入式系统PC机引导代码Bootloader引导,针对不同电路板进行移植主板的BIOS引导,无须改动操作系统WinCE、VxWorks、Linux等,需要移植Windows、Linux等,不需要移植驱动程序每个设备驱动都必须针对电路板进行重新开发或移植,一般不能直接下载使用操作系统含有大多数驱动程序,或从网上下载直接使用协议栈需要移植操作系统包括,或第三方提供开发环境借助服务器进行交叉编译在本机就可开发调试仿真器需要不需要总结2:常见嵌入式操作系统总结3:总结4:总结5:嵌入式软件开发主要流程嵌入式系统开发的内容主要内容一、嵌入式Linux开发综述二、Linux的配置和编译内核是所有Linux系统软件组成的核心。它的性能对整个系统的性能起决定性作用。如果内核不支持目标板上的某个硬件,那么在目标板上使用这个内核时,这个硬件就不能起作用。一个嵌入式系统准备好一个可用的Linux内核,包括内核的选择、配置、编译和安装工作。Linux内核源代码中的主要子目录Documentation内核方面的相关文档。arch与体系结构相关的代码。对应于每个支持的体系结构,有一个相应的目录如i386、arm、alpha等。每个体系结构子目录下包含几个主要的子目录:kernel与体系结构相关的核心代码mm与体系结构相关的内存管理代码lib与体系结构相关的库代码include内核头文件。对每种支持的体系结构有相应的子目录。init内核初始化代码。kernel内核管理代码。mm内存管理代码。ipc进程间通讯代码。net网络部分代码。lib与体系结构无关的内核库代码。drivers设备驱动代码。每类设备有相应的子目录,如char、block、net等fs文件系统代码。每个支持文件系统有相应的子目录,如ext2、proc等。modules可动态加载的模块。Scripts配置核心的脚本文件。Linux的配置和编译步骤Linux内核从配置到安装大致有如下步骤:清理:makemrproper配置:makeconfig/menuconfig/xconfig建立依赖关系:makedep编译:make或makezImage安装:makeinstall但在嵌入式系统开发中,并不总是按照上述步骤1、Linux内核选择尽管是主要的内核来源,但这里可用的内核版本并不总适用于嵌入式系统下面列出了针对当前主要嵌入式系统的Linux内核源代码下载地点,通常直接提供了针对某种目标硬件系统的Linux内核版本处理