Linux系统分析 课程学习总结报告

Linux系统分析 课程学习总结报告

请您根据本课程所学内容总结梳理出一个精简的Linux系统概念模型,最大程度统摄整顿本课程及相关的知识信息,模型应该是逻辑上可以运转的、自洽的,并举例某一两个具体例子(比如读写文件、分配内存、使用I/O驱动某个硬件等)纳入模型中验证模型。谈谈您对课程的心得体会,改进建议等。出要求是发表一篇博客文章,长度不限,只谈自己的思考,严禁引用任何资料造成文章虚长。

概念模型

​ 操作系统是管理计算机硬件与软件资源的计算机程序。

​ Linux内核主要包含了五大模块:进程调度模块进程间通信模块内存管理模块文件系统模块网络接口模块

​ 我们课程主要学习了其中的进程调度、文件系统、内存管理。

​ 进程调度模块主要是对进程使用的处理机进行管理和控制。Linux以进程作为系统资源分配的基本单位,并采用动态优先级的进程高级算法,保证各个进程使用处理机的合理性。使用的调度策略有:先进先出的实时进程、时间片轮转的实时进程、普通的分时进程

​ Linux 的文件系统模块采用了虚拟文件系统(VFS),屏蔽了各种文件系统的差别,为处理各种不同的文件系统提供了统一的接口,支持多种不同的物理文件系统。同时,Linux把各种硬件设备看作一种特殊的文件来处理,用管理文件的方法管理设备,非常方便、有效。

​ Linux的内存管理模块采用了虚拟存储机制,实现对多进程的存储管理,使得每个进程都有各自互不干涉的进程地址空间。


​ 具体一点描述如下。Linux自启动以来,由0号进程创建其他所有进程,这些进程或是由用户输入形成,或是系统运行所必需,所有进程井然有序地共享一个cpu,不停完成用户所需要的计算。

进程调度

​ 进程是Linux系统下资源管理的基本单位。每一个进程都有自己的独立的执行空间。 进程资源由两部分组成:内核空间进程资源以及用户空间进程资源

​ 内核空间进程资源:指的就是PCB相关信息。包含进程控制块本身、打开的文件表项、当前文件夹、当前终端信息、线程基本信息、可访问内存地址、PID、PPID、UID、EUID等,也就是说内核通过PCB能够访问到进程全部的资源。这些资源仅仅能通过系统调用才能访问到。

​ 用户空间进程资源:通过成员mm_struct映射的内存空间。实质就是进程的代码段、数据段、堆、栈、以及能够共享访问的库的内存空间。这些资源进程能够直接访问。


​ 用户级进程拥有下面几种状态:就绪/执行状态(TASK_RUNNING)、等待状态(能够被中断打断TASK_INTERRUPTIBLE)、等待状态(不能够被中断打断TASK_UNINTERRUPTIBLE)、僵死状态(TASK_ZOMBIE)。几种状态之间的转换如下图:

TASK_RUNNING:正在运行或处于就绪状态:就绪状态是指进程申请到了CPU以外的其它全部资源。

TASK_INTERRUPTIBLE:处于等待队伍中,等待资源有效时唤醒(比方等待键盘输入、socket连接、信号等等),但能够被中断唤醒。

TASK_UNINTERRUPTIBLE:处于等待队伍中,等待资源有效时唤醒(比方等待键盘输入、socket连接、信号等等),但不能够被中断唤醒。

TASK_ZOMBIE:僵死状态。进程资源用户空间被释放,但内核中的进程PCB并没有释放。等待父进程回收。


进程调度时机如下:

  1. 进程状态发生变化时
  2. 当前进程时间片用完
  3. 进程从系统调用返回到用户态时
  4. 中断处理后,进程返回到用户态时

文件系统

​ 文件系统的结构包括在磁盘上的结构和在内存中的结构。磁盘上包括引导控制块、盘控制块、目录结构、FCB。在内存中包括:

  • 系统打开文件表:包含每个已打开文件的FCB的副本,以及其他信息。
  • 进程打开文件表:包含一个指向系统打开文件表相应项的指针,以及其他信息。

