首页 理论教育 HelloChina系统调用的实现-操作系统实现之路

HelloChina系统调用的实现-操作系统实现之路

时间:2023-10-21 理论教育 版权反馈
【摘要】:在Intel x86 CPU上,Hello China系统调用利用了CPU提供的中断处理机制,采用第128号软件中断(异常)作为系统调用的入口点。但在Hello China初始化的时候,把从第32号开始的所有中断描述表表项,都设置成了中断调用门。通用中断处理程序采用C语言实现,该处理程序首先判断当前发生的是异常还是中断。若是异常,则调用DispatchException函数,从而根据异常向量调用对应的异常处理函数。

HelloChina系统调用的实现-操作系统实现之路

在Intel x86 CPU上,Hello China系统调用利用了CPU提供的中断处理机制,采用第128号软件中断(异常)作为系统调用的入口点。但在Hello China初始化的时候,把从第32号开始的所有中断描述表(IDT)表项,都设置成了中断调用门。中断调用门与异常门不同的是,在中断调用门中,CPU在调用中断处理程序前,会自动清除CPU的中断允许标志。这样的处理是适合硬件中断的处理要求的,但对于系统调用来说,就不太合适了。因此,需要修改第128号中断(异常)的入口处理程序,通过软件方式打开中断标志。下面是第128号中断的处理程序:

该入口程序与所有硬件中断处理程序一样,首先保存通用寄存器,把异常或中断号压入堆栈,然后再调用通用中断处理程序(gl_general_int_handler标号处的函数)。与普通中断处理程序的唯一不同是,在开始处,就打开了CPU的中断标志位(sti指令)。gl_syscall作为第128号中断的处理程序,在初始化中断描述符表(IDT)的时候,就被填写到了中断描述符表的第128号表项中。这样一旦用户应用程序代码执行了int 0x80指令,CPU就根据中断描述符表寄存器(idtr)的内容,找到IDT的首地址,然后再定位到第128号表项,从中找到中断处理程序的入口地址(即gl_syscall标号),跳转到该处执行。因此gl_syscall标号处的代码,就是系统调用存根的一部分,注意不是全部,因为gl_syscall又进一步调用了通用中断处理程序(gl_general_int_handler),而通用中断处理程序是用C语言编写的一个通用函数,这个函数根据中断编号,又调用了系统调用分发函数,系统调用分发函数才根据系统调用功能号,调用了真正的系统功能函数。由此可见,系统调用的存根,可能是由多个函数组成的,可以说,从128号中断处理程序(gl_syscall标号的代码)开始,一直到真正的功能函数被调用之前的所有代码,都叫做系统调用存根。

通用中断处理程序采用C语言实现,该处理程序首先判断当前发生的是异常还是中断。若是异常,则调用DispatchException函数,从而根据异常向量调用对应的异常处理函数。若是中断,则调用DispatchInterrupt函数,该函数根据中断向量号调用对应的处理程序。不论中断还是异常,处理方式都是相通的,就是根据中断或异常向量号,索引一个全局数组,这个全局数组记录了处理对应中断或异常的中断对象(InterruptObject),在中断对象中记录了处理函数的入口地址。对于异常来说,这个处理函数是SyscallHandler,下面是其实现代码(为了便于描述,做了适当简化):(www.xing528.com)

显然,这个函数无非是根据系统调用的功能号和传递过来的参数,调用了操作系统内核提供的功能函数。__SYSCALL_PARAM_BLOCK是定义的一个结构体,用于传递系统调用相关的所有信息,包括系统调用功能号、对应的参数,调用完成后的返回值,也是存放在这个结构体中。这个结构体的具体定义和用法,将在下一节中做详细介绍。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