嵌入式系统设计与开发课件-第5章_第1页
嵌入式系统设计与开发课件-第5章_第2页
嵌入式系统设计与开发课件-第5章_第3页
嵌入式系统设计与开发课件-第5章_第4页
嵌入式系统设计与开发课件-第5章_第5页
已阅读5页,还剩99页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

5.1Linux及其应用5.2嵌入式Linux内核5.3嵌入式Linux文件系统5.4典型嵌入式Linux系统练习题第5章嵌入式Linux操作系统

5.1Linux及其应用

5.1.1Linux与Unix和GNU

Linux是Unix操作系统的一个克隆系统,所以在介绍Linux之前先来看看Unix的发展简史。1965年,美国AT&T的Bell实验室、通用电气公司(GE)和麻省理工学院(MIT)合作开发名为Multics(MultiplexedInformationandComputingService)的用于商用的大型机操作系统,Multics的主要设计目标是提供一种用于多用户的大规模的计算环境,方便地实现软、硬件资源的共享。

1969年,Bell实验室从该项目计划中撤出,以DennisRitchie、KenThompson和RuddCanaday等为首的Bell实验室的科学家决定开发另一个新的系统来替代Multics,并且取名为Unics。Multi表示大而复杂,Uni则表示小而精干,借用了Multics的“cs”谐音,体现出Unics是对Multics的“背叛和继承”。Unics不仅提供了一个良好的编程环境,而且产生了一个团体随之成长。这就是Unix的最初由来。

Unix第一次编写是在一台PDP-7的机器上,当时Thompson用这台机器在玩“太空旅游”游戏。起初,Unix系统必须在GECOS(一种通用电气的操作系统)环境下编写并且通过纸带转化到PDP-7。后来,他们写了一个针对PDP-7的汇编器,Unix也变成自支持的了。新系统在1970年夏天编写完成,但是由于没有磁盘,直到12月份才拷贝出来。尽管操作系统的编写工具偏向使用高级语言,但是第一个版本的Unix却是用汇编语言写的。1971年,Thompson尝试使用Fortran语言重写Unix,但是很快放弃。后来,他开发了一种叫做B的简单语言,他对B做稍许改进并命名为NB(NewB)。NB语言增加了一些类以及相应的编译器,就是C语言。Thompson从1972年开始使用C语言重写Unix,但是他遇到了几个问题:如何协同程序(即上下文切换)和第一版的C没有结构体。于是,Ritchie添加了C语言结构体,改进了编译器,并且在第二年的夏天完成了重写工作。

1976年至1977年之间,Thompson花了6个月时间,在UCB(UniversityofCalifornia-Berkeley)的计算机学院担任客座教授,教授Unix。Thompson回到Bell实验室以后,UCB的老师和学生继续改进Unix系统,并研发了Unix操作系统的第一个分支——BSD(BerkeleySoftwareDistribution)。BSD系列的突出贡献就是引入了TCP/IP网络。

1984年,AT&T分裂成多个子公司,并成立了独立的AT&T计算机系统,进入计算机领域。与此同时,SunMicrosystem、SGI、HP、NCR和IBM纷纷推出基于各自硬件平台上的Unix核,这些Unix系统各具特色,值得一提的是Microsoft在20世纪80年代初推出了Xenix,并且成为当时最大的Unix系统发布商之一。

1993年,Novell买下了USL(UnixSystemLaboratories,AT&T的分支机构)和Unix,1995年又将其卖给了SCO(SantaCruzOperation)。严格来说,Unix是由OpenGroup(开放组织)管理的一个商标,它指的是一种遵循特定规范的计算机操作系统。这个规范也称为单一Unix规范(TheSingleUnixSpecification),定义了所有必需的Unix操作系统函数的名称、接口和行为。这个规范在很大程度上是早期由IEEE(电气和电子工程师协会)开发的一系列规范(P1003或POSIX规范)的超集。Unix的源代码属于SCO公司。有许多商用的类Unix系统,如SCO的UnixWare、IBM的AIX、HP的HP-UX和Sun的Soloris,还有一些可以免费获得,如FreeBSD和Linux。表5-1是对常见的Unix系统变体的简要介绍。

Linux诞生于1991年,是一个年轻的操作系统,芬兰赫尔辛基大学的学生LinusBenedictTorvalds是Linux的缔造者。1990年,Linus购买了一台微机,用来学习计算机科学家AndrewS.Tanenbaum开发的Minix(一个用于教学的Unix操作系统)。在学习过程中,Linus发现Minix的功能很不完善,于是,他在自己的微机上自行开发了一套保护模式下的操作系统,这就是Linux的原型。

Linux第一次问世是在1991年10月5日,即0.02版。Linus将该版本发布在学校的一台FTP服务器上,服务器管理员认为这个操作系统是Linus的Minix,于是将两者名字混起来建立了名为Linux的目录存放该系统。该版本的系统包括一个简单的磁盘驱动程序和一个文件系统,可以运行bash和gcc编译器,但是其中不包括良好的用户界面以及文档。Linux0.02版本发布以后开始引起各地程序员和爱好者们的注意力,并且以每两周出一次修正版的速度成长。

1993年,Linux第一个正式版本1.0版发布,并遵从GPL(GNUPublicLicense)版权协议。该协议使得Linux更加迅速地流传开来,并且在公众心中留下了美好的印象,从而得到全世界黑客们的热心支持。

