实验笔记
MIT 6.1810 Lab: Xv6 and Unix utilities
MIT 6.1810 Lab: Copy-on-Write Fork for xv6
MIT 6.1810 Lab: Multithreading
待续
总结
xv6是一个十分精巧的操作系统,它的每个模块是否简单,却又保留各种操作系统设计的理念。通过对xv6的源码进行学习,可以真正理解操作系统的原理与底层的代码逻辑。
内核
对于内核的理解一直是让人困惑的。一方面,内核在系统调用时接管,代进程执行;另一方面,内核维护着整个系统运作,处理中断与外设,像是一个庞大的后台进程。内核可以被调度、可以被中断、中断又是内核在执行……学习操作系统时总是会有各种各样的概念、设计、方法,但是如果不能真正的理解内核,就难以将操作系统的学习连成一个有机的整体。
XV6是一个精简版的操作系统,可能与现在Linux内核有很大的不同,但却对我对内核的理解有了很大的启发。我们知道内核往往是由Bootloader在开机加电后塞到内存中,然后程序流跳转的内核的入口,内核进行初始化,这段时间内核表现像是CPU的唯一进程。另一个问题就是多CPU怎么办,每个CPU核心都会跳转到内核的初始化程序处,但是这段程序往往会根据获取CPU编号,只用一个核心完成初始化。
初始化的最后,这里内核变成永远循环的调度程序,从属于每个CPU核心。调度程序会不停的将CPU跳转到某一进程,进程会因时钟中断将CPU跳转到调度程序。在此之后,就要把内核理解为常驻内存的一段程序。当发生系统调用、外部中断,CPU就会按照预先的设置,执行一部分内核代码,并最终返回。
进程上下文、中断上下文这些概念往往是指,特定状态下,内核实现某一功能的逻辑程序流,不能孤立的认为某一段程序是某上下文。
此外还有内核线程,它的组织与用户进程一样,但是永远执行内核程序,与用户进程一起被调度。
进程调度
xv6中不区分进程与线程。进程是xv6调度的单位,进程运行在CPU上,时钟中断使进程进入内核态,时钟中断会将激活调度程序。从进程切换到调度程序的最后,就是将当前的上下文(此时位于内核,保存的是内核上下文,用户程序的上下文在发生中断时,保存在进程的虚拟地址空间中)保存在当前进程的进程描述符中,切换前的最后一条语句是ret
,将控制流指向ra
寄存器指向的位置,ra
即调用切换寄存器函数的函数下一句,因为切换寄存器函数是被调用的,因此在切换寄存器函数中,ra
存储的是调用函数的下一句。
中断
在XV6中,在用户空间和内核空间发生中断时,处理的逻辑是不同的。发生中断时,CPU会根据寄存器中存储的中断向量,跳转到指定的位置。因此在用户空间和内核空间中,中断寄存器中保存的地址是不同的,这个寄存器的修改会在特权空间切换时修改。
在用户空间,系统调用又称软中断,与硬件中断的处理方式相同。中断发生时,硬件关中断、改特权、保存PC、跳转程序。在XV6中首先跳转到uservec
,在这里保存用户上下文到进程地址空间的保留区域,最后切换内核页表,由内核完成相应操作。最终会由userret
恢复用户上下文。
在内核空间,发生中断时会将当前的内核上下文保存在内核栈中(内核栈属于当前内核上下文的从属进程)。其中kernelvec
保存内核上下文,kernelret
恢复内核上下文。
时钟中断无论发生在用户空间还是内核空间都会激活调度程序,两者的区别是,用户空间发生时钟中断时,会先保存用户上下文陷入内核,后续除了调用的trap
函数不同外,处理逻辑基本一致。
系统调用
待续
标签:中断,Lab,CPU,内核,进程,6.1810,上下文,MIT From: https://www.cnblogs.com/benoqtr/p/18032830