在Linux系统分析这门课中,我们主要学习了中断,系统调用,程序加载执行,进程管理,文件系统,计时器方面等方面的内容。
通过这门课的学习让我初步了解到了,Linux系统的大致运行过程。
VFS
通过构建一个通用文件模型,使得VFS
使用一套统一的操作来管理不同的文件系统。另外在Linux中外设也被看成是一种文件,系统对设备文件的读写将转换成驱动程序对外设的读写操作。Linux系统的启动做了些什么,我们大致可以从start_kernel
这个函数里面略窥一二。
kernel_init
(所有用户进程的祖先),kthreadd
(所有内核进程的祖先)的初始化及运行中断是CPU提供的一个重要的机制,它使得指令流可以被强制跳转。
狭义上的中断专指来自CPU外部的硬件中断,而来自CPU内部的特殊信号则称为异常。前者可进一步分为可屏蔽中断和非屏蔽中断;后者可以细分为终止,故障和陷阱。其中陷阱是由用户代码主动引发的中断,系统调用正是由此实现。
如果发生了中断或异常,CPU会依次执行以下操作:
确定与中断或异常关联的向量i(0 <= i <= 255)。
读中断描述符表(IDT)中的第i项。
通过第i项中的段选择符在GDT中查找相应的段描述符。后者指定中断或异常处理程序的段基地址。
权限检查:比较CPL与段描述符的DPL;比较CPL与门描述符的DPL。
检查是否发生了特权级的变化,若CPL不同于段描述符的DPL(从用户态陷入内核态),则:
读取tr寄存器访问运行进程的TSS段。
装载TSS中的ss与sp到寄存器(指向当前线程的内核栈)。
在新栈中保存ss和sp之前值。
若发生的是故障则用引起异常的指令修改cs和sp寄存器的值,以使这条指令在异常处理结束后可以被再次执行。
在栈中保存flags,cs和ip的值。
如果异常产生一个异常操作码,则将它保存在栈中。
装载处理程序入口地址到cs和ip。
从中断或异常返回时要执行iret指令,CPU会执行以下操作:
cs、ip、flags依次出栈并装载到相应寄存器。若有硬件出错码,则将其出栈。
权限检查:比较CPL与处理程序权限等级,若相等,则结束;否则(从内核态返回用户态),执行下一步。
从栈中装载ss和sp寄存器(指向被中断线程的用户栈)。
检查并重置ds,es,fs,gs寄存器。
当然,除了上述由硬件自动保存和恢复的寄存器之外,还有很多寄存器需要手动维护(SAVE_ALL和RESTORE_ALL )。这些在栈中暂存的寄存器值一起构成了pt_regs结构。
中断处理程序依次执行以下操作:
将中断向量入栈
保存所有其他寄存器
调用do_IRQ
跳转到ret_from_intr
异常处理程序依次执行以下操作:
在内核堆栈中保存大多数寄存器的内容。
调用C语言的函数
通过ret_from_exception()从异常处理程序退出。
中断处理函数直接在被中断进程的内核栈内执行,即所谓的中断上下文。需要注意的是,Linux允许中断嵌套执行。
文件系统也是操作系统的三大核心功能之一。同进程一样,文件控制块FCB是系统为管理文件而设置的一个数据结构。FCB是文件存在的标志,它记录了系统管理文件所需要的全部信息,包括文件名,文件物理地址,文件大小,文件创建时间等等信息。在Linux系统中一切有着有一切皆文件的思想,无论是正规文件,目录文件,符号链接,设备文件,管道文件, 套接字都通过VFS系统提供一个统一的接口。文件系统的一个最大特点是“按名存取”,用户只要给出文件的符号名就能方便地存取在外存空间的文件信息,而不必关心文件的具体物理地址。而文件系统最重要的三个功能就是open, read, 和write,而这三个中最重要的就是open,这里介绍一下open的过程:
第一部分:open会首先调用C库中的open函数,通过int 0x 80进行系统调用,然后获取中断异常向量表中获取128号中的段选择符和段内偏移(也即系统调用程序的入口地址),在系统调用中会进行保存现场,通过对指令分析获取用户提供的参数,然后获取系统调用表中对应的sys_open函数。第二部分:sys_open函数会进行命名查找,得到文件控制块,获取文件的类型,根据文件的类型调用不同的文件打开函数,文件打开函数会创建一个文件打开表(系统文件打开表),通过文件控制块填入相关信息,然后会返回进程中,进程中也会存在一个文件打开表,进程文件打开表就是进程的file中的fd数组,fd数组中存入指针会指向存入系统打开表中的表项,而那些表项对应着刚刚打开的文件,最后open会返回这个文件存在fd数组的下标。
有了上述的open过程,之后的read和write就会很简单了,read和write就可以根据上述的open返回的数组下标,找到对应的文件,然后就可以对文件进行读写。
另外,Linux中的设备,除网络设备外,字符设备和块设备都被映射到Linux文件系统的文件和目录,因此Linux中对设备的操作与上述讲的对普通文件的操作很类似,这里不再赘述。
相对时间:记录系统从启动直到当前时刻的时间。相对时间由系统时钟中断进行维护。
墙上时间:系统启动的时候根据实时RTC芯片保存的数据进行初始化,在系统运行期间由系统时钟维护并在合适的时刻和RTC芯片进行同步。墙上时间存储在系统核心变量xtime中,该变量记录了现实世界中年月日格式的时间。
心得与体会
通过这门课了学习到了很多知识,以前只局限于Linux基本命令的使用,环境的配置,现在能更加深入了解Linux的运行原理,明白Linux一些底层操作,例如中断异常,时钟 ,文件系统之类的;不过李老师讲函数之间调用,很容易就晕了,最好还是有函数之间的调用脑图会清楚很多;
原文:https://www.cnblogs.com/deepfeel/p/13273802.html