操作系统有效的组织和管理计算机系统的各种软件、硬件资源,合理的组织计算机系统的工作流程,控制程序的执行,并向用户提供一个良好的工作环境和友好的接口。
(1)操作系统是计算机系统的资源管理者
(2)改善人机界面,为用户提供友好的工作环境
对计算机系统而言,操作系统是对所有系统资源进行管理的程序集合,对用户而言,操作系统提供了对系统资源进行有效利用的简单抽象方法。
操作系统的结构组成:驱动程序,内核,接口库,外围,如图所示。
操作系统主要有五大管理功能:进程管理、文件管理、存储管理、设备管理和作业管理。
1)进程与CPU管理
进程控制:创建进程、撤销进程以及控制进程务在运行过程中的状态转换。
进程调度:从进程就绪队列中,按照一定的算法选择一个进程,使其得到CPU控制权,开始运行。在进程完成后,放弃CPU。
进程同步:设置进程同步机制,协调各进程之间的运行。
进程通信:提供进程间通信的各种机制。如下图:
2)存储器管理
存储器管理的主要任务是为多进程的运行提供高效稳定的运行环境。一般包含:
地址重定位:在多进程环境下,每个任务动态创建,进程的逻辑地址必须转换为主存的物理地址。
内存分配:为每个进程分配内存空间,使用完毕后收回分配的内存。
内存保护:保证每个进程都在自己的内存空间内运行,各程序互不侵犯,尤其是保护操作系统占用的内存空间。
存储器扩展:通过建立虚拟存储系统来对主存容量进行逻辑扩展。虚拟存储器允许程序以逻辑方式寻址,而不用考虑物理内存的大小。如图所示。
3)文件管理
计算机系统或者嵌入式系统将程序和数据以文件的形式保存在存储介质中供用户使用。文件系统对用户文件和系统文件进行管理,保证文件的安全性,实现信息的组织、管理、存取和保护。
目录管理:文件系统为每个文件建立一个目录项,包含文件名、属性、存放位置等信息。
文件读写管理:文件系统根据用户的需要,按照文件名查找文件目录,确定文件的存储位置,然后利用文件指针进行读写操作。
文件存取控制:为了防止文件被非法窃取或者破坏,文件系统中需要建立文件访问控制机制,保证数据的安全。
存储空间管理:存储空间管理为文件分配存储空间,在文件删除后释放所占用的空间,文件存储管理提高存储空间的利用率,优化文件操作的速度。如下图所示。
4)设备管理
设备管理的主要任务是管理各类外围设备,完成用户提出的I/O请求,加快I/O信息的传送速度,发挥I/O设备的并行性,提高I/O设备的利用率;以及提供每种设备的设备驱动程序和中断处理程序,向用户屏蔽硬件使用细节。
缓冲管理:由于CPU与I/O设备的速度相差很大,通常设备管理需要建立I/O缓冲区,并对缓存区进行有效管理。
设备分配:用户提出I/O设备请求后,设备管理程序对设备进行分配,使用完成后收回设备。
设备驱动:设备驱动程序提供CPU与设备控制器间的通信。CPU向设备发出I/O请求,接收设备的中断请求,并能及时的响应。如下图:
5)作业管理
操作系统屏蔽了硬件操作的细节,用户通过操作系统提供的接口访问计算机的硬件资源。
人机交互接口:人机交互接口主要提供用户与操作系统服务之间的信息交互,包括语音、手势、命令等接口。
程序服务接口:用户获得操作系统服务的唯一途径,由一组系统调用组成。在早期的操作系统中,系统调用由汇编语言编写。
图形与界面接口:图形与界面接口提供对屏幕上的对象进行操作,完成程序控制和操作,方便用户对软硬件资源的使用。如下图:
操作系统基本概念:
1)代码的临界段
代码的临界段也称为临界区(见第2章中断部分),指处理时不可分割的代码。一旦这部分代码开始执行,则不允许任何中断打入。为确保临界段代码的执行,在进入临界段之前要关中断,而临界段代码执行完以后要立即开中断。
2)资源
任何为任务所占用的实体都可称为资源。资源可以是输入输出设备,例如打印机、键盘、显示器,资源也可以是一个变量,一个结构或一个数组等。
3)共享资源
可以被一个以上任务使用的资源叫做共享资源。为了防止数据被破坏,每个任务在与共享资源打交道时,必须独占该资源。实现资源独占的机制一般用互斥(mutual exclusion)。
4)任务及任务状态
在日常生活中,任务是指通过一定的努力,达到特定的目的或者功能;在嵌入式操作系统中,任务通常为进程和线程的统称,是内核调度的基本单元。
任务主要包含如下的几个方面:
代码 :一段可执行的程序。
数据 :程序运行相关数据,如变量、工作空间、缓存区等。
堆栈 :保存程序运行参数和寄存器内容的一段连续内存空间。
上下文环境:就是用来记录任务属性与状态的数据集。内核管理任务及处理器执行任务所需要的信息,如优先级,任务状态,处理器寄存器的内容。
在多任务环境下,各个任务被内核进行切换,在不同的状态间进行转换,如下图所示。
最常见的是将任务的运行划分为4种状态:
休眠(DORMANT):指任务驻留在存储空间内,还没有被操作系统激活;
就绪(READY):任务运行的条件已经满足,进入任务等待列表,通过调度进入运行。
挂起或等待(WAITING):任务被阻塞,等待事件的发生。
运行(RUNNING):任务获得CPU使用权,执行相应的代码。
5.)优先级
在一个嵌入式系统中每个任务被赋予一个优先级,任何两个任务的优先级都不相同。任务的优先级可以分为动态优先级和静态优先级两种类型。
(1)静态优先级
应用程序执行过程中诸任务优先级不变,则称之为静态优先级。在静态优先级系统中,诸任务以及它们的时间约束在程序编译时是已知的。
(2)动态优先级
应用程序执行过程中,任务的优先级是可变的,则称之为动态优先级。在动态优先级调度中,任务的优先级设置具有不同的方法,其中一项称之为单调执行率调度法RMS(Rate Monotonic Scheduling),用于动态分配任务优先级。
6)进程切换及调度
进程切换(process switch) - 有时称为上下文切换(context switch),或CPU寄存器内容切换。即当多进程内核决定运行另外的进程时,它保存正在运行进程的当前状态,即CPU寄存器中的全部内容。
进程切换所需要的时间取决于CPU有多少寄存器要入栈。实时内核的性能不应该以每秒钟能做多少次进程切换来评价。
(1)基于事件触发的优先级调度策略-实时操作系统
进程切换(process switch) - 有时称为上下文切换(context switch),或CPU寄存器内容切换。即当多进程内核决定运行另外的进程时,它保存正在运行进程的当前状态,即CPU寄存器中的全部内容。
多数实时内核都是基于事件触发的优先级调度算法。基于优先级调度的内核有占先式内核和非占先式内核两种类型。
不可剥夺型内核与非占先式调度:
不可剥夺型内核的异步事件由中断服务来处理。中断服务可以使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被中断了的那个任务,直到该任务主动放弃CPU的使用权时,那个高优先级的任务才能获得CPU的使用权。
不可剥夺型内核采用的调度方法称为非占先式调度。
如下图:
可剥夺型内核与占先式调度:
当一个运行着的进程或者进程运行过程中产生了中断或者进行了系统调用,CPU进入中断服务子程序或者系统调用函数,在中断服务程序或者系统调用中,使一个有更高级的进程进入就绪态,中断服务完成以后或者系统调用返回后,当前进程的CPU使用权就被剥夺,高优先级的进程立刻得到CPU的控制权,开始运行。
可剥夺型内核中,最高优先级的进程一旦就绪,总能得到CPU的控制权。如下图:
(2)基于时间片的轮转调度-非实时操作系统
分时操作系统或者软实时操作系统内核大多基于时间片轮转的调度算法。
时间片轮转调度是一种最古老、最简单、最公平且使用最广的算法。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。
进程的切换中,存在两种现象:
时间片够用,意思就是在该时间片内,进程可以运行至结束,进程运行结束之后,将进程从进程就绪等待队列中删除,然后启动新的时间片;
时间片不够用,意思是在该时间片内,进程只能完成它的一部分任务,在时间片用完之后,将进程的状态改为等待状态,将进程放到进程就绪等待队列的尾部,等待CPU的调用。
缺点:
时间片长度确定比较困难,进程切换开销比较大。如果时间片过小,则进程频繁切换,会造成CPU资源的浪费。如果时间片过大,则轮转调度算法就退化成了先来先服务算法。如下图:
7)可重入性(Reentrancy)
可重入型函数可以被一个以上的任务调用,而不必担心数据的破坏。可重入型函数任何时候都可以被中断,一段时间以后又可以运行,而相应数据不会丢失。可重入型函数或者只使用局部变量,即变量保存在CPU寄存器中或堆栈中。
不可重入型函数的例子如下列程序所示。Swap()是一个简单函数,它使函数的两个形式变量的值互换。为便于讨论,假定使用的是可剥夺型内核,中断是开着的,Temp定义为整数全程变量。
8)时钟节拍(Clock Tick)
时钟节拍是特定的周期性中断。这个中断可以看作是系统心脏的脉动。中断之间的时间间隔取决于不同的应用,一般在10ms到200ms之间。时钟的节拍式中断使得内核可以将进程延时若干个整数时钟节拍,以及当进程等待事件发生时,提供等待超时的依据。时钟节拍率越快,系统的额外开销就越大,但随着处理器时钟频率的提高,操作系统的时钟节拍周期也可以适当减小,以提高操作系统的响应速度。
9)对存储器的需求
如果设计是前后台系统,对程序存储器容量的需求仅仅取决于应用程序代码。而使用多进程内核时的情况则很不一样。内核本身需要额外的代码空间(ROM)。
代码空间总需求量由下列表达式给出。
总代码量 = 应用程序代码 + 内核代码
全局变量在编译时分配固定大小的存储空间,而局部变量和进程切换时需要的内存空间一般时通过栈空间来分配的。如果内核不支持单独中断用栈,总的RAM需求由下列式子给出。
RAM总需求 = 应用程序的RAM需求 + (进程栈需求 + 最大中断嵌套栈需求) * 进程数
2、操作系统的分类
1)实时操作系统
实时操作系统是一种能在限定的时间内对输入进行快速处理并作出响应的计算机处理系统。根据对响应时间限定的严格程度,实时系统又可分为硬实时系统和软实时系统。
硬实时系统主要用于工业生产的过程控制、较大系统的跟踪和控制、武器的制导等响应速度十分快、工作极其安全可靠的场合。
软实时系统主要应用于对响应的速度要求不象硬实时系统那么高,且时限要求也不那么严密的信息咨询和事务处理领域,如情报资料检索、订票系统、银行财务管理系统、信用卡记账取款系统和仓库管理系统等。
2)网络操作系统
网络操作系统与分布操作系统不同,不是一个集中、统一的操作系统,它基本上是在各种各样自治的计算机原有操作系统基础上加上具有各种网络访问功能的模块,这些模块使网络上的计算机能方便、有效地共享网络资源,实现各种通信服务的有关协议。
常见的网络操作系统主要有 UNIX、NOVELL、WINDOWS NT、Netware等。
3)分布式操作系统
分布式系统是一种多计算机系统,这些计算机可以处于不同的地理位置和拥有不同的软硬件资源,并用通信线路连接起来,具有独立执行任务的能力。分布式系统也便于实现文件、信息和设备的共享。
分布式系统具有一个统一的操作系统,它可以把一个大任务划分成很多可以并行执行的子任务,并按一定的调度策略将它们动态地分配给各个计算机执行,并控制管理各个计算机的资源分配、运行及计算机之间的通信,以协调任务的并行执行。
分布式操作系统(Distributed Operating System,简称DOS)负责管理分布式处理系统资源和控制分布式程序运行。它和集中式操作系统的区别在于资源管理、进程通信和系统结构等方面。
分布式操作系统有:Amoeba、Mach、Chorus、DEC等。
3、 Linux分类
当我们说Linux系统时,其含义往往是指采用Linux内核的操作系统。Linux内核负责控制硬件、管理文件系统、进程管理、网络通讯等,但它本身并没有给用户提供必要的工具和应用软件。
基于Linux内核搭配各种各样系统管理软件或应用工具软件,如GNU工具与类库,从而组成一套完整可用的操作系统。
Linux内核构成了最为关键的引擎,人们根据不同用途制作发行版通常用于特定的用途,常见的Linux发行版关系见下图。
Debian系列主要包含Debian、Ubuntu等发行版。有海量的软件支持和apt-get软件包管理系统,支持包括x86、AMD、MIPS、ARM、POWERPC等。
Fedora系列中的Linux版本包含Fedora、Red Hat Linux、Red Hat Enterprise(RHEL)、CentOS等发行版,专长x86架构的计算机。
SUSE系列中的Linux版本包含SUSE、SUSE Linux Enterprise Server(SLES)、openSUSE等发行版,SUSE主要应用于服务器。
Linux系统可以粗糙地抽象为3个层次,如图所示。底层是Linux操作系统,即系统内核(Kernel);中间层是Shell层,即命令解释层;高层则是应用层。
嵌入式Linux是将日益流行的Linux操作系统进行裁剪修改,使之能在嵌入式计算机系统上运行的一种操作系统。
嵌入式Linux应用特点:
嵌入式设备使用的处理器多种多样,而Linux系统支持运行在x86、ARM、PowerPC、MIPS等不同平台的处理器上。
Linux的代码开源、不存在黑箱技术,遍布全球的众多Linux爱好者又是Linux开发者的强大技术支持。
Linux的内核小、效率高,内核的更新速度很快,Linux是可以裁剪的,非常适合针对特定场景进行定制,其系统内核最小只有约134KB。
Linux对各种编程语言、类库、编程框架支持良好,如python、java、C++等编程语言,OpenCV、OpenGL、TensorFlow等类库和框架,使用freeRTOS等实时操作系统往往很难做到直接支持。
Linux应用程序丰富,如音乐播放器、数据库等现成的应用可以直接使用。
Linux内核的结构在网络方面是非常完整的,Linux对网络中最常用的TCP/IP协议有最完备的支持,使得编写需要联网的应用程序非常方便。
4、Linux文件系统
Linux文件系统具有良好的扩展性
支持ext、ext2、ext3、ext4、xia、vfat、minix、msdos、umsdos、 proc、smb、ncp、iso9660、sysv、hpfs、affs、ufs
每个实际文件系统从操作系统和系统服务中分离出来,它们之间通过一个接口层:虚拟文件系统或VFS来通讯。VFS使得Linux可以支持多个不同的文件系统,每个表示一个VFS 的通用接口。
1)Jffs文件系统主要包括JFFS1、JFFS2和JFFS3: 日志闪存文件系统版本主要用于NOR型闪存,基于MTD驱动层。
JFFS1:
JFFS2:可读写的、支持数据压缩的、基于哈希表的日志型文件系统,并提供了崩溃/掉电安全保护,提供“写平衡”支持等
JFFS3: JFFS3针对JFFS2不是应用与大容量闪存的缺点,将索引树数据从主存移动到了闪存,改进了磨损平衡机制。
2)YAFFS针对NAND FLASH设计,和JFFS相比它减少了一些功能,所以速度更快,挂载时间很短,对内存的占用较小。自带NAND芯片驱动,并为嵌入式系统提供了直接访问文件系统的API。
YAFFS2是YAFFS的改进版本
YAFFS仅支持小页(512B) NAND闪存, YAFFS2则可支持大页(2KB) NAND闪存;
YAFFS2在内存空间占用、垃圾回收速度、读/写速度等方面均有大幅提升。
3)CRAMFS文件系统是专门针对闪存设计的只读压缩的文件系统,其容量上限为256M,采用zlib压缩,文件系统类型可以是EXT2或EXT3.
在Cramfs文件系统中,每一页(4KB)被单独压缩,可以随机页访问,其压缩比高达2:1,为嵌入式系统节省大量的Flash存储空间,使系统可通过更低容量的FLASH存储相同的文件,从而降低系统成本。
但是它的只读属性同时又是它的一大缺陷,使得用户无法对其内容对进扩充。
文件系统的重要数据结构: