现在的位置: 首页 > 综合 > 正文

Linux操作系统分析(五)- Linux操作系统是如何工作的?破解操作系统的奥秘

2014年03月14日 ⁄ 综合 ⁄ 共 2606字 ⁄ 字号 评论关闭

学号:SA***199  姓名:*浩

学习笔记:

Linux操作系统分析(一) How the computer work

Linux操作系统分析(二) 进程的创建与可执行程序的加载

Linux操作系统分析(三)- 更新内核与添加系统调用

Linux操作系统分析(四)- 掌握Linux系统的构建和调试方法

Linux操作系统分析(五)- Linux操作系统是如何工作的?破解操作系统的奥秘

操作系统工作的基础:存储程序计算机、堆栈(函数调用堆栈)机制和中断机制


存储程序计算机:


存储程序计算机最早是由著名数学家冯·诺依曼等人在1946年总结并明确提出来的,因此又被称为冯.诺依曼计算机。其要点为:

  1. 计算机完成任务是由事先编号的程序完成的;
  2. 计算机的程序被事先输入到存储器中,程序运算的结果,也被存放在存储器中。
  3. 计算机能自动连续地完成程序
  4. 程序运行的所需要的信息和结果可以通输入\输出设备完成。
  5. 计算机由运算器、控制器、存储器、输入设备、输出设备所组成;

归纳总结一下就是以运算为中心,采用存储程序原理,指令顺序执行。


堆栈(函数调用堆栈)机制:


        在Linux操作系统分析(一) How the computer work中我们分析了函数堆栈的使用,大多数CPU上的程序实现使用栈来支持函数调用操作。栈用来传递函数参数、存储返回信息、临时保存寄存器原有值以用于回复以及存储局部数据。栈帧结构的两端由两个指针来指定。寄存器ebp通常用作栈帧的指针、esp用作栈的指针。esp随着数据的入栈和出栈。因此对于函数中大部分数据的访问都是通过基于帧帧指针ebp来实现。函数调用时,调用者首先会将参数以及返回地址(下一条指令的EIP)压入栈中,并将当前EIP修改为被调用函数的起始地址;被调用者开始执行后先将原栈基址EBP保存在栈中,并修改EBP和ESP的值,初始化一个新栈。返回时,被调用者恢复EBP和ESP,并且将EIP修改为栈中存储的返回地址。


中断机制:


         通过中断机制,计算机可以改变指令的执行顺序,能够提高cpu的并发处理能力。

        那么,通用的计算机系统是如何处理中断呢?它是靠硬件和软件配合来协同实现中断处理的全过程的。

        CPU执行完一条指令后,下一条指令的逻辑地址存放在cs和eip这对寄存器中。在执行新指令前,控制单元会检查在执行前一条指令的过程中是否有中断或异常发生。如果有,控制单元就会抛下指令,进入下面的流程:

  1.   确定与中断或异常关联的向量i (0<i<255)
  2.   寻找向量对应的处理程序
  3.   保存当前的“工作现场”,执行中断或异常的处理程序
  4.   处理程序执行完毕后,把控制权交还给控制单元
  5.   控制单元恢复现场,返回继续执行原程序

整个流程如下图所示:



操作系统(内核)是如何工作


Linux内核概念:


        Linux内核其实就是一种特殊的软件,它在硬件和运行在计算机上的应用程序之间提供了一个层。它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。是操作系统的核心部分。Linux以统一的方式支持多任务,而这种方式对用户进程是透明的,每一个进程运行起来就好象只有它一个进程在计算机上运行一样,独占内存和其它的硬件资源,而实际上,内核在并发地运行几个进程,并且能够让几个进程公平合理地使用硬件资源,也能使各进程之间互不干扰安全地运行。

Linux内核具体是怎么工作的呢:


       现代操作系统都支持多任务系统,系统工作时,分为内核态和用户态。进程是正在运行的程序的一种抽象,进程工作在从用户态到内核态,从内核态在到用户态之间的转换。用户态的进程不能直接使用硬件资源,通过中断来切换到内核态来完成。内核态通过分析中断请求,确定中断向量表,然后转向相应的中断出俩函数,完成中断服务。然后在转到用户态,继续执行原先程序。

进程从用户态切换到内核态 :

       用户态切换到内核态的3种方式:

  • 系统调用:用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作,系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现。
  • 异常:CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。
  • 外围设备的中断:当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。

3种方式是系统在运行时由用户态转到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的。这3种方式但是从最终实际完成由用户态到内核态的切换操作上来说,涉及的关键步骤是完全一致的,没有任何区别,都相当于执行了一个中断响应的过程,因为系统调用实际上最终是中断机制实现的,而异常和中断的处理机制基本上也是一致的,关于它们的具体区别这里不再赘述。涉及到由用户态切换到内核态的步骤主要包括:

  •  从当前进程的描述符中提取其内核栈的ss0及esp0信息。
  •  使用ss0和esp0指向的内核栈将当前进程的cs,eip,eflags,ss,esp信息保存起来,这个过程也完成了由用户栈到内核栈的切换过程,同时保存了被暂停执行的程序的下一条指令。
  •  将先前由中断向量检索得到的中断处理程序的cs,eip信息装入相应的寄存器,开始执行中断处理程序,这时就转到了内核态的程序执行了


进程从内核态切换到用户态 :

内核态程序执行完毕时如果要从内核态返回用户态,可以通过执行指令iret来完成,指令iret会将先前压栈的进入内核态前的cs,eip,eflags,ss,esp信息从栈里弹出,加载到各个对应的寄存器中,重新开始执行用户态的程序,




参考资料:

       


抱歉!评论已关闭.