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

    计算机有"3⼤法宝"即是:存储程序计算机、函数调⽤堆栈、中断。

    操作系统有“两把宝剑”即是中断上下⽂和进程上下⽂。

    1. C代码中嵌⼊汇编代码
      

      练习:下面代码的输出是  0,1 

      

    2. 中断

      中断分外部中断(硬件中断)和内部中断(软件中断),内部中断⼜称为异常(Exception),异常⼜分为故障(fault)和陷阱(trap)。系统调⽤就是利用陷阱(trap)这种软件中断⽅式主动从⽤户态进⼊内核态的。

      系统调用实际上是一种特殊的中断。和一般的中断一样,它需要进行现场的保存,用户态到内核态的切换,现场的恢复,内核态到用户态的切换这么几个步骤。但和一般的中断相比,系统调用又有所不同。这个中断不是由硬件触发的(如键盘按键),而是由封装在C库中的系统调用函数通过调用int 0x80进入的。这个指令是一条陷入指令,它是我们正在执行的代码引起的,而不是外界与当前代码无关的中断源引起的。从system_call到iret的过程。

      

       IDT,中断描述符表(IDT),是一张系统表。

        1.每个中断或异常在表中有相应的中断或异常处理程序的入口地址。
        2.每个描述符8个字节,共256项,占用2KB
        3.内核在允许中断前,必须适当初始化IDT

      中断和异常的硬件处理
        1.确定与中断和异常相关的联的向量i
        2.从idtr寄存器中找到 IDT的地址,从IDT中找到 第i项
        3.从gdtr寄存器中获得GDT的基地址,从GDT找到 IDT项 中的 段选择符 所标识的 段描述符
        4.确定中断时由授权的发生源发出的
        5.检查是否发生了特权级的变化, 一般指的是是否由用户态陷入了内核态, 如果由用户态陷入了内核态, 需要使用新的特权级相关的堆栈
        6.若发生的是故障,用引起异常的指令地址修改cs和eip的值,以使得这条指令在异常处理结束后能再次被执行
        7.在栈中保存eflags、cs 和eip的内容
        8.如果异常产生一个硬件出错码, 则将它也保存在栈中
        9.装载cs和eip寄存器,其值分别是IDT表中第i项门中描述符的段选择符和偏移量字段

      经过上述的硬件级处理过后,内核态的堆栈会发生变化,但是由用户态进入中断和由内核态进入中断又有不同,如下图所示:

      

      中断和异常的软件处理:
        异常处理有一个标准的结构,由三部分组成 :
        1. 在内核态堆栈中保存大多数寄存器的内容
        2. 调用C语言的函数
        3. 通过ret_from_exception()从异常处理程序退出 。  

      当异常发生时,如果控制单元 没有自动地把一个硬件错误代 码插入到栈中,相应的汇编语 言片段会包含一条pushl $0指令,在栈中垫上一个空值,如果错误码已经被压入堆栈,则没有这条指令。然后,把异常处理 函数的地址压进栈中;函数的名字由异常处理程序名与do_ 前缀组成。 然后调用error_code,该函数的主要功能:(1)按照pt_regs结构定义的堆栈数据格式完成相应 的入栈操作,进一步完成现场的保存。(2) 把堆栈地址中的do_handler_name()函数的地址 装入edi寄存器中,并在这个位置写入fs值,使栈 结构进一步与pt_regs结构完全一致。(3) 最后执行call *%edi指令。

      中断/异常返回
        在中断/异常处理完成后,会执行iret指令:
        将保存在栈中的值 装在cs、eip和eflags寄存器,有出错码就弹出
        检查处理程序的特权等级,判断是否运行在内核态。如果是,就进行下一步
        从栈中装载ss和esp,返回原来的栈空间
        检查段寄存器

      中断上下文:其实可以看作就是硬件传递过来的这些参数和内核需要保存的一些其他环境(主要是当前被打断执行的进程环境)。需要注意的是,中断上下文没有自己的上下文环境,它占用的是被中断进程的上下文。

    3.进程管理

      进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位;进程控制块(PCB) + 程序段 + 相关的数据段 = 进程实体;进程控制块:进程控制块PCB是名字为task_struct的数据结构,它称为任务结构体。当一个进程被创建时,系统就为该进程建立一个 task_struct任务结构体。当进程运行结束时,系统撤 消该进程的任务结构体。进程的任务结构体是进程存在的唯一标志。

      进程上下文:把系统提供给进程的处于动态变化的运行环境总和称为进程上下文。

      为了对给定类型的进程进行有效的搜索,内核维护了几个进程链表。一般进程链表是双向循环链表。

      0号进程:init_task,1号进程:kernel_init,2号进程:kthreadd。

      函数fork,vfork,clone来创建新进程,execve加载可执行程序,exit来终止进程。

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

      进程调度算法:SCHED_FIFO和SCHED_RR是⽤于实时进程的调度类,优先级⾼于SCHED_NORMAL。SCHED_FIFO采⽤先进先出的策略,对于所有相同优先级的进程,最先进⼊就绪队列的进程总能优先获得调度,直到其主动放弃CPU。SCHED_RR(Round Robin)采⽤更加公平的轮转策略,⽐FIFO多⼀个时间⽚,使得相同优先级的实时进程能够轮流获得调度,每次运⾏⼀个时间⽚。

    4. 文件管理  

      文件打开:应用程序对open ( )的调用将引起 内核调用服务例程 sys_open ( )函数,该函数接收的参数为:要打开文件的路径名 和 访问模式等。该系统调用成功后将返回一个 文件描述符,也就是文件对象指针数组的一个索引;系统调用不成功时返回 -1。

      文件关闭:用户程序通过close ( )系统调用关闭打开的文件,该函数接收的参数为要关闭文件的 文件描述符。内核服务例程为 sys_close ( )函数。

      VFS:虚拟文件系统(Virtual File System, 简称 VFS), 是 Linux 内核中的一个软件层,用于给用户空间的程序提供文件系统接口;同时,它也提供了内核中的一个 抽象功能,允许不同的文件系统共存。系统中所有的文件系统不但依赖 VFS 共存,而且也依靠 VFS 协同工作。为了能够支持各种实际文件系统,VFS 定义了所有文件系统都支持的基本的、概念上的接口和数据结构;同时实际文件系统也提供 VFS 所期望的抽象接口和数据结构,将自身的诸如文件、目录等概念在形式 上与VFS的定义保持一致。换句话说,一个实际的文件系统想要被 Linux 支持,就必须提供一个符合VFS标准的接口,才能与 VFS 协同工作。实际文件系统在统一的接口和数据结构下隐藏了具体的实现细节,所以在VFS 层和内核的其他部分看来,所有文件系统都是相同的。

      为什么读一个文件之前一定要open这个文件:用户进程在读/写一个文件之前必须先打开这个文件。所谓打开文件实质上是在进程与文件之间建立连接,而打开文件描述符唯一地标识着这个连接。

      同一个进程,打开两个不同文件,返回的两个fd是不一样的:内核中,对应于每个进程都有一个文件描述符表,表示这个进程打开的所有文件。文件描述表中每一项都是一个指针,指向一个用 于描述打开的文件的数据块:file对象,file对象中描述了文件的打开模式,读写位置等重要信息,当进程打开一个文件时,内核就会创建一个新的file对象。需要注意的是,file对象不是专属于某个进程的,不同进程的文件描述符表中的指针可以指向相同的file对象,从而共享这个打开的文件。file对象有引用计数,记录了引用这个对象的文件描述符个数,只有当引用计数为0时,内核才销毁file对象,因此某个进程关闭文件,不影响与之共享同一个file对象的进程。

      读文件的过程简述:

      1. 进程调用库函数 向 内核 发起 读文件请求;
      2. 内核 通过检查 进程的文件描述符(fd) 定位 到虚拟文件系统(VFS)的 已打开文件列表 表项;
      3. 调用该文件可用的系统调用函数read()。该函数通过 文件表项 链接到 目录项模块,根据传入的文件路径,在目录项模块中检索,找到该文件的inode;
      4. 在inode中,通过 文件内容偏移量 计算出要读取的页;
      5. 通过inode找到文件对应的 地址空间(address_space);
      6. 在address_space 中访问该文件的 页缓存树,查找对应的 页缓存结点:
        如果页缓存命中,那么直接返回文件内容;
        如果页缓存缺失,那么产生一个页缺失异常,创建一个页缓存页,同时通过inode找到文件该页的磁盘地址,读取相应的页填充该缓存页;重新进行第6步查找页缓存;
      7. 文件内容读取成功

  • 相关阅读:
    day 66 ORM django 简介
    day 65 HTTP协议 Web框架的原理 服务器程序和应用程序
    jQuery的事件绑定和解绑 事件委托 轮播实现 jQuery的ajax jQuery补充
    background 超链接导航栏案例 定位
    继承性和层叠性 权重 盒模型 padding(内边距) border(边框) margin 标准文档流 块级元素和行内元素
    属性选择器 伪类选择器 伪元素选择器 浮动
    css的导入方式 基础选择器 高级选择器
    03-body标签中相关标签
    Java使用内存映射实现大文件的上传
    正则表达式
  • 原文地址:https://www.cnblogs.com/LiScott/p/13267864.html
Copyright © 2011-2022 走看看