GNU计划和自由软件基金会(FreeSoftwareFoundation,FSF)是由RichardM.Stallman于1984年一手创办的,旨在开发一个类似Unix、并且是自由软件的完整操作系统——GNU系统(GNU是“GNU’sNotUnix”的递归缩写)。各种使用Linux作为核心的GNU操作系统正在被广泛使用。虽然这些系统通常被称做“Linux”,但是严格地说,它们应该被称为GNU/Linux系统。到20世纪90年代初,GNU项目已经开发出许多高质量的免费软件,其中包括有名的emacs编辑系统、bashshell程序、gcc系列编译程序、gdb调试程序等。这些软件为Linux操作系统的开发创造了一个合适的环境,是Linux能够诞生的基础之一。目前,许多人都将Linux操作系统称为“GNU/Linux”操作系统。5.1.2Linux的特点

Linux操作系统在短短的十几年之内得到了非常迅猛的发展,这与Linux所具有的良好特性是分不开的。Linux包含了Unix的全部功能和特性。简单地说,Linux具有以下主要

特性。

(1)开放性。开放性是指系统遵循世界标准规范,特别是遵循开放系统互连(OSI)国际标准。凡遵循国际标准所开发的硬件和软件,都能彼此兼容,可方便地实现互连。Linux完全支持POSIX1003.1标准。另外,为了使UnixSystemV和BSD上的程序能直接在Linux上运行,Linux还增加了部分SystemV和BSD的系统接口,使Linux成为一个完善的Unix程序开发系统。

(2)多用户。多用户是指系统资源可以被不同用户各自拥有使用,即每个用户对自己的资源(例如文件、设备)有特定的权限,互不影响。Linux是一个多用户操作系统,它允许多个用户同时访问系统而不会造成用户之间的相互干扰。另外,Linux还支持真正的多用户编程,一个用户可以创建多个进程,并使各个进程协同工作来完成用户的需求。

(3)多任务。多任务是现代计算机的最主要的一个特点。它是指计算机同时执行多个程序,而且各个程序的运行互相独立。Linux系统调度每一个进程,平等地访问微处理器。由于CPU的处理速度非常快,其结果是,启动的应用程序看起来好像在并行运行。事实上,从处理器执行一个应用程序中的一组指令到Linux调度微处理器再次运行这个程序之间只有很短的时间延迟,用户是感觉不出来的。

(4)良好的用户界面。Linux向用户提供了用户界面和系统调用。Linux的传统用户界面是基于文本的命令行界面,即Shell,它既可以联机使用,又可存在文件上脱机使用。Shell有很强的程序设计能力,用户可方便地用它编制程序,从而为用户扩充系统功能提供了更高级的手段。可编程Shell是指将多条命令组合在一起,形成一个Shell程序,这个程序可以单独运行,也可以与其他程序同时运行。系统调用给用户提供编程时使用的界面。用户可以在编程时直接使用系统提供的系统调用命令。系统通过这个界面为用户程序提供低级、高效率的服务。

Linux还为用户提供了图形用户界面。它利用鼠标、菜单、窗口、滚动条等设施,给用户呈现了一个直观、易操作、交互性强的友好的图形化界面。

(5)设备独立性。设备独立性是指操作系统把所有外部设备统一当成文件来看待,只要安装它们的驱动程序,任何用户都可以像使用文件一样,操纵、使用这些设备,而不必知道它们的具体存在形式。具有设备独立性的操作系统,通过把每一个外围设备看做一个独立文件来简化增加新设备的工作。当需要增加新设备时,系统管理员就在内核中增加必要的连接。这种连接(也称做设备驱动程序)保证每次调用设备提供服务时,内核以相同的方式来处理它们。当新的及更好的外设被开发并交付给用户时,操作允许在这些设备连接到内核后,就能不受限制地立即访问它们。设备独立性的关键在于内核的适应能力。其他操作系统只允许一定数量或一定种类的外部设备连接。而设备独立性的操作系统能够容纳任意种类及任意数量的设备,因为每一个设备都是通过其与内核的专用连接独立进行访问的。

Linux是具有设备独立性的操作系统,它的内核具有高度适应能力,随着更多的程序员加入Linux编程,会有更多硬件设备加入到各种Linux内核和发行版本中。另外,由于用户可以免费得到Linux的内核源代码,因此,用户可以修改内核源代码,以便适应新增加的外部设备。

(6)提供了丰富的网络功能。完善的内置网络是Linux的一大特点。Linux在通信和网络功能方面优于其他操作系统。其他操作系统不包含如此紧密地和内核结合在一起的连接网络的能力,也没有内置这些联网特性的灵活性。而Linux为用户提供了完善的、强大的网络功能。

支持Internet是其网络功能之一。Linux免费提供了大量支持Internet的软件,Internet是在Unix领域中建立并繁荣起来的,在这方面使用Linux是相当方便的,用户能用Linux与世界上的其他人通过Internet网络进行通信。文件传输是其网络功能之二。用户能通过一些Linux命令完成内部信息或文件的传输。

远程访问是其网络功能之三。Linux不仅允许进行文件和程序的传输,它还为系统管理员和技术人员提供了访问其他系统的窗口。通过这种远程访问的功能,一位技术人员能够有效地为多个系统服务,即使那些系统位于相距很远的地方。

(7)可靠的系统安全。Linux采取了许多安全技术措施,包括对读/写进行权限控制、带保护的子系统、审计跟踪、核心授权等,这为网络多用户环境中的用户提供了必要的安全保障。

(8)良好的可移植性。可移植性是指将操作系统从一个平台转移到另一个平台使它仍然能按其自身的方式运行的能力。Linux是一种可移植的操作系统,能够在从微型计算机到大型计算机的任何环境中和任何平台上运行。可移植性为运行Linux的不同计算机平台与其他任何机器进行准确而有效的通信提供了手段,不需要另外增加特殊的和昂贵的通信接口。5.1.3Linux的发展及应用

1.Linux的发展

1991年10月5日,LinusTorvalds在新闻组comp.os.minix发布了大约有一万行代码的Linuxv0.01版本。1994年3月,Linux1.0发布,代码量17万行,当时是按照完全自由免费的协议发布的,随后正式采用GPL协议。1996年6月,Linux2.0内核发布,此内核有大约40万行代码,并可以支持多个处理器。此时的Linux已经进入了实用阶段,全球大约有350万人使用。

1998年可以说是Linux与商业接触的一年。1月,小红帽(RedHat)高级研发实验室成立。4月Mozilla代码发布,成为Linux图形界面上的王牌浏览器。RedHat宣布商业支持计划,网罗了多名优秀技术人员开始商业运作。同年10月,Intel和Netscape宣布小额投资红帽软件,这被业界视作Linux获得商业认同的信号。

1999年,IBM宣布与RedHat公司建立伙伴关系,7月IBM启动对Linux的支持服务和发布了LinuxDB2,从此结束了Linux得不到支持服务的历史,这可以视作Linux真正成为服务器操作系统一员的重要里程碑。

2000年2月,RedHat发布了嵌入式Linux的开发环境,Linux在嵌入式行业的潜力逐渐被发掘出来。

2003年1月,NEC宣布将在其手机中使用Linux操作系统,代表着Linux成功进军手机领域。

2004年6月的统计报告显示,在世界500强超级计算机系统中,使用Linux操作系统的已经占到了280席,抢占了原本属于各种Unix的份额。从1991年发布以来,Linux已经经历了高速的发展,受到了越来越多的用户的青睐。目前,世界上大概有三百多种Linux发行版本,主流的有RedHat、SUSE、Debian,并且不断有新的版本发行,其中不乏优秀之作,比如近年来比较流行的Ubuntu。现在,Linux无论是从性能上还是功能上都日臻成熟,在操作系统领域,基本上与Unix和Windows形成了三足鼎立的局面。

2.Linux的应用

随着Linux系统的逐渐推广,它被越来越多的计算机用户所了解和应用,各国政府都在鼓励和支持Linux在本国的发展。越来越多的政府机构和IT巨头的注意力正在转向Linux。从嵌入式设备到桌面电脑再到服务器,Linux现在几乎可以用于所有的地方。

1) Linux在嵌入式设备中的应用

Linux的特点使得它天生就是一个适合于嵌入式开发和应用的操作系统:Linux内核精简而高效,通过对不需要的功能的裁减,Linux内核完全可以小到100KB以下;Linux操作系统实时性强,出现了一些基于Linux进行修改的实时操作系统,其中著名的为RTLinux;Linux具备良好的网络性能;Linux支持多种体系结构,可修改性强。

2) Linux在桌面电脑中的应用

Linux在桌面电脑中的应用一直是广大Linux爱好者和支持者最关心的,但是几乎所有Unix系统的初学者都觉得操作不方便,难以理解,当然Linux也不例外。近些年,随着广大Linux爱好者和支持者的共同努力,新版本的Linux系统特别是在桌面应用方面得到了改进,达到相当的水平,完全可以作为一种集办公应用、多媒体应用、网络应用等多方面功能于一体的图形界面操作系统。

3) Linux在大型服务器上的应用

目前Linux服务器是当前最广泛的应用。全世界各个Linux厂商和独立软件开发商已经开发了大量的Linux应用产品,其中涉及的领域包括零售业、金融证券、教育、邮政、电力等十几个行业,提供的解决方案包括网上证券系统、电力管理、财务管理、客户关系管理、并行计算、电子化邮局等。

5.2嵌入式Linux内核

5.2.1嵌入式Linux的内核特征

Linux是个人计算机和工作站上的Unix类操作系统。但是,它绝不是简化的Unix。相反,Linux是强有力和具有创新意义的Unix类操作系统。它不仅继承了Unix的特征,而且在许多方面超过了Unix。作为Unix类操作系统,Linux内核具有下列基本特征:

(1)内核的组织形式为整体式结构。Linux内核由很多过程组成,每个过程可以独立编译,然后用连接程序将其连接在一起成为一个单独的目标程序。从信息隐藏的观点看,它没有任何程度的隐藏——每个过程都对其他过程可见。这种结构的最大特点是内部结构简单,子系统间易于访问,因此内核的工作效率较高。另外,基于过程的结构也有助于不同的人参与不同过程的开发,从这个角度来说,Linux内核又是开放式的结构,它允许任何人对其进行修正、改进和完善。

(2)进程调度方式简单而有效。对于用户进程,Linux采用简单的动态优先级调度方式;对于内核中的例程(如设备驱动程序、中断服务程序等),则采用了一种独特的机制——软中断机制,这种机制保证了内核例程的高效运行。

(3)支持内核线程。内核线程是在后台运行而又无终端或登录Shell和它结合在一起的进程。有许多标准的内核线程,其中有一些通过周期地运行来完成特定的任务(如swapd),而其余一些则连续地运行,等待处理某些特定的事件(如inetd和lpd)。内核线程可以说是用户进程,但和一般的用户进程又有不同,它像内核一样不被换出,因此运行效率较高。

(4)支持多种平台的虚拟内存管理。内存管理是和硬件平台密切相关的部分,为了支持不同的硬件平台而又保证虚拟存储管理技术的通用性,Linux的虚拟内存管理为不同的硬件平台提供了统一的接口,因此把Linux内核移植到一个新的硬件平台并不是一件很困难的事。

(5)虚拟文件系统(VFS)。Linux内核另一个独具特色的部分是虚拟文件系统(VFS)。虚拟文件系统不仅为多种逻辑文件系统(如ext2、fat等)提供了统一的接口,而且为各种硬件设备(作为一种特殊文件)也提供了统一的接口。

