1、第5章 Linux内核简介,主要内容Linux核心的一般结构 进程的概念、进程的调度和进程通信 文件系统的构成和管理 内存管理 设备驱动及中断处理,5.1 概 述,Linux系统大致可分为三层: 靠近硬件的底层是内核,即Linux操作系统常驻内存部分。 中间层是shell层,即操作系统的系统程序部分。 最高层是应用层,即用户程序部分,内核是Linux操作系统的主要部分,实现进程管理、内存管理、文件系统、设备驱动和网络系统等功能。,Linux操作系统的心脏内核,区分用户态和内核态目的在于安全考虑:禁止用户程序和底层硬件直接打交道(最简单的例子,如果用户程序往硬件控制寄存器写入不恰当的值,可能导致
2、硬件无法正常工作)禁止用户程序访问任意的物理内存(否则可能会破坏其他程序的正常执行,如果对内核所在的地址空间写入数据的话,会导致系统崩溃),用户程序如何同设备打交道?,例如,用户需通过网卡发送数据硬件被linux 内核隔离,只能通过内核实现。 不可能直接调用操作系统的函数:不可行,也不安全。Linux提供的解决方法:系统调用,系统调用的意义,操作系统为用户态进程与硬件设备进行交互提供了一组接口系统调用 把用户从底层的硬件编程中解放出来 极大的提高了系统的安全性 使用户程序具有可移植性,trap 0,系统调用图解,Linux内核体系结构,内核的核心进程,Fork()创建新进程 ,是父进程的一个克
3、隆 Exec()新进程脱胎换骨,离家独立,开始了独立工作的职业生涯,父子孙共存的系统必然是一个并发的系统,5.2.1 进程和线程的概念 5.2.2 进程的结构 5.2.3 对进程的操作 5.2.4 进程调度 5.2.5 shell基本工作原理,5.2 进 程 管 理,5.2.1 进程和线程的概念,1进程及其状态 简单说来,进程就是程序的一次执行过程。 进程至少要有三种基本状态:运行态、就绪态和封锁态(或等待态)。 进程的状态可依据一定的条件和原因而变化,进程状态转换图,TASK_DEAD ( EXIT_ZOMBIE或EXIT_DEAD),TASK_INTERRUPTIBLE or TASK_U
4、NINTERRUPTIBLE or TASK_KILLABLE,进程的模式和类型 在Linux系统中,进程的模式划分为用户模式和内核模式; 按照进程的功能和运行的程序来分,进程划分为两大类:系统进程、用户进程,若当前运行的是用户程序、应用程序或者内核之外的系统程序,则在用户模式下运行。,在用户程序执行过程中,如果使用了系统调用,或者发生了中断,就要运行操作系统程序,进程模式变为内核模式。,系统进程只运行在内核模式,用户进程可以在用户模式和内核 模式下运行,4Linux线程线程和进程是紧密相关的概念,一般来说,Linux系统中的进程应具有一段可执行的程序、专用的系统堆栈空间、私有的“进程控制块”
5、、独立的存储空间。 而Linux系统中,线程只具有前3个组成部分,缺少自己的存储空间。,5.2.2 进程的结构,包含下列几方面的信息:进程状态调度信息 标志符内部进程通讯链接信息时间和计时器文件系统虚拟内存处理器信息,1、task_struct结构,Linux系统中的每个进程都有一个名为task_struct的数据结构,它相当于“进程控制块”; 在进程被创建时,系统从内存中分配一个task_struct的数据结构。,2进程系统堆栈 每个进程都有一个系统堆栈,用来保存中断现场信息,以及进程进入内核模式后的返回现场信息; 系统堆栈和task_struct数据结构之间存在紧密联系,二者物理存储空间也
6、连在一起 系统堆栈的大小静态确定。,5.2.3 对进程的操作,1进程的创建各个进程构成了树形的进程族系; 内核在完成了基本的初始化以后,就有了系统的第一个进程(即初始化进程); 所有其他的进程和内核线程都由这个原始进程或其子孙进程所创建。,进程是有“生命期”的动态过程,包括创建、撤销、挂起、恢复等等。,2进程的等待,父进程创建子进程,往往是让子进程替自己完成某项工作,因此,创建之后,父进程通常需要等待子进程运行结束; 父进程可用系统调用wait( )等待它的子进程终止;,3进程的终止进程可使用系统调用exit( )终止自己; 其实现算法如下: (1)撤消所有的信号量。 (2)释放其所有的资源,
7、包括存储空间、已打开的文件、工作目录、信号处理表等。 (3)置进程状态为“终止态”(TASK_ZOMBIE)。 (4)向它的父进程发送子进程终止的信号。 (5)执行进程调度。,5.2.4 进程调度,调度算法 调度时机 进程切换,进程调度系统有条不紊的使者,任何程序要占用CPU,真正处于执行状态,就必须经由进程调度; 进程调度机制要兼顾以下三种不同进程的需要:,交互进程:需要经常响应用户操作,着重于系统的响应速度,使得共有一个系统的各个用户,都感到自己在独占系统,典型的交互程序有shell,文本编辑器; 批处理进程:也称作“后台作业”,在后台运行,对响应速度无要求,只考虑“平均速度”,如:编译程
8、序、科学计算等; 实时进程:对时间有很高要求,不仅考虑平均速度,还对完成任务的时间限制有要求。,进程调度机制主要涉及到调度方式、调度时机和调度策略1调度方式 Linux内核的调度方式,基本上采用“抢占式优先级”,即:当进程在用户模式下运行时,在一定条件下(如:时间片用完),内核调度其他进程进入运行;在选择其他进程时以优先级为基础,即: 系统中的每个进程都有个优先权,反映了该进程可以获得CPU使用权的资格; 从进程就绪队列中选择一个优先权最高的进程,为其分配一个CPU时间片; 运行过程中,当前进程的优先级随时间递减,从而经过一段时间后,以前优先级较低的进程就相对“提升”了优先级,有机会运行; 当
9、所有进程优先级都变为0时,就重新计算一次优先级。,2调度策略三种不同的调度策略 SCHED_FIFO适合于短实时进程,对时间性要求比较强,每次运行所需时间较短; SCHED_RR适合于运行时间较长的实时进程,也叫“时间片轮转法” 。当时间片用完时,该进程被送回相同优先级队列的末尾,因此,进程从创建到完成需要经过多次循环调用; SCHED_OTHER适合于交互式的分时进程,这类进程的优先权取决于两个因素:1、进程剩余时间配额:若已经用完配给的时间,则优先权为02、进程的优先数:沿袭UNIX的方法,3调度的时机:有以下情况:当前进程使用系统调用,使自己进入睡眠状态,主动让出一段时间的CPU使用权。
10、 进程终止,永久地放弃对CPU的使用。 当唤醒一个睡眠进程时,发现被唤醒的进程比当前进程更有资格运行。 一个进程通过执行系统调用,来改变调度策略或者降低自身的优先权,从而引起立即调度。,4调度算法,调度算法比较简单,以便减少频繁调度时的系统开销。Linux执行系统调度时: 首先查找所有就绪队列中的进程,选出优先级最高、且在内存的一个进程; 如果队列中有实时进程,那么将优先运行; 如果需要运行的进程不是当前进程,那么当前进程就被挂起,并且保存它的现场, 然后为选中的进程恢复其运行现场;,5.2.5 shell基本工作原理,Linux系统提供给用户的最重要的系统程序是shell命令,它不属于内核部
11、分,基本功能是解释并执行用户输入的各种命令,实现用户与Linux内核的接口。 系统初次启动后,系统为每个终端用户建立一个进程,以执行shell解释程序。,最简单也是最复杂的操作,在控制台下输入ls命令,Shell程序分析输入参数,确定这是ls命令,调用系统调用fork生成一个子进程,什么是系统调用?,为什么我们敲击键盘就会在终端上显示?,中断的概念,终端控制台设备驱动,内核态用户态相关问题,系统调用是怎么实现的?,软中断、异常的概念,调用execve系统调用将ls的可执行文件装入内存,内存管理,进程的地址空间,分页机制,文件系统,从系统调用返回,如何做到正确的返回?,堆栈的维护,寄存器的保存与
12、恢复,Ls命令得以执行,进程的调度,运行队列等待队列的维护,什么是shell?,终端解释程序,shell命令的基本执行过程,5.3 文 件 系 统,Linux系统的一个重要特征,就是支持多种不同的文件系统,如:ext, FAT, ext2, ext3, MINIX, MS DOS, SYSV等。 目前,Linux主要使用的文件系统是ext3。ext3是ext2的升级版本,其主要优点是:在ext2的基础上加入了记录数据的日志功能。,5.3.1 ext2文件系统 5.3.2 虚拟文件系统,5.3.1 ext2文件系统,1ext2文件系统的物理结构,与其他文件系统一样,文件信息都保存在数据块中, 所
13、有数据块的大小都是一样的,如图所示:,介质上的第一个数据块,只有根文件系统才有引导程序,2块组的构造包含超级块、组描述结构、块位图、索引节点位图、索引节点表和数据块。(1)超级块(Superblock) 超级块中包含有文件系统本身的大小和形式的基本信息。例如:块组号码 、数据块大小 、每组数据块的个数、空闲块 、空闲索引节点 、第一个索引节点 (2)块组描述结构(Block Group Descriptor) 每个数据块组都有一个描述它的数据结构,即块组描述结构。,3索引节点(Inode)每个文件都有惟一一个索引节点,起着文件控制块的作用,利用这种数据结构可对文件进行控制和管理。索引节点有两种
14、形式:盘索引节点、内存索引节点,4多重索引结构,如果文件索引表很大,则把索引表整个放在内存中是不合适的,在使用过程中很可能需要扩充空间; 此外,单一索引表已经无法满足灵活性和节省内存的要求; 为此,提出多重索引结构,采用间接索引的方式,进行几级寻址,最末尾的数据块中存储文件具体内容;,ext2文件系统的物理结构,盘块,盘块,盘块,盘块,盘块,文件系统在查找文件时,根据路径名和文件名,搜索对应的索引节点,找到该文件的数据块;,ext2中的目录项当创建一个文件时,就构成一个目录项,并添加到相应的目录文件中。 一个目录文件可以包含很多目录项,每个目录项包含的信息有:,索引节点号 目录项长度 名字长度
15、 文件类型 文件名字,例如:要读取文件/home/meng/m1.c,文件系统首先按照超级块中根目录的索引节点,找到根目录的数据块,从中找到表示home文件的目录项,得到相应索引节点的号码; 接着在节点中找到存放home数据块的地址,从中找到meng对应的目录项,得到相应的索引节点号码; 再由meng目录文件中获取m1.c文件的索引节点号码,通过这个节点就可以访问m1.c文件。,进程控制块使用文件时的逻辑结构,Linux系统中每个进程控制块都有两个数据结构,用来描述进程与文件相关信息。,两个指针,根目录 节点,当前目 录节点,保存该进程打开文件的有关信息。最多打开256个文件,第四章中I/O重
16、定向中讲到的文件描述符(如:0,1,2)就是fd数组的下标,索引节 点表,文件的打开在进程与文件之间建立起连接。,6位示图,每个块组中包含一个块位示图,和一个索引节点位示图,位示图管理块组的数据块,具体方法是: 利用一串二进位的值来反映该块组中数据块的分配情况, 也称作位向量(Bit Vector)法。 0表示空闲,1表示已分配。例如:设下列数据块是空闲的: 2,3,4,5,8,9,10,11,12,13,17,18,25,26,27,. 则,块位示图的表示为:100001100000011100111111000.,5.3.2 虚拟文件系统,Linux系统可以支持多种文件系统,为此,必须使用
17、一种统一的接口,这就是虚拟文件系统VFS(Virtual File System).,VFS是一个软件层,是用户应用程序与具体文件系统实现之间的抽象层:对用户界面:一组标准的、抽象的文件操作,以系统调用提供,如read()、write()、open()等。对具体文件系统界面:主体是file_operations结构,全是函数指针,提供函数跳转表。,虚拟文件系统抽象的体现,用户程序,虚拟文件系统VFS,Minix,Ext2,FAT,设备文件,文件系统的系统调用接口,包括read()、write()、open()、close()等,用户空间 内核空间 系统调用对应的内核函数sys_read() 等
18、支撑VFS的具体文件系统,VFS在一个简单文件复制操作中的作用,假设用户输入shell命令:$ cp /floppy/TEST /tmp/test 在cp命令中,通过VFS提供的系统调用接口进行文件操作。,VFS支持的文件系统类型,VFS支持三种主要类型的文件系统: 基于磁盘的文件系统:管理在本地磁盘分区中可用的存储空间。 包括:ext2、ext3、ReiserFS、 MINIX、 MS-DOS、 NTFS 、 VFAT 、 DVD文件系统、 JFS 等等 网络文件系统:用于访问属于其他网络计算机的文件系统所包含的文件 NFS、Coda、AFS、SMB、NCP 特殊文件系统,文件系统的安装与拆
19、卸,在系统初启时,往往只有一个文件系统安装上,即:根文件系统,主要包括: 保证系统正常运行的操作系统代码文件,以及语言编译程序、命令解释程序、命令处理程序、以及用户文件; 根文件系统一旦安装上,则在整个系统运行过程中是不能卸载的; 其他的文件系统(例如,由软盘构成的文件系统),可以根据需要(如从硬盘向软盘复制文件),作为子系统动态地安装到主系统,f2是为了安装子文件系统而预留的安装节点; 安装之后,主文件系统和子文件系统构成一个有完整目录层次、容量更大的文件系统,VFS有下列主要对象类型:超级块对象(superblock ) 存放文件系统相关信息:例如文件系统控制块 索引节点对象(inode
20、) 存放具体文件的一般信息:文件控制块/inode 目录项对象(dentry ) 存放目录项与文件的链接信息 文件对象(file ) 存放已打开的文件和进程之间交互的信息,VFS索引节点缓存和目录缓存,为了加快对系统中所有已经安装文件系统的存取,VFS提供了索引节点缓存把当前使用的索引节点保存在高速缓存中。 为了能够很快地从中找到所需的VFS索引节点,采用散列(hash)方法。其基本思想是:,为了加速对常用目录的存取,VFS还提供目录高速缓存;当文件系统读取一个目录时,就把目录的详细信息加入到目录缓存中,下一次查找该目录时,就可以直接从缓存中找到该目录的详细信息; 目录缓存也采用散列表的方法进
21、行管理:表中每一项都是一个指针,指向有相同散列值的目录缓存队列。,Linux系统采用多重缓冲技术,来平滑和加快文件信息从内存到磁盘的传输; 一个缓冲区由两部分组成:存放数据的缓冲区和一个缓冲控制块; 所有处于“空闲”状态的buffer_head 都链入自由链中,它只有一条。 具有相同散列值的缓冲区组成一条散列队列.,数据块缓冲区,5.4 内 存 管 理,近年来,随着硬件技术和生产水平的迅速发展,内存的成本迅速降低,容量也不断扩大; 但是,仍然不能满足各种软件对存储空间的需求,因此,内存的有效管理仍是现代操作系统研究的重点问题。 Linux系统采用了虚拟内存管理机制,就是交换和请求分页存储管理技
22、术:,虚拟内存管理:,地址映射机制 请页机制 内存分配和回收机制交换机制 缓存和刷新机制,物理内存有限,是一种稀缺资源 32位系统中,每个进程独立的占有4G虚拟空间。 虚拟内存优势: 用户程序开发方便 保护内核不受恶意或者无意的破坏 隔离各个用户进程,物理内存获取过程:用户程序请求物理内存 内核分配物理页面 内核填写对应页表项 用户程序获得物理内存从这个过程看出,内存管理的核心内容是:物理页面分配 和 所有进程页表的维护,即:物理内存管理 和 虚拟空间管理。,逻辑空间分页:进程的逻辑地址空间划分为大小相等的页面; 内存空间分页:内存也划分成相同大小的存储块; 逻辑地址表示:地址结构如图所示:,
23、5.4.1 请求分页机制,1、分页的概念,内存分配原则:以内存块为单位分给进程,并且进程的页面可以装在物理上不连续的内存块中。 页表:由于页号连续,而块号不一定连续,为了找到进程的每个页面对应内存中的物理块号,为每个进程建立页表。,可知页面大小为:212=4K,请求分页存储管理示意图,Linux进程的虚存空间,3Linux的多级页表,每个进程的虚拟存储空间可达4GB,分为两个部分:系统空间1G + 用户空间3G,所有进程共享系统空间,Linux系统中页面大小为4K,因此,进程的虚存空间要划分为4G/4K=220个页面,Linux系统采用两种方法来管理内存页: 位图:记录内存单元的使用情况 链表
24、:记录已分配的内存单元和空闲的内存单元采用双向链表结构将内存单元连接起来,可以加速空闲内存的查找,或链表处理操作。,4内存页的分配与释放,空闲内存的组织示意图,项0:单个空闲内存页信息; 项1:以两个连续内存页为一组的页组信息; 项2:以四个内存页。 页组中内存页的数量依次按2的倍数递增,每个页组的起始内存编号。,记录相应页组的分配情况,释放的时候检查是否有与之相邻的空闲页,如果有,则组合成一个大的空闲页组。,5.4.2 内存交换,当出现内存不足时,Linux内核中的内存管理子系统调用交换守护进程kswapd,释放一些内存页; 进程kswapd有自己的进程控制块task_struct结构,但是
25、,它没有自己独立的地址空间,只使用系统空间;所以也把它称为线程,其任务就是保证系统中有足够的空闲内存页; 当系统启动时,交换守护进程由内核的init(初始化)进程启动,并进入无限循环,每次循环末尾进入睡眠,内核在一定时间之后,唤醒并调度该进程使之运行。,交换守护进程的工作主要分为两部分:1、若发现可用内存页出现短缺,则将若干不常用的活跃内存页面变为不活跃状态;2、清理不活跃的“脏”页面(即:内存页上的内容与盘上内容不一致),将其写入交换设备,或回收一些内存页,使之成为空闲的内存页。,5.5 进 程 通 信,系统中的进程与内核之间,以及不同的进程之间,需要进行通信和协调,最常用的通信方式是: 信
26、号机制 管道文件 System V IPC(内部进程通信)机制本节只介绍上述方法的基本实现思想,1信号概念,5.5.1 信号机制,信号(signal,称为软中断)机制:是在软件层次上对中断机制的一种模拟。 异步进程可以通过彼此发送信号来实现简单通信。,接收信号的进程,在运行过程中检测自身是否收到信号; 若收到信号,则转去执行预先规定好的信号处理程序; 再返回原先正在执行的进程。,3进程对信号可采取的处理方式,进程间可用系统提供的系统调用发送信号; 除了内核和超级用户之外,并不是每个进程都可以向其他进程发送信号;普通进程只能向具有相同uid和gid的进程发送信号。,5.5.2 管道文件,由系统自
27、动处理上述两个进程间的同步、调度和缓冲。 管道文件允许两个进程按先入先出(FIFO)的方式传送数据。,例如:$grep m?.c | wc l 执行上述命令时,就要创建一个管道文件,和两个进程: 命令grep m?.c对应一个进程,向管道文件中写入信息,称为“写进程”; 命令wc l对应另一个进程,从管道文件中读取信息,称为“读进程”,管道的实现机制,每个进程最多可以打开256个文件,每个文件对应一个file结构。f_inode表示VFS中该文件的索引结点。,5.6 设 备 管 理,设备管理是操作系统管理的最复杂的部分; Linux系统采用设备文件统一管理硬件设备,从而将设备的硬件特性和管理细
28、节隐藏起来,实现用户程序与设备的无关性; Linux系统中,硬件设备分为:块设备、字符设备和网络设备。,5.6.1 设备管理概述,每个设备都对应文件系统中的一个索引节点,都有一个文件名,对设备的使用类似于对文件的存取; 应用程序通常可以通过系统调用open( )打开设备文件,建立起与目标设备的连接; 大多数Linux设备驱动程序都可以在需要时装入内核,不需要时卸载下来。,用户是通过文件系统与设备交互的,所有设备都作为特别文件,从而在管理上就具有下列共性:,字符设备 用户对字符设备(如:打印机、终端)的使用就和存取普通文件一样。在应用程序中使用标准的系统调用来打开、关闭、读写字符设备。,字符设备驱动程序示意图,字符设备初始化时,驱动程序被添加到device_struct结构组成的chrdevs数组中。,全部是函数指针,指向实现文件操作的入口函数。,Linux操作系统内核分析 深入分析Linux内核源代码 Understanding The Linunx Kernel Linunx Kernel Development Linxu操作系统原理与应用,参考书:,