OS:lab4课下基础
OS:lab4课下基础 1.系统调用 1.1 系统调用相关概念 在MIPS中,syscall是用于执行系统调用的自陷指令,它使得进程陷入到内核的异常处理程序中,由内核根据系统调用时的上下文执行相应的内核函数,完成相应的功能,并最终返回到syscall的后一条指令。 存在只能由内核来完成的操作(读写设备、创建进程、IO等) C标准库中的一些函数的实现依赖于操作系统 通过执行syscall指令,用户进程可以陷入到内核态,请求内核提供的服务 通过系统调用陷入到内核态时,需要在用户态与内核态之间进行数据传递与保护 系统调用保证了系统的安全性:内核将自己能够提供的服务以系统调用的方式提供给用户空间,用户程序只能将服务相关的参数交予操作系统执行 API : Application Programming Interface,程序之间的接口 直接使用系统调用较为麻烦,于是产生了一系列用户空间的API定义,他们在系统的调用的基础上,实现了更多更高级的常用功能。用户在编写程序时可以直接调用高层次的API来实现各种功能。 通过层级划分使得程序具有更好的可移植性,只要程序以来的API不变,无论底层的系统调用如何变化,都不会影响 1.2 系统调用机制的实现 异常分发向量组(exception_handlers)中的8号异常,即为操作系统处理系统调用时的异常。 MOS实验代码中,kern目录下即为内核态代码,user目录下即为用户态代码 以user/lib/debugf.c中的debugf函数来学习处理系统调用的流程(debugf函数是一个debug信息输出函数,进行了IO方面的系统调用) debugf函数的调用链为(系统调用请求从用户态向内核态传递) debugf调用字符串输出函数debug_output debug_output调用了用户空间的syscall_*函数(这里的*为通配符,代表着用户空间进行系统调用的一组操作,都定义在用户态代码syscall_lab.c中,这里调用的是syscall_print_cons) syscall_*函数调用msyscall函数,系统陷入内核态(msyscall是汇编代码,直接调用syscall)。 内核态中将异常分发到handle_sys函数,将系统所需信息传递进内核(输出字符串s) 内核取得信息,执行对应的内核空间的系统调用函数sys_*(kern/syscall_all.c) 系统调用完成,返回值传递回用户态 从系统调用函数返回,回到debugf调用处 通过上述描述,对于系统调用的处理实际上是从用户空间向系统空间进行传递的,用户空间中的syscall_*函数与内核中的sys_*是一一对应的,syscall_*函数是用户空间中最接近内核的函数,他调用msyscall中的汇编代码syscall直接陷入内核态,sys_*函数是内核中系统调用的具体实现。 直接调用syscall陷入内核的msyscall函数具有六个参数,其中第一个参数是与调用名相似的宏,例如SYS_print_cons,被称为系统调用号(include/syscall.h),用来区分不同的系统调用,其余还有五个参数,即为系统调用时需要传递给内核的参数。 回忆MIPS函数调用规范中的参数传递,前四个参数保存在寄存器中 Exercise 4.1 msyscall 进行系统调用(syscall),并返回到msyscall的调用者处(jr),syscall_* #include <asm/asm.h> LEAF(msyscall) // Just use 'syscall' instruction and return. /* Exercise 4.1: Your code here. */ syscall #陷入内核 jr ra #返回调用者 syscall_* END(msyscall) 通过汇编指令syscall陷入内核态后,处理器将PC寄存器指向一个内核中固定的异常处理入口(见lab3中不同异常处理跳转到的地址) ...