zoukankan      html  css  js  c++  java
  • 课程学习总结报告

    要求:

    请您根据本课程所学内容总结梳理出一个精简的Linux系统概念模型,最大程度统摄整顿本课程及相关的知识信息,模型应该是逻辑上可以运转的、自洽的,并举例某一两个具体例子(比如读写文件、分配内存、使用I/O驱动某个硬件等)纳入模型中验证模型。

    谈谈您对课程的心得体会,改进建议等。

    根据课程顺序,把学习内容主要分为以下几个大块:

    一. 系统调用和堆栈框架

    · 为了屏蔽硬件操作的细节,增强系统的安全性,增强用户程序的可移植性,Linux操纵系统划分了用户态和内核态,对应的内存空间被划分成用户空间和内核空间。内核态的权限高于用户态,即内核态下,cs:ip可以指向任意位置,而用户态下,cs:ip的活动范围只能是自己的空间。为了使用户调用操作系统底层服务,如中断,时钟,异常等,需要采取一种机制,就是系统调用。

    从软件的角度看,通过int 0x80指令或者syscall指令可以触发系统调用。首先,当linux进入内核态时,先保存此时的上下文环境,如果是硬件中断触发的系统调用,保存的是中断上下文,如果是用户程序触发的系统调用,保存用户进程上下文。所谓的上下文是内核保存的,用于系统调用返回的参数信息然后,通过系统调用号,找到对应的系统调用处理函数的首地址,建立函数堆栈,修改cs:ip的值并执行处理函数。处理函数执行完毕后,根据保存的上下文信息恢复现场返回用户态。

    · 堆栈是C语言程序运行时必须的一个记录调用路径和参数的空间, 在这个堆栈上保存了函数调用框架, 传递的参数, 保存的返回地址, 函数内部 的局部变量等等参数。一个函数调用动作是通过call指令来完成的。

    一个完成的函数调用过程大致可以用下图表示:即call target,进入target,退出target。

    二. 进程管理

    概念:进程是Linux进行资源分配和调度的基本单位,进程也被看做是程序的一次执行过程,当持久化在磁盘上的二进制代码被载入内存时,Linux操作系统为其分配了用户栈和内核栈,同时使用task_struct这种数据结构对进程进行描述,task_struct是Linux操作系统感知进程存在的数据结构,具体描述了进程号,进程状态,进程的调度策略和调度信息,进程打开文件表,进程链表,父子进程的关系等信息。Linux根据这个数据结构找到进程对应的用户栈和内核栈,并根据cs,ip,ss,sp,ebp等寄存器信息,执行这个进程。

    状态切换

    上下文切换:期间涉及到prev进程上下文的保存,以及next进程上下文的加载,如图所示:

    具体的还牵扯到了进程的内核态和用户态堆栈。

    进程调度:有了进程的概念,Linux就可以执行磁盘中持久化的二进制代码了。为了提高cpu利用率,提高计算机的并发性,引入了进程的调度这个概念,这相当于Linux虚拟化了多个“平行空间”,每个进程都有自己独立的用户栈和内核栈,Linux内核根据调度策略,在一定的时机对进程进行调度。

    进程调度时机包括:时间片用完,中断返回,进程状态发生变化,系统调用返回等。

    至于调度策略,Linux系统采用优先级调度的策略,又分成实时进程和非实时进程,实时进程指需要及时处理的进程,优先级范围是0~99100~139是非实进程的优先级范围。实时进程的优先级高于非实时进程。同一优先级对列按FIFO或者RR(时间片轮转)进行调度。

    三. 中断

    中断最初⽤于避免CPU轮询I/O设备,就绪状态发⽣时让I/O设备主动通过中断信号通知CPU,大大提⾼了CPU在输⼊输出上的⼯作效率,这就是硬件中断(外部中断)。后来随着中断适⽤范围扩⼤,比如解决机器运⾏过程出现的异常情况以及系统调⽤的实现等,这就产⽣了软件中断(内部中断),也称为异常,软件中断⼜分为故障(fault)和陷阱(trap)。

    简而言之,在没有中断机制之前,计算机只能⼀个程序⼀个程序地执⾏,也就是批处理,而无法多个程序并发⼯作。有了中断机制,CPU帮我们做了⼀件事情,就是当⼀个中断信号发⽣时,CPU把当前正在执⾏的进程X的CS:RIP寄存器和RSP寄存器等都压栈到了⼀个叫内核堆栈的地⽅,然后把CS:RIP指向⼀个中断处理程序的入口,做保存现场的⼯作,然后去执⾏其他进程⽐如Y,等重新回来时再恢复现场,即恢复CS:RIP寄存器和RSP寄存器等到CPU上继续执⾏原进程X。显然中断机制在计算机系统中发挥着关键作⽤。

    经过上述的硬件级处理过后, 内核态的堆栈会发生变化, 但是由用户态进入中断和由内核态进入中断又不太一样,由上图的特权级是否变化即可看出,具体在堆栈中则有以下区别:

    可以看到内核态进入中断,需要额外保存用户态的上下文信息,以便从内核态变成用户态时继续执行。

    四. 文件管理

    Linux支持多种文件系统,包括ext2、ext3、vfat等等。

    Linux采用虚拟文件系统VFS来达到支持多种文件系统格式的目标。VFS为各类文件系统提供一个统一的操作界面和编程接口。向上提供统一的编程接口,向下对各种文件系统进行兼容。

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

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

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

    五. 具体例子

    以用户读一个文件为例,

    当用户点击打开文件时,会调用库函数中的read()函数,而在这个函数中会触发软中断指令,CPU陷入到内核态,进程堆栈也会切换到相应的内核态堆栈。

    接着,进入异常处理的硬件级流程,在这个过程中,CPU在栈中保存eflags、cs、和eip的内容,随后进入异常处理的软件级流程,在这个过程中, CPU会进一步保存上下文.。

    与这个过程相对应的是:CPU读取idtr寄存器指向的IDT表中的第128项,此时可以得到0x80中断门,通过这个中断门CPU可以得到中断处理例程。

    接着, 中断处理例程会到系统调用表中找到read()函数相对应的VFS虚拟文件系统中的系统调用sys_read()。

    到达VFS层次后,sys_read()会根据fd在进程打开文件表中找到相应的系统打开文件表(File数据结构),然后执行系统打开文件表中的file operations中具体的操作。

    文件打开之后,将pt_regs数据结构中描述的寄存器以及cs:eip寄存器恢复, 此时进程又重新恢复到了用户态, 并沿着read()函数的下一条语句继续执行。

    六. 总结与建议

    总的来说,这门课真的是干货满满,两位老师深入Linux内核代码的耐心讲解,在现在的大环境下真的很难得,也确实让我学到了不少东西,真正了解到了Linux底层的一些运行流程与原理,

    相较于平时自己的摸索,这种课程真的给我带来了很大的帮助。

    建议的话,一些内核代码部分的讲解,逻辑的梳理,只是听老师用嘴说,可能不是很容易理解,如果能有形象的展示,也许会更助于理解。

    最后,希望这门课可以一直继续开下去,帮助更多学弟学妹们。

    谢谢二位老师的辛苦付出,祝老师们身体健康!

     

  • 相关阅读:
    vue开发chrome扩展,数据通过storage对象获取
    Vue手动集成less预编译器
    Google Translate寻找之旅
    Javascript Range对象的学习
    Javascript Promises学习
    SublimeText 建立构建Node js系统
    We're sorry but demo3 doesn't work properly without JavaScript enabled. Please enable it to continue.
    npm安装包出现UNMET DEPENDENCY报错
    (转载)命令行说明中格式 尖括号 中括号的含义
    Linux重启网卡服务Failed to start LSB: Bring up/down networking.
  • 原文地址:https://www.cnblogs.com/seanloveslife/p/13268158.html
Copyright © 2011-2022 走看看