linux操作系统分析-课程学习报告总结
前言
请您根据本课程所学内容总结梳理出一个精简的Linux系统概念模型,最大程度统摄整顿本课程及相关的知识信息,模型应该是逻辑上可以运转的、自洽的,并举例某一两个具体例子(比如读写文件、分配内存、使用I/O驱动某个硬件等)纳入模型中验证模型。谈谈您对课程的心得体会,改进建议等。
一、精简的Linux系统概念模型
Linux系统一般有4个主要部分:内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。
Linux系统一般有4个主要部分:内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。

Linux体系结构可以分为两块:
(1)用户空间:用户空间中包含了,用户的应用程序,C库
(2)内核空间:内核空间包括系统调用,内核,以及与平台架构相关的代码
Linux系统的核心是内核。内核控制着计算机系统上的所有硬件和软件,在必要时分配硬件,并根据需要执行软件。内核主要负责以下四种功能:
- 系统内存管理
- 软件程序管理
- 硬件设备管理
- 文件系统管理
二、进程管理
1、进程的描述
在操作系统原理中,我们通过进程控制块PCB描述进程。为了管理进程,内核要描述进程的结构,我们也称其为进程描述符,进程描述符直接或间接提供了进程相关的所有信息。
在Linux内核中⽤⼀个数据结构struct task_struct来描述进程。struct task_struct的结构包括了进程的状态、进程双向链表的管理,以及控制台tty、⽂件系统fs的描述、进程打开⽂件的⽂件描述符fifiles、内存管理的描述mm,还有进程间通信的信号signal的描述等内容,十分庞大繁杂。值得一提的是,task_struct数据结构的最后是保存进程上下⽂中CPU相关的⼀些状态信息的关键数据结构thread。struct thread_struct数据结构内部最关键的是sp和ip。sp⽤来保存进程上下⽂中的ESP寄存器状态,ip⽤来保存进程上下⽂中的EIP寄存器状态。
2、进程的状态
操作系统原理中的进程有就绪态、运⾏态、阻塞态这3种基本状态,实际的Linux内核管理的进程状态则与原理稍有出入,如原理中的就绪态和运行态,在linux中都是TASK_RUNNING态。在Linux中,进程的状态划分比原理更加复杂,如终止态中又多了僵尸态;阻塞态也有两种:TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE。
3、进程调度
先到先服务算法、最短作业优先调度、优先级调度、 轮转法调度、多级队列调度、多级队列反馈调度等。一个进程的上下文(context)包括进程的状态、有关变量和数据结构的值、机器寄存器的值和PCB以及有关程序、数据等。一个进程的执行是在进程的上下文中执行。当正在执行的进程由于某种原因要让出处理机时,系统要做进程上下文切换,以使另一个进程得以执行。当进行上下文切换时系统要首先检查是否允许做上下文切换(在有些情况下,上下文切换是不允许的,例如系统正在执行某个不允许中断的原语时)。然后,系统要保留有关被切换进程的足够信息,以便以后切换回该进程时,顺利恢复该进程的执行。在系统保留了CPU现场之后,调度程序选择一个新的处于就绪状态的进程、并装配该进程的上下文,使CPU的控制权掌握在被选中进程手中。
系统调用的过程:

- 应用程序代码调用系统调用xyz,该函数是一个包装系统调用的库函数xyz;
- 库函数xyz负责准备向内核传递的参数,并触发软中断以切换到内核态;
- CPU 被软中断打断后,执行中断处理函数 ,即系统调用处理函数system_call;
- 系统调用处理函数调用系统调用服务例程sys_xyz,真正开始处理该系统调用。
三、中断管理
内核的一个主要功能就是处理硬件外设I/O,中断信号提供了一种特殊的方式, 使得CPU转去运行正常程序之外的代码,中断会改变处理器执行指令的顺序, 通常与CPU芯片内部或外部硬件电路产生的电信号相对应。
初始化过程:
- 系统加载 start_kernel 开始,调用了 trap.c 中的 trap_init()函数对 中 断 进 行 初 始 化 。 并且调用同一文件下的set_trap_gate()/set_system_gate()/set_intr_gate()等对中断描述符进行初始化。
- 在进入保护模式之前, IDT 再次通过 setup_idt()函数进行初始化,在这里使用了 ignore_int()函数,是为了保护未初始化完成时发生异常不出错。 然后调用 init_IRQ()函数,把中断描述附表的中断处理代码段地址设在在 interrupt 数组中,该数组指向同一个函数处理 common_interrup。
明确中断发生时, CPU 硬件级的中断信号处理过程 :
1. 确定与中断或异常相关联的向量 i
2. 读取 idtr 寄存器的值,找到 IDT 的基址,通过查询 IDT,找到第 i 项对应的内容。
3. 从 gdtr 寄存器获得 GDT 的基地址,并在 GDT 中查找,以读取IDT 表项中的段选择符所标识的段描述符。
4. 确定中断是由授权的发生源发出的。
中断:需要比较 CPL 和 GDT 中的 DPL。中断处理程序的特
权不能低于引起中断的程序的特权。
编程异常:需要比较 CPL 和 IDT 中的 DPL。
5. 检查是否发生了特权级的变化,一般指的是用户态陷入内核态。
如果是用户态陷入内核态,控制单元要使用新的特权级堆栈。
保存 ss 和 esp,并用新的堆栈的值填充。
6. 如果是故障,用引起故障的指令修改 cs 和 eip,以便异常处理后再次执行。
7. 在堆栈中保存 eflags/cs/eip 的内容。
8. 如果有硬件出错码,则保存。
9. 使用 IDT 中第 i 项中的段描述符和偏移量填充 cs 和 eip。