​ file结构一方面可从f_dentry链接到目录项模块以及inode模块,获取所有和文件相关的信息,另一方面链接file_operations子模块,其中包含所有可以使用的系统调用函数,从而最终完成对文件的操作。


内存管理

​ Linux把进程地址空间分成内核区和用户区两部分。内核的内存部分是程序的无法访问的,但内核本身可以读取程序的内存。这是将数据传递给内核函数的方法之一。

代码段:构成程序的可执行文件和库。主可执行文件及其所有库都被加载到进程的地址空间中,因此它们的所有的函数都具有内存地址。
数据段:程序用来存储它正在处理的数据的内存,通常称为堆。例如,这可以用于存储当前正在编辑的文档、正在查看的网页或者正在播放的游戏。
栈段:进程中的每个线程可以共享代码段和数据段,但是都有自己的堆栈段。栈段是一块内存,用于跟踪线程当前正在运行的函数,以及所有父函数 - 被调用以获取当前函数的函数。


​ 当在内核态申请内存时直接给分配,而进程在用户态申请内存时,只是给了一个新的线性地址空间的一个使用权,真的要用的时候会产生缺页异常,然后再真的分配。请求调页是一种动态内存分配技术,它把页框的分配推迟到不能再推迟为止。与之相关的分配页框的方式为写时复制:父子进程是共享页框的,当读的时候,不分配新的页框。当写的时候,谁写就给谁分配,两者各自过运行一段时间都就都有了自己的空间。


读文件实例

  1. read执行去C库里面,找到Int80 03指令封装。80为中断向量号,03为系统调用号;

  2. 从idtr寄存器中读取中断向量表的基地址,找到IDT;

  3. trap-init调用set_system_gate等函数对中断向量表中的每一项进行初始化,并将指令所在地址的cs、eip、DPL以及门类型和中断向量号进行绑定;

  4. 根据中断向量号128找到第128项,其中包括cs和eip,再根据gdtr、cd、eip找到所要执行指令的地址,再进行系统调用;

  5. 进入系统调用,保存现场,对指令进行分析得到系统调用号05根据系统调用号,找到系统调用表中的sys_read的入口,即sys_read的函数指针;

  6. sys_read()函数通过文件表项链接到目录项模块,根据传入的文件路径,在目录项模块中检索,找到该文件的inode;

  7. 在inode中,通过文件内容偏移量计算出要读取的页;

  8. 通过inode找到文件对应的address_space;

  9. 在address_space中访问该文件的页缓存树,查找对应的页缓存结点:

    • 如果页缓存命中,那么直接返回文件内容;

    • 如果页缓存缺失,那么产生一个页缺失异常,创建一个页缓存页,同时通过inode找到文件该页的磁盘地址,读取相应的页填充该缓存页;重新进行第6步查找页缓存;

  10. 文件内容读取成功。

心得体会与建议

​ 总的来说,这一门课的学习,让本来对Linux系统不怎么熟悉的人,不仅掌握了Linux的一些基本操作,也对Linux内在的原理有了比较深入的理解。

​ 再说说两位老师的上课情况。两位老师的课程内容侧重点有很大的不同,孟老师注重实验,李老师注重原理。所以每次上完课,基本都会觉得孟老师讲的内容更容易理解,觉得李老师将的内容稍微晦涩一些。但在最近的复习阶段,把李老师讲的内容都融汇到一起看,条理还是很清晰的。

​ 所以这里就有一点建议,就是这门课只有在孟老师讲课的部分布置了一些作业,而李老师讲课的时候大家都只是听,而没有作业或者实验来巩固,这也在一定程度上,慢慢增加了我们听课的难度。(有作业逼学生复习,可能听课效果也会有提升)

posted @ 2020-07-09 22:44  winkkkk  阅读(211)  评论(0编辑  收藏  举报