![](https://csdnimg.cn/release/download_crawler_static/86297452/bg6.jpg)
在用户程序使用系统调用之前,我们首先要对系统调用表进行初始化。其次,由于我们的系统调用
是通过0x80号中断来完成的,我们加入0x80中断对应的中断描述符。如下所示,代码放置在
src/kernel/syscall.cpp 中。
我们已经知道,每一个系统调用号都有一个处理这个系统调用的函数,实际上就是操作系统向用户
程序提供的服务的约定。这些系统调用的函数被统一放在系统调用表中,如下所示。
system_call_table 的每一个元素是系统调用的处理函数的地址。
我们希望通过0x80中断从特权级3(用户态)到特权级0(内核态)转移,中断描述符中的代码段选择子
的RPL=0,注意到 InterruptManager::setInterruptDescriptor 默认中断描述符的代码段选择子是
DPL=0的平坦模式代码段选择子,因此我们直接调用这个函数设置中断描述符即可。注意,我们需要设
置中断描述符的DPL=3,否则会由于特权级保护导致用户程序无法使用这个中断。
asm_system_call_handler 是0x80号中断的处理函数,如下所示。
#include "memory.h"
#include "program.h"
#include "syscall.h"
// 中断管理器
InterruptManager interruptManager;
// 输出管理器
STDIO stdio;
// 内存管理器
MemoryManager memoryManager;
// 进程/线程管理器
ProgramManager programManager;
// 系统调用
SystemService systemService;
#endif
void SystemService::initialize()
{
memset((char *)system_call_table, 0, sizeof(int) * MAX_SYSTEM_CALL);
// 代码段选择子默认是DPL=0的平坦模式代码段选择子,DPL=3,否则用户态程序无法使用该中断描述符
interruptManager.setInterruptDescriptor(0x80, (uint32)asm_system_call_handler, 3);
}
int system_call_table[MAX_SYSTEM_CALL];
; int asm_systerm_call_handler();
asm_system_call_handler: