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

    1.进程管理

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

    进程的状态以及状态之间的切换(如下图所示)

     需要注意的是,就绪态和运行态在系统中的状态都是TASK_RUNNING,也就是说,在Linux内核中,当进程是TASK_RUNNING状态时,它是可运⾏的,也就是就绪态,是否在运⾏取决于它有没有获得CPU的控制权,也就是说这个进程有没有在CPU中实际执⾏。如果在CPU中实际执⾏着,进程状态就是运⾏态;如果被内核调度出去了,在等待队列⾥就是就绪态。

    进程创建

    linux提供了几个系统调用来创建和终止进程:
    fork,vfork,clone来创建新进程(最终都通过__do_fork)
    exec执行一个新程序
    exit来终止进程

    调度时机

    进程状态发生变化时

    当前进程时间片用完时

    进程从系统调用返回到用户态时

    中断处理后,进程返回到用户态时

    进程的上下文切换(如下图所示)

     2.系统调用

    应用程序 代码调用系统调用( xyz ),该函数是一个包装系统调用的 库函数 ;

    库函数 ( xyz )负责准备向内核传递的参数,并触发 软中断 以切换到内核;

    CPU 被 软中断 打断后,执行 中断处理函数 ,即 系统调用处理函数 ( system_call);

    系统调用处理函数 调用 系统调用服务例程 ( sys_xyz ),真正开始处理该系统调用。

    3.中断管理

    内核的一个主要功能就是处理硬件外设I/O,而cpu的速度比外设快很多,如果使用轮询方式与外设交互,显然会浪费许多cpu的资源,所以需要操作系统支持中断。

    中断和异常的硬件处理

    进入中断/异常

    当cpu执行完一条指令后,会检查是否发生了中断或者异常。如果发生了中断或异常,则执行下列操作:

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

    此时,进程的内核堆栈如下图所示:

     

     中断服务程序占用的是被中断进程的内核栈,因此在中断服务程序正式执行之前,还需要将硬件没有自动入栈的一些通用寄存器进行手动入栈,其顺序与pt_regs结构相对应。

    从中断/异常返回

    中断/异常处理完后,相应的处理程序会执行一条iret汇编指令,这条汇编指令让CPU控制单元做如下事情:

    1. 用保存在栈中的值装载cs、eip和eflags寄存器。如果一个硬件出错码曾被压入栈中,那么弹出这个硬件出错码
    2. 检查处理程序的特权级是否等于cs中最低两位的值(这意味着进程在被中断的时候是运行在内核态还是用户态)。若是,iret终止执行;否则,转入3
    3. 从栈中装载ss和esp寄存器。这步意味着返回到与旧特权级相关的栈
    4. 检查ds、es、fs和gs段寄存器的内容,如果其中一个寄存器包含的选择符是一个段描述符,并且特权级比当前特权级高,则清除相应的寄存器。这么做是防止怀有恶意的用户程序利用这些寄存器访问内核空

    中断处理

    主要流程

    1. 在内核态堆栈保存IRQ的值和寄存器的内容
    2. 为正在给IRQ线服务的PIC发送一个应答,这将允许PIC进一步发出中断
    3. 调用do_IRQ(),执行共享这个IRQ的所有设备的中断服务例程
    4. 跳到ret_from_intr()的地址后中断跳出

     do_IRQ()根据中断向量号i找到对应的中断描述符,将注册到本中断的各个设备的irqaction都执行一遍。

    4.文件系统

    VFS

    VFS是一个软件层,用来处理与Unix标准文件系统相关的所有系统调用,能为各种文件系统提供一个通用的、统一的接口。对于用户而言,不再需要自己针对每个不同的文件系统执行不同的操作命令,只需要用统一的open eadwrite等操作。

    VFS与具体文件系统的关系如下图所示,它向上提供统一的接口,向下兼容各种不同的文件系统。

     

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

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

    示例一:读文件:

    1. 进程调用库函数read向内核发起读文件请求

    2. 触发系统调用sys_read(),获得当前进程的控制块

    3. 系统调用read()会触发相应的VFS的read()函数

    4. 然后找到file结构,再找到fd数组,以fd为索引找到对应项,然后找到系统打开文件表

    5. 执行系统打开文件表里面的file operation里面的read

    此处有个点需要注意:为什么read之前要先open呢?因为这个系统打开文件表是open创建的。

  • 相关阅读:
    !function() {}()
    element.dataset API
    正则匹配 数字和英文状态下的逗号
    《vim实用技巧》读书笔记
    ajax分页
    smarty分页类
    数组排序
    数组大类
    自动刷新价格
    简单购物车
  • 原文地址:https://www.cnblogs.com/wwwxuexi/p/13272471.html
Copyright © 2011-2022 走看看