(6)模块机制。Linux的模块机制使得内核保持独立而又易于扩充。模块机制可以使内核很容易地增加一个新的模块(如一个新的设备驱动程序),而无需重新编译内核;同时,模块机制还可以把一个模块按需添加到内核或从内核中卸下,这使得我们可以按需要定制自己的内核。

(7)增加系统调用以满足特殊的需求。一般来说,系统调用是操作系统的设计者提供给用户使用内核功能的接口,但Linux开放的源代码也允许用户设计自己的系统调用,然后把它加入到内核。

(8)网络部分采用面向对象的设计思想。网络部分面向对象的设计思想使得Linux内核支持多种协议、多种网卡驱动程序变得容易。5.2.2进程管理

进程(Progress)是Unix操作系统最基本的抽象之一,是申请系统资源的基本单位。简单地说,进程就是运行中的程序。程序是静态的,而进程则是动态的,并且多个进程可以并发调用同一个程序。通常进程除了包含程序中的所有内容外,还要包含其他资源,比如打开的文件、挂起的信号、内核内部的数据、处理器状态、地址空间以及存放全局变量的数据段等。

进程管理的主要功能是完成处理机资源的分配调度,它的调度单元是进程。也就是说,进程管理的主要任务就是决定哪个进程使用CPU,并对进程进行管理。一般来说,进程管理包括四个方面:进程控制、进程调度、进程同步和进程通信。

1.Linux进程概述

Linux进程实体由以下三部分组成。

(1)正文段(Text):存放进程的可执行代码。

(2)用户数据段(UserSegment):存放进程执行时所操作的数据。

(3)进程控制块(ProcessControlBlock,PCB):存放进程的控制信息。Linux为每个新建立的进程分配一个进程控制块(PCB),其数据结构为task_struct。在生命周期内,进程的状态不断地发生着变换,对于Linux来说,其进程主要有以下几种状态。

(1)运行状态:指进程正在运行(已获得CPU资源的分配)或者处于等待调度程序进行CPU资源分配(就绪态)时的状态。所有运行状态的进程被放在运行队列中。

(2)等待状态:指进程正在等待某个事件发生或某种资源分配时的状态。它又可分为两种:可中断等待状态和不可中断等待状态。处于可中断等待状态的进程可以被某一信号中断后进入运行队列;处于不可中断等待状态的进程一般情况下不能被中断,只能等待资源有效分配时被唤醒。

(3)暂停状态:指进程暂时停止运行,接受某种处理时所处的状态。比如,一个进程受其他进程的跟踪调用而暂时将CPU资源让给跟踪它的进程时就处于这种状态,该进程只能被其他进程的信号唤醒。

(4)僵死状态:指进程使用系统调用exit()自我消亡时的状态,此时,子进程向父进程发信号并释放其所占资源,但尚未释放其进程控制块(PCB)。

Linux进程的状态及转换图如图5-1所示。图5-1Linux进程的状态及转换图

2.Linux进程控制

进程控制的主要任务是创建和撤消进程并且控制进程的状态转换。在Linux中,使用fork()系统调用实现进程的创建工作,并为新创建的进程分配一个进程控制块(其数据结构为task_struct)。当进程完成了特定的工作之后,系统就回收它占用的进程控制块及其他系统资源,并撤消该进程。

1)进程的创建与执行

在Linux中,除了初始化进程是启动时由系统创建外,其他进程都是当前进程通过系统调用fork()创建的。其中,调用fork()的进程叫做父进程,而通过fork()创建的新进程叫做子进程。进程的创建过程如下:首先,系统为新进程(子进程)分配task_struct结构,并为新进程堆栈分配物理页;然后拷贝当前进程(父进程)的内容(正文段、用户数据段及系统数据段)给子进程,同时对子进程中有别于父进程的项进行初始化;最后,把新进程的task_struct结构地址保存在task指针数组中。需要注意的是,Linux创建子进程时采用的是写时拷贝(copyonwrite)的方法,即子进程只是逻辑上拷贝父进程的地址空间,当子进程用到父进程的程序和数据时才拷贝。在父进程使用fork()创建子进程以后,子进程通过exec()转去执行指定程序,由于Linux采用的是写时拷贝的方法,因此在执行exec()之前,只有少量内容被复制,这样可以节省内存空间和拷贝时间。可执行文件名作为Linux的exec()系统调用参数。可执行文件包含了可执行代码及数据,也包含了操作系统用来将映像正确装入并执行的信息。

2)进程的等待与终止

Linux父进程使用fork()创建子进程,子进程通过exec()转去执行指定程序,而父进程可通过系统调用wait()等待子进程结束,wait()的参数指定了父进程等待的子进程。如果子进程尚未终止(未完成任务),则父进程挂起,一旦等到指定的子进程结束,父进程被唤醒,即可继续做其他的工作。

Linux结束一个进程是通过系统调用exit()来实现的。exit()首先释放进程占用的大部分资源,包括进程运行时打开的文件、申请的内存等。然后进程进入僵死状态,并向其父进程发送SIGCHLD信号(参见表5-2),表示子进程结束,使等待子进程结束的父进程取得信号后恢复执行。

3.Linux进程调度

进程调度的主要任务就是按照调度策略合理地分配处理机,提高CPU利用率。进程调度由调度程序负责。每次进行进程调度时,调度程序根据调度算法从一组可运行的进程中选择一个来执行。调度程序中最基本的数据结构是可执行进程的就绪队列。

Linux的可执行进程的就绪队列包含正在执行的进程和可以执行的等待CPU资源的进程。Linux进程调度就是根据调度策略在执行进程的就绪队列中选出一个进程在处理机上运行。调度策略决定了系统对资源的分配,因此会对系统的性能产生直接的影响。Linux系统使用的调度策略有:

(1)用于实时进程的先进先出算法和转轮算法;

