在用户模式下,您不能只切换到内核模式。用户和内核之间的交互是通过系统调用完成的。每个系统调用都提供一个定义的服务。用户发送服务名称(通常是数字)和所需参数。这是一个真实世界的例子,它是如何完成的。它是 x86 AT&T 风格的汇编程序。
它将系统调用名称移入 EAX 寄存器,将指向参数的指针移入 CPU 的 EBX 寄存器,然后发出软件中断号 42。中断处理将切换到内核模式。中断号在中断描述符表 (IDT) 中查找并调用在那里注册的函数,即系统调用处理程序。该处理程序在内核模式下执行。返回用户模式时,代码会将 EAX 的内容移动到变量 ret 中。
pok_ret_t pok_do_syscall (pok_syscall_id_t syscall_id, pok_syscall_args_t* args)
{
pok_ret_t ret;
uint32_t args_addr;
uint32_t id;
args_addr = (uint32_t) args;
id = (uint32_t) syscall_id;
asm volatile ( "movl %1,%%eax \n\t"
"movl %2,%%ebx \n\t"
"int $42 \n\t"
"movl %%eax, %0 \n\t"
:"=g"(ret)
:"g"(id), "g"(args_addr)
: "%eax" , "%ebx"
);
return ret;
}
OS Dev wiki是阅读更多相关信息的好地方。
所以你不只是切换到内核,而是你可以要求内核为你做一些事情。然后内核会告诉你它是否完成。