四、文件系统
1、简介
在LINUX系统中有一个重要的概念:一切都是文件。 其实这是UNIX哲学的一个体现,而Linux是重写UNIX而来,所以这个概念也就传承了下来。在UNIX系统中,把一切资源都看作是文件,包括硬件设备。UNIX系统把每个硬件都看成是一个文件,通常称为设备文件,这样用户就可以用读写文件的方式实现对硬件的访问。这样带来优势也是显而易见的:UNIX 权限模型也是围绕文件的概念来建立的,所以对设备也就可以同样处理了。
2、文件打开:
- 应用程序对open ( )的调用将引起内核调用服务例程sys_open ( )函数,该函数接收的参数为:要打开文件的路径名和访问模式等;
- 该系统调用成功后将返回一个文件描述符,也就是文件对象指针数组的一个索引;
- 系统调用不成功时返回-1。
3、文件关闭
- 用户程序通过close ( )系统调用关闭打开的文件,该函数接收的参数为要关闭文件的文件描述符。
- 内核服务例程为sys_close ( )函数。
4、读文件流程
- 进程调用库函数向内核发起读文件请求;
- 内核通过检查进程的文件描述符定位到虚拟文件系统的已打开文件列表表项;
- 调用该文件可用的系统调用函数read()。read()函数通过文件表项链接到目录项模块,根据传入的文件路径,在目录项模块中检索,找到该文件的inode;
- 在inode中,通过文件内容偏移量计算出要读取的页;
- 通过inode找到文件对应的address_space;
- 在address_space中访问该文件的页缓存树,查找对应的页缓存结点:
- 如果页缓存命中,那么直接返回文件内容;
- 如果页缓存缺失,那么产生一个页缺失异常,创建一个页缓存页,同时通过inode找到文件该页的磁盘地址,读取相应的页填充该缓存页;重新进行第6步查找页缓存;
- 文件内容读取成功。
5、虚拟文件系统
- 是 Linux 内核中的一个软件层,用于给用户空间的程序提供文件系统接口;
- 同时,它也提供了内核中的一个抽象功能,允许不同的文件系统共存。
- 系统中所有的文件系统不但依赖 VFS 共存,而且也依靠 VFS 协同工作。
- 为了能够支持各种实际文件系统,VFS 定义了所有文件系统都支持的基本的、概念上的接口和数据 结构;
- 同时实际文件系统也提供 VFS 所期望的抽象接口和数据结构,将自身的诸如文件、目录等概念在形式 上与VFS的定义保持一致。一个实际的文件系统想要被 Linux 支持,就必须提供一个符合VFS标准 的接口,才能与 VFS 协同工作。实际文件系统在统一的接口和数据结构下隐藏了具体的实现细节,所以在VFS 层和内核的其他部分看来,所有文件系统都是相同的。

Linux课程总结
在Linux系统分析这门课程中,通过内核源代码和知识点结合的方式学习Linux,在实验中通过自己动手运行和调试内核,知晓了操作系统内核的结构和设计原理,一个操作系统是如何运作起来的,系统的各个功能之间是如何分工协作的,这让课程不仅仅是停留在理论阶段,学完之后加深了对操作系统的理解。希望老师能加一点对知识点的总结和联系,这样更有利于对知识的串联和理解。
浙公网安备 33010602011771号