(2)用于普通进程的基于优先级的转轮算法。

然而,在实际应用中,Linux往往是将这些调度算法融合在一起使用的。

4.Linux进程同步

进程在协同工作时遇到的问题主要有进程同步和互斥。由于进程是并发运行的,这就意味着多个进程需共享系统资源。为使多个进程能有序协调运行,系统必须设置同步机制对进程的行为进行控制。进程同步的主要任务是对各进程的运行进行协调,协调的方式有以下两种。

(1)进程互斥:指进程在访问临界资源(一次只允许一个进程访问的资源)时应互斥进行。

(2)进程同步:指相互合作完成共同任务的进程间采用同步机制对它们的执行次序加以协调。

5.Linux进程通信

并发的进程有时需要进行一些合作以完成共同的任务,这就需要进程之间相互交换信息,进程通信的任务就是实现相互合作的进程之间的信息交换。有关Linux进程通信将在5.2.6节中详细讨论。5.2.3内存管理

1.Linux中的内存管理概述

Linux中的存储管理实际上是对虚拟地址空间和物理地址空间的管理以及对虚拟页和物理页的管理。在32位处理器上,Linux内核使用32位地址空间,每个进程可以访问4GB的虚拟内存空间。其中:从0到3GB的虚拟地址空间是用户空间,用户进程可以独占并可以直接访问;从3GB到4GB的虚拟地址空间是核心空间,由所有核心态进程共享,存放仅供核心态访问的代码和数据,用户进程处于用户态时不能访问。所有进程从3GB到4GB的虚拟地址都是一样的,有相同的页目录项和页表,对应到同样的物理内存段,Linux以此方式让核心态进程共享代码段和数据段。

Linux采用请求页式技术管理内存,将页面分为三级:页目录(PageDirectory,PGD)、中间页目录(PageMiddleDirectory,PMD)和页表(PageTable,PTE)。每一个进程都有一个页目录,存储该进程所使用的内存页面情况,页目录中的每一项指向中间页目录的一页;中间页目录可能跨多个页,它的每一项指向页表中的一页;页表也可能跨多个页,每个页表项指向该进程的一个虚页。此外,Linux按照“按需调页”的原则只分配必需的内存页面,避免了页面过多占用存储空间的情况。

2.Linux虚拟内存管理的组成结构

Linux虚拟内存管理的组成结构可以分为以下几部分:

(1)内存映射模块(mmap):实现磁盘或交换空间文件的逻辑地址与虚拟地址之间的相互映射。

(2)交换管理模块(swap):控制内存页面换入换出,采用交换机制,保留物理内存中的有效页面,清除近期访问较少的页面。

(3)内存管理模块(core):完成页的分配、回收及请求调页处理等功能。

(4)结构特定模块:提供各种硬件平台通用接口、初始化内存以及处理页面故障等。图5-2给出了Linux虚拟内存管理的组成结构。图5-2Linux虚拟内存管理的组成结构5.2.4文件系统管理

计算机系统中存在着大量的信息和数据,这些信息和数据以文件的形式存放在外存上,为了管理外存上的文件,操作系统设置了管理文件的功能模块——文件系统。文件系统管理应包含文件存储空间管理、文件目录管理、文件读写管理以及文件保护管理。

对于Linux而言,文件系统管理是一个非常重要的部分。Linux能支持多种不同的文件系统,这是通过引入虚拟文件系统(VirtualFileSystem,VFS)来实现的。具体来说,Linux通过虚拟文件系统,对其支持的文件系统进行抽象,而将其所支持的真正的文件系统挂接在虚拟文件系统之下。这样,Linux就可以使用统一的接口对各种不同类型的文件系统进行访问。

Linux虚拟文件系统包括以下功能:

(1)记录可用的文件系统类型;

(2)建立设备与文件系统之间的联系;

(3)处理面向文件的一些通用操作。5.2.5设备管理

Linux的设备管理的主要任务是控制设备完成I/O操作。Linux采用设备文件统一管理文件硬件设备,从而将硬件设备的特性及管理细节对用户隐藏起来,实现了用户程序与设备的无关性。

1.Linux中的设备

1)分类

Linux中设备被分为字符设备、块设备和网络设备三类。字符设备是以字节为单位输入/输出数据的设备,一般不需要使用缓冲区,可以直接读写;块设备是以一定大小的数据块为单位输入/输出数据的设备,一般需要使用缓冲区在设备和内存间传送数据;网络设备是通过通信网络传输数据的设备,例如网络适配器(网卡)等。

2)特点

Linux设备管理的一个基本特点就是把物理设备看成文件,从抽象的观点看,Linux的设备又称为设备文件。Linux中每一个设备都有一个文件名,该文件名由两部分组成:一是主设备号,代表设备的类型,可以唯一确定设备的驱动程序和界面,如hd表示IDE硬盘,而sd表示SCSI硬盘;二是次设备号,代表同类设备中的序号,如hda表示IDE主硬盘,hdb表示IDE从硬盘。基于以上的特点,Linux采用处理文件的接口和系统调用来管理控制设备,对设备的操作是通过对文件操作的file_operations结构体来调用驱动程序的设备服务子程序的。

2.Linux的设备驱动程序

Linux系统对设备的控制和操作都是由设备驱动程序来完成的。Linux的驱动程序分为两个基本类型:字符设备驱动程序和块设备驱动程序。此外,每个设备驱动程序都是由两部分组成的:一是设备驱动子程序,它包含对设备进行各种操作的代码;二是设备中断子程序,负责处理设备中断。

设备驱动程序主要完成以下功能:

(1)对设备进行初始化;

(2)对设备状态进行检测;

(3)负责设备和内存之间的数据传送;

