课程学习总结报告
Posted ustc-zg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了课程学习总结报告相关的知识,希望对你有一定的参考价值。
一 前言
请您根据本课程所学内容总结梳理出一个精简的Linux系统概念模型,最大程度统摄整顿本课程及相关的知识信息,模型应该是逻辑上可以运转的、自洽的,并举例某一两个具体例子(比如读写文件、分配内存、使用I/O驱动某个硬件等)纳入模型中验证模型。
谈谈您对课程的心得体会,改进建议等。
二 精简的Linux系统概念模型
从宏观上来说Linux操作系统的体系架构分为用户态和内核态,主要是为了确保系统安全,这是一种用来发生故障时保护数据和功能以及避免恶意操作的设计方式。其中:
用户态:CPU可以执行包括特权指令在内的所有指令,可以访问内存中的所有数据,包括外围设备,如硬盘、网卡等。
内核态:CPU能够执行有限范围内的指令,只能访问用户进程中的数据,且不能访问外围设备。
Linux系统一般由4个主要部分组成:内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。部分层次结构如下图所示。
Linux内核的主要组成部分:
进程管理
内存管理
文件系统
设备驱动
网络管理
三 内核启动过程
Linux内核的启动是从start_kernel()开始的,几乎涉及了内核的所有主要模块的初始化。
首先是init_task()(0号进程),init_task是task_struct类型,是进程描述符,使用宏INIT_TASK对其进行初始化。
之后通过rest_init()新建kernel_init和kthreadd内核线程。通过调用kernel_thread()创建1号内核线程,调用kernel_thread执行kthreadd,创建PID为2的内核线程。
总之,init_task()(0号进程)在创建了init进程后,调用cpu_idle()演变为idle进程,执行一次调度后,init进程运行。1号内核线程负责执行内核的部分初始化工作及进行系统配置,最后调用do_execve加载init程序,演变成init进程(用户态1号进程),init进程是内核启动的第一个用户态进程。kthreadd(2号线程)进程由0号进程创建,始终运行在内核空间,负责所有内核线程的调度和管理。
四 进程管理
进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位,Linux中每一个进程由一个task_struct数据结构来描述(进程控制块PCB)。
task_struct结构体描述了进程标识、进程状态、进程调度信息和策略等信息。
4.1 进程的切换
Linux中由switch_to宏执行进程切换,schedule()函数调用这个宏调度一个新的进程在CPU上运行。这个宏和函数的被调用关系:schedule() --> context_switch() --> switch_to --> __switch_to()。当schedule()需要暂停A进程的执行而继续B进程的执行时,就发生了进程之间的切换。本质上说每个进程切换有两步组成:切换页全局目录以安装一个新的地址空间以及切换内核态堆栈和硬件上下文。切换全局页表项这个切换工作由context_switch() 完成,而switch_to完成第二部分。有关进程上下文的切换详见上篇博客,本文主要介绍Linux中进程的调度策略问题。
4.2 Linux进程调度策略
Linux的进程调度是基于优先级的调度。Linux的进程分为普通进程和实时进程,在基于优先级的算法下实时进程的优先级高于普通进程。Linux中进程的优先级是动态的,调度程序周期性的调整他们的优先级,避免进程饥饿。调度策略:
SCHED_OTHER 非实时进程,基于优先级的轮转法
SCHED_FIFO 实时进程,基于先进先出算法
SCHED_RR 实时进程,基于优先权的轮转法
在可运行队列结构中,arrays数组的两个元素分别用来表示活动进程集合和过期进程集合,active和expired两个指针分别直接指向这两个集合。活动进程:处于可运行状态的进程,并且还没有用完他们的时间片,他们等待被运行。过期进程:处于可运行状态的进程,但已经用完了自己的时间片,在其他进程没有用完它们的时间片之前,他们不能再被运行。
普通进程
对于普通进程而言,在Linux中其动态优先级不小于100(数值越大级别越低)。其中:
交互进程——用完时间片的活动交互进程通常仍然是活动进程,调度程序重填时间片把它留在活动进程集合中(放置与队列尾部)。
非交互进程——为提高交互进程的性能,用完时间片的非交互进程(如活动批处理进程)总是变成过期进程。但是需要注意的是,如果最老的过期进程等待了很长时间,或者过期进程比交互进程的优先级高,调度程序把用完时间片的活动交互进程移到过期进程集合中。
为了防止进程饿死,以下三种情况会出现队列迁移:
a 活动队列为空时,过期队列拷贝到活动队列中去,之后过期队列为空。
b 过期队列中等待时间最长的进程等待时间超过阈值时,发生队列迁移。
c 当前进程发现过期队列中的首进程(优先级最高的进程)优先级高于当前进程。
实时进程
对于实时进程而言,在Linux中其动态优先级数范围在1-99之间(1为最高优先级)。实时进程总是被当作活动进程,在运行过程中禁止低优先级进程的执行,且实时进程运行后会一直占用CPU资源,只有下列情况在会被另一进程替代:
a 进程被更高优先级的实时进程取代。
b 进程执行了阻塞操作并进入睡眠。
c 进程停止或被杀死。
d 进程自愿放弃cpu(可以通过调用系统调用sched_yield()放弃CPU)。
e 进程是基于时间片轮转的实时进程,且用完了时间片。
五 设备驱动
几乎每个系统操作最终都映射到一个物理设备上。除了处理器,内存和非常少的别的实体之外,全部中的任何设备控制操作都由特定于要寻址的设备相关的代码来进行。这些代码称为设备驱动。内核中必须嵌入系统中出现的每个外设的驱动,从硬盘驱动到键盘和磁带驱动器。
Linux对设备的访问是通过对文件的操作来完成的。要访问某个设备,除了要有驱动程序,还要建立设备文件。
在驱动程序中,主要完成以下工作:
a 获取并注册设备号
b 新建,初始化,并添加cdev结构体
c 其他初始化,如分配内存、端口初始化等。
而对于设备文件来说,包括有以下几项操作:
a 根据设备号,创建设备文件
b 创建完成就可以调用open。open完成后返回文件描述符fd,之后就可以利用fd进行read,write等操作。
六 文件系统
Linux系统中,遵循一切都是文件的原则。文件控制块FCB是系统为管理文件而设置的一个数据结构,是文件存在的标志,它记录了系统管理文件所需要的全部信息。FCB通常包括:文件名、文件号、用户名、文件的物理位置、文件的长度、文件类型、文件属性等。我们以open()进行系统调用打开文件为例,说明在文件系统中打开文件的流程:
首先,当程序运行到open()函数时,会调用C标准库中封装的open函数,产生中断。
跳转到软中断处理函数,保存现场、指令解析、进而得到指令参数。
以参数为索引,执行系统调用表中对应的表项,其中每一项都是一个函数入口指针,open对应sysopen。
sysopen首先要判断文件系统的类型,不同的文件系统类型采用不同的查找方式,之后根据文件路径进行搜索,若在搜索过程中找到一个挂载点,则要更换文件系统再进行路径查找,直至找到对应的文件控制块。
在内存中,有系统打开文件表——包含每个已打开文件的FCB的副本,以及其他信息;以及进程打开文件表——包含一个指向系统打开文件表相应项的指针,以及其他信息。
open函数会新建一个file结构体,其中file -> f_op指向file_operation,对应真正的sysopen和sysread等操作,之后将file添加到一个file数组中,返回其索引值fd。
之后对文件的read、write等操作,都会根据fd找到file结构体,执行file -> f_op中所指向的对应操作。
七 课程心得体会
两位老师讲课各有特色,Linux课程本身涉及到大量内核源码,自己阅读非常枯燥,两位老师的讲解深入浅出的同时又伴有幽默,激发了我对这门课深入学习的兴趣。孟老师通过授课+博客的方式,不仅让我学习了知识点,更是督促我化为己用,能够将自己所学输出出来。李老师讲课过程中会涉及到大量源代码的阅读,但为了吸引我们的注意,老师也是在讲课过程中穿插各种生动有趣的类比,不过因为个人基础的问题,希望老师在之后的讲课中语速能再放慢一些。
在跟随两位老师学习Linux操作系统的过程中,我受益匪浅,非常感谢两位老师的辛苦付出~!
以上是关于课程学习总结报告的主要内容,如果未能解决你的问题,请参考以下文章