码迷,mamicode.com
首页 > 系统相关 > 详细

Linux系统模型

时间:2020-07-09 19:26:31      阅读:89      评论:0      收藏:0      [点我收藏+]

标签:read   部分   空闲   count   flags   相对   打开文件   控制流   文件的   

Linux系统模型

Linux系统模型如下图所示

技术图片

应用程序通过函数库提供的API,或者shell脚本,或者直接系统调用来与内核交互,但本质上都是使用系统调用来使用内核提供的服务。

内核主要提供了以下几种服务:

  1. 中断。通过中断,内核可以将原来的控制流转为中断处理程序的控制流.系统调用属于中断,用户程序可以使用系统调用来进行一些操作,如文件读写;
  2. 进程管理。内核使用PCB来描述和管理一个进程.其中包括进程的创建,调度,销毁等;
  3. 内存管理。内核将内存分为了内核态和用户态;
  4. 文件管理。内核使用了VFS来管理文件.VFS对应用程序,提供了统一的接口.对各个不同的文件系统提供了统一的接口;
  5. 设备管理。内核使用了LKM技术,使得设备的驱动程序可以动态地加入内核.在不重编译内核和重启系统的条件下对Linux系统内核进行修改和扩展。

具体案例

下面文件读取过程为例,介绍内核的运行过程:

要读取一个文件,首先需要使用open()系统调用打开该文件

在32位系统中,open()系统调用执行过程如下:

  1. 程序调用open(),实际上是调用C库函数中的sys_open()

  2. sys_open()中,使用int 0x80 指令,触发系统中断

  3. 内核先从idtr寄存器中找到idt,然后,根据传入的中断号0x80,找到中断描述符

  4. 从gdtr寄存器中找到gdt,然后根据中断描述符中的段选择符,找到段描述符

  5. 由于进程在用户态进行了系统调用,所以进程需要从用户态转为内核态。CPU从tr寄存器中获取tss段,找到内核态堆栈的指针和ss段,装载到eip和ss中

  6. 转到内核态堆栈后,将原来的eflags,eip,cs保存在内核态的堆栈中

  7. 根据中断描述符中的段偏移和段选择符,装载到eip和cs寄存器中,这样进程就找到了系统调用表所在的位置

  8. 然后根据系统调用号,找到sys_open()对应的系统调用,开始执行

  9. sys_open()的具体工作

    • 根据传入的参数,文件名,进行命名查找

    • 如果找了该文件,得到文件控制块,然后根据文件的类型,调用对应的文件打开函数

    • 文件需要将文件控制块复制到系统文件打开表中,如文件操作,读写指针的位置

    • 在进程文件打开表中,有一个fd数组,fd数组中的项指向了系统打开文件表中对应的项。sys_open会找到一个空闲的fd,指向系统打开文件表。然后将fd返回

  10. sys_open()的返回值会保存在eax中,然后使用iret指令恢复现场

当文件打开后,可以使用read()系统调用打开文件,过程如下:

  1. 和上文类似,read()实际上是调用了sys_read(),该函数需要三个参数:一个文件描述符fd;一个包含要传送数据的内存缓冲区地址buf;一个指定应该传送多少字节数的count。然后查找到相对应系统调用的位置
  2. 根据传入的文件描述符fd,找到系统文件打开表中的对应项,然后执行对应的read函数,最后将文件中的内容读取到内存缓冲区
  3. 最后进行系统调用返回

课程总结

孟老师的课,先通过传授一些汇编知识,帮助我扫清了阅读源码的障碍.然后通过巧妙的实验,让我对Linux的进程切换,系统调用过程有了深入的理解.李老师的课,通过阅读Linux内核的部分源码,我对操作系统的理解不再浮于概念,而是对中断过程,进程管理,设备管理,文件管理有了具体而形象的理解.但是可能是课时原因,对内存管理提及不多,希望李老师今后的授课中,可以加入内存管理的部分.

Linux系统模型

标签:read   部分   空闲   count   flags   相对   打开文件   控制流   文件的   

原文地址:https://www.cnblogs.com/lm273/p/13275460.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!