(4)启动或停止设备的运行。

3.Linux的I/O控制

Linux的I/O控制方式有三种:中断方式、查询等待方式和DMA(内存直接存取)方式。

(1)中断方式:在硬件支持中断的情况下,驱动程序可以使用该方式控制I/O过程。对I/O过程控制使用的中断是硬件中断。

(2)查询等待方式:又叫轮询方式(pollingmode)。对于不支持中断方式的计算机只能采用这种方式来控制I/O过程。并行接口的驱动程序中默认的控制方式就是查询等待方式。

(3) DMA方式:其基本思想是在外围设备和内存之间开辟直接的数据交换通道。在DMA控制器中,除了状态寄存器和数据缓冲寄存器外,还包括字节计数器和内存地址寄存器以及控制电路等。因此,DMA控制器可以用来代替CPU,以实现内存与设备之间进行成批的数据交换。5.2.6进程间通信机制

Linux提供多种进程间通信机制(InterprocessCommunication,IPC),常用的有信号(Signal)机制、管道(Pipe)机制、消息队列(MessageQueue)机制、信号量(Semaphore)机制与共享内存(SharedMemory)机制。受篇幅所限,下面只对其中的几种通信机制加以介绍。

1.信号机制

信号机制是Linux最基本的进程通信机制,用于向一个或多个进程发送异步的时间信号来处理异常事件。

Linux进程对某个信号做出的反应是由其进程控制块(PCB)中的信号屏蔽机制和处理函数选择机制来决定的。由于Linux的信号屏蔽机制是通过一个32位变量的位掩码来决定的,因此,Linux最多能接受32种信号,其中最常用信号的值、名及意义如表5-2所示。

2.管道机制

Linux管道分为两类:无名管道和有名管道。

1)无名管道(AnonymousPipe)

在Linux中,管道是通过指向同一个临时VFSinode(虚拟文件系统的索引节点)的两个file结构来实现的(确切地说是两个file结构的f_inode属性指向同一个临时的VFS索引节点inode),该VFSinode指向内存中的一个物理页面。如图5-3所示,两个file结构,一个用来从管道中读取数据,另一个用来向管道中写入数据。无名管道由pipe()系统调用创建,当管道创建后,将包含两个文件描述符fd[0]和fd[1],fd[0]用于读管道,对应读取数据的file结构,fd[1]用于写管道,对应写入数据的file结构,读、写管道可以通过系统调用read()和write()来实现。

两个进程是这样使用管道来实现通信的:写进程利用标准库函数write()将数据复制到临时VFSinode所指向的共享物理页上,而读进程则利用read()函数复制共享物理页中的数据,从而读出管道中的数据。管道机制如图5-3所示。图5-3管道机制示意图

2)有名管道(FIFO)

Linux中另外一种管道形式叫有名管道或FIFO,这是因为这种管道的操作是基于先入先出(FirstInFirstOut,FIFO)原理的。有名管道和无名管道的数据结构及操作相似,二者的区别在于:有名管道是按名存取文件,文件在使用之前就已经存在,用户可关闭和打开有名管道,而无名管道是临时对象,只在操作时才存在;另外,有名管道允许无亲缘关系的进程间通信,而无名管道则不行,这里的亲缘关系指的是具有共同的祖先,比如父子进程和兄弟进程。

3.消息队列机制

消息是一个有着特定类型的字符块,而消息队列则是一个消息链表。消息队列允许一个或多个进程读取消息,也允许一个或多个进程写入消息。Linux为所有消息队列维护一个msgque链表,该链表中的每个指针指向一个msgid_ds结构,该结构完整描述了一个消息队列。每个msgid_ds结构包含一个ipc_perm结构以及两个等待队列(写等待队列和读等待队列)。消息队列机制中,进程在创建时返回一个带有访问权限的标识,ipc_perm结构则描述了这种访问权限,在进程通信时通过ipc_perm结构检查进程的访问权限。此外,消息队列中的每个消息都是一个含格式化信息的结构msg,其定义如下:structmsg

{structmsg*msg_next;/*消息队列中的下一个消息*/

longmsg_type; /*消息类型*/

char*msg_spot; /*消息文本的地址*/

time_tmsg_stime; /*消息发送时间*/

shortmsg_ts; /*消息文本长度*/

}消息队列是进程读、写消息的存储空间,进程可以向消息队列写入信息,也可以从消息队列中读取信息。当进程希望对指定的消息队列进行写操作时,首先要经过系统的检查,即将进程的标识信息与队列的ipc_perm对应的属性进行比较。检查通过后,将消息复制到msg,再挂到消息队列的末尾。如果消息队列一时无法接收该信息的写入,比如消息队列已满,写消息的进程就暂时进入写等待队列,直到消息队列有空间时才被唤醒。进程从消息队列读取消息也是类似的。系统先检查进程的访问权限,检查通过后,读取消息。如果进程所要读取的消息不存在,则进程进入读等待队列,直到所要读取的消息进入消息队列时才被唤醒。

5.3嵌入式Linux文件系统

5.3.1嵌入式文件系统介绍

文件系统通常被定义为一种用来管理、组织信息的方法。嵌入式文件系统,顾名思义就是指在嵌入式系统中使用的文件系统。嵌入式文件系统是嵌入式系统中一个非常重要的组成部分,随着嵌入式硬件功能的不断增强和价格的不断降低以及嵌入式系统应用范围的不断扩大,其重要性愈发明显。嵌入式文件系统不同于普通桌面文件系统,这是因为嵌入式系统是针对特殊的应用而定制的。一般来说,嵌入式文件系统要为嵌入式操作系统的设计目的服务,不同用途的操作系统下的文件系统在许多方面存在着不同。5.3.2Linux文件系统概述

Linux支持多种不同类型的文件系统,例如minix、ext、ext2、msdos、vfat、ntfs、iso9660等。Linux的第一个文件系统是minix;1992年引入了第一个专门为Linux设计的文件系统ext(ExtendedFileSystem,扩展文件系统);1993年又加入了ext2,对ext文件系统进行重新组织和改进。ext2在使用中不断得到改进,逐渐发展成熟,已经成为Linux的标准文件系统。而ext3文件系统则是由ext2文件系统发展而来的,目前,最新的Linux版本已经开始支持这种文件系统。

Linux能支持多种不同类型的文件系统,并且是通过引入虚拟文件系统(VFS)来实现的。真正的文件系统从操作系统和系统服务中分离出来,在它们之间使用了虚拟文件系统这样一个接口层。虚拟文件系统为用户提供一个统一、抽象、虚拟的文件系统界面。也就是说,虚拟文件系统屏蔽了不同文件系统的差别,为处理各种不同的文件系统提供了统一的接口。5.3.3嵌入式Linux常用文件系统

在嵌入式Linux应用中,主要的易失性存储设备为SRAM、DRAM、SDRAM,非易失性存储设备为Flash、ROM等,常用的基于存储设备的文件系统类型包括jffs2、yaffs、cramfs、ramdisk、ramfs/tmpfs等。另外,nfs是一种网络文件系统,常用于嵌入式Linux的开发调试。下面就对这几种文件系统加以介绍。

1.基于Flash的文件系统

Flash(闪存)作为嵌入式系统的主要存储媒介,主要有NOR和NAND两种。Flash存储器的擦写次数是有限的,NAND闪存还有特殊的硬件接口和读写时序,因此,必须针对Flash的硬件特性设计符合应用要求的文件系统。在嵌入式Linux下,MTD(MemoryTechnologyDevice,存储技术设备)为底层硬件(闪存)和上层(文件系统)之间提供一个统一的抽象接口,即Flash的文件系统都是基于MTD驱动层的。

1) jffs2

jffs文件系统最早是由瑞典AxisCommunications公司基于Linux2.0的内核为嵌入式系统开发的文件系统。而jffs2日志闪存文件系统版本2(JournallingFlashFileSystemv2)是RedHat公司基于jffs开发的闪存文件系统,最初是针对RedHat公司的嵌入式产品eCos开发的嵌入式文件系统。jffs2主要用于NOR型闪存,基于MTD驱动层,其特点是可读写的、支持数据压缩的、基于哈希表的日志型文件系统,并提供了崩溃/掉电安全保护,提供“写平衡”支持等;缺点主要是当文件系统已满或接近满时,因为垃圾收集的关系而使得运行速度大大放慢。

2) yaffs(YetAnotherFlashFileSystem)

yaffs/yaffs2是专为嵌入式系统使用NAND型闪存而设计的一种日志型文件系统。与jffs2相比,它减少了一些功能(例如不支持数据压缩),所以速度更快,挂载时间很短,对内存的占用较小。yaffs/yaffs2自带NAND芯片的驱动,并且为嵌入式系统提供了直接访问文件系统的API,用户可以不使用Linux中的MTD与VFS,直接对文件系统操作。yaffs也可与MTD驱动程序配合使用。

yaffs与yaffs2的主要区别在于:前者仅支持小页(512B)NAND闪存,后者则可支持大页(2KB)NAND闪存。同时,yaffs2在内存空间占用、垃圾回收速度、读/写速度等方面均有大幅提升。

3) cramfs(CompressedROMFileSystem)

cramfs是Linux的创始人LinusTorvalds参与开发的一种只读的压缩文件系统。它也基于MTD驱动程序。在cramfs文件系统中,每一页(4KB)被单独压缩,节省大量的Flash存储空间,从而降低系统成本。cramfs文件系统以压缩方式存储,在运行时解压缩,所以不支持应用程序以XIP(eXecuteInPlace,片内运行)方式运行,所有的应用程序要求被拷到RAM里去运行。cramfs采用分页压缩的方式存放档案,在读取档案时,不会一下子就耗用过多的内存空间,而只针对目前实际读取的部分分配内存,尚没有读取的部分不分配内存空间,当读取的档案不在内存时,cramfs文件系统自动计算压缩后的资料所存的位置,再即时解压缩到RAM中。另外,cramfs的速度快,效率高,其只读的特点有利于保护文件系统免受破坏,提高了系统的可靠性。由于以上特性,cramfs在嵌入式系统中应用广泛。但是它的只读属性同时又是它的一大缺陷,使得用户无法对其内容进行扩充。cramfs映像通常是放在Flash中,但是也能放在别的文件系统里。

2.基于RAM的文件系统

1) ramdisk

ramdisk是将一部分固定大小的内存当做分区来使用的。它并非一个实际的文件系统,而是一种将实际的文件系统装入内存的机制,并且可以作为根文件系统。将一些经常被访问而又不会更改的文件(如只读的根文件系统)通过ramdisk放在内存中,可以明显地提高系统的性能。

2) ramfs/tmpfs

ramfs是LinusTorvalds开发的一种基于内存的文件系统,工作于虚拟文件系统(VFS)层,不能格式化,可以创建多个,在创建时可以指定其最大能使用的内存大小。ramfs/tmpfs文件系统把所有的文件都放在RAM中,所以读/写操作发生在RAM中,可以用ramfs/tmpfs来存储一些临时性或经常要修改的数据,例如/tmp和/var目录,这样既避免了对Flash存储器的读/写损耗,也提高了数据读/写速度。

ramfs/tmpfs相对于传统的ramdisk的不同之处主要在于:不能格式化,文件系统大小可随所含文件内容大小而变化。tmpfs的一个缺点是当系统重新引导时会丢失所有数据。

3.网络文件系统(NetworkFileSystem,NFS)

NFS是由Sun开发并发展起来的一项在不同机器、不同操作系统之间通过网络共享文件的技术。在嵌入式Linux系统的开发调试阶段,可以利用该技术在主机上建立基于NFS的根文件系统,挂载到嵌入式设备,可以很方便地修改根文件系统的内容。5.3.4嵌入式Linux文件系统框架和特性

Linux支持多种文件系统,为了对各类文件系统进行统一管理,Linux引入了虚拟文件系统(VirtualFileSystem,VFS),为各类文件系统提供一个统一的操作界面和应用编程接口。

Linux下的文件系统结构如图5-4所示。图5-4

Linux下的文件系统结构

Linux启动时,第一个必须挂载的是根文件系统;若系统不能从指定设备上挂载根文件系统,则系统会出错而退出启动。之后可以自动或手动挂载其他的文件系统。因此,一个系统中可以同时存在不同的文件系统。

1.Linux文件系统层次式树状目录结构

Linux文件系统采用层次式树状目录结构。如图5-5所示,层次式树状目录结构最上层是根目录“/”,在此根目录下再建立各层目录和文件。每层目录中可以包含多个下一级目录和文件。Linux表示文件和目录位置的方法有两种:绝对路径和相对路径。绝对路径是从根目录开始,依次指定其下层各个目录的名字,如/usr/bin/make;相对路径是从当前目录(系统在运行中进入的目录)开始,指定其下层目录,如当前目录为/usr,则绝对路径/usr/bin/make可以表示成相对路径bin/make。图5-5Linux文件系统的层次式树状目录结构

2.Linux文件类型

Linux中的文件类型主要有以下几种:

(1)普通文件:是最常见的一种文件类型。普通文件可分为二进制文件和ASCII文件两种。

(2)目录文件:用来维护文件系统层次结构的文件。目录文件记录了它包含的文件、子目录以及与它相关的信息。

(3)设备文件:用来表示I/O设备的文件。设备文件又分为两种:字符设备文件和块设备文件,分别对应字符设备和块设备。

(4)管道文件:用于在进程间通信时传递数据。

(5)链接文件:是指向另一个文件的文件,即文件指针。链接文件仅含有访问另一个文件的信息。

3.Linux文件访问权限

Linux为了保证文件信息的安全,给文件设置一定的访问权限。访问权限有3种:User(用户)、Group(同组用户)及Other(其他用户)。对文件访问的处理操作也有3种:读、写和执行。当用户访问文件时,系统首先检查访问者的权限,只有与文件的访问权限相符才允许访问,反之,则拒绝访问。Linux文件访问权限是可以修改的,至于如何修改,将在第7章中进行讨论。

5.4典型嵌入式Linux系统

5.4.1μCLinux

μCLinux是Lineo公司推出的开放源码的嵌入式Linux操作系统。μCLinux中的μ表示Micro,是微小的意思,C表示Control,是控制的意思,所以μCLinux就是Micro-Control-Linux,字面上的理解就是“针对微控制领域而设计的Linux系统”。

μCLinux是一种优秀的嵌入式Linux版本,它秉承了标准Linux的优良特性,经过各方面的小型化改造,形成了一个高度优化的、代码紧凑的嵌入式Linux。虽然μCLinux的体积很小,但是它仍然保留了Linux的大多数的优点:稳定、良好的移植性、优秀的网络功能、对各种文件系统完备的支持和标准丰富的API等。它专为嵌入式系统做了许多小型化的工作,目前已支持多款CPU。其编译后目标文件可控制在几百KB数量级,并已经被成功地移植到很多平台上。

μCLinux主要是针对目标处理器没有存储管理单元(MemoryManagementUnit,MMU)的嵌入式系统而设计的。虽然μCLinux没有MMU,会对多任务的实现以及进程管理带来一些影响,但是在嵌入式开发中采用不带MMU的处理器可以降低成本。此外,从功能上来看,大部分嵌入式系统都是在特定条件下实现相对简单的功能,因此,不带MMU并不会对程序的开发和运行带来太大的影响。

μCLinux具有如下特点:

(1)支持多种CPU,支持的微处理器如ARM7TDMI、Motorola的ColdFire系列和龙珠系列等。

(2)标准Linux的API。

(3)小型Linux内核和开发系统。内核小于512KB,加上开发工具后也小于900KB。

(4)可定制的网络支持和文件系统。μCLinux具备完整的TCP/IP栈,同时也支持大量的其他网络协议。μCLinux支持多种文件系统,包括ext2、msdos、fat16/32、nfs、romfs和ramfs等。5.4.2RT-Linux

NMTRT-Linux是由美国墨西哥科技大学(NewMexicoTechnology,NMT)开发的嵌入式Linux操作系统。由于其源代码开放,而且Linux功能强大,性能稳定,支持广泛,因此其应用前景被十分看好。到目前为止,RT-Linux已经成功地应用于航天飞机的空间数据采集、科学仪器测控和电影特技图像处理等领域。

RT-Linux开发者并没有针对实时操作系统的特性而重写Linux的内核,因为这样做的工作量非常大,而且要保证兼容性也非常困难。为此,RT-Linux采用的做法是“架空”Linux内核,在Linux内核与硬件系统之间实现一个简单的实时内核,Linux内核作为这个实时内核最低优先级的任务,所有其他实时任务的优先级都要高于Linux的进程。RT-Linux这种将Linux内核作为最低优先级的任务的做法,使Linux对于下层的实时内核来说是可以被抢占的,这样实时进程和中断子程序就不会被非实时操作所延迟。这样对Linux内核的改动非常小,并且充分利用了Linux下现有的丰富的软件资

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论