从用户模式切换到内核模式

时间:2013-09-27 18:17:19

标签: operating-system kernel

在我的操作系统类中,我被问到从用户切换到内核模式是否具有特权。这不是特定于操作系统的。起初我认为是的,但它似乎是一个很大的Catch 22.我提到了我的教科书:

  

硬件允许特权指令仅在中执行   内核模式。 ...

     

切换到内核模式的指令是特权的一个示例   指令。

     加涅,加格; Abraham Silberschatz; Peter B. Galvin(2010-01-26)。   操作系统概念(第22页)。 Wiley Higher Ed。 Kindle版。

所以我们从用户模式开始。要切换到内核模式,需要特权指令。特权指令必须在内核模式下完成,因此我们必须切换到内核模式以启用切换到内核模式。

我认为系统不允许用户直接将自己切换到内核模式,但是当用户试图执行另一个特权指令时,它由内核完成。这是对的吗?

4 个答案:

答案 0 :(得分:32)

在用户模式下,您不能只切换到内核模式。用户和内核之间的交互是通过系统调用完成的。每个系统调用都提供一个定义的服务。用户发送服务名称(通常是数字)和所需参数。 这是一个真实世界的例子。它是x86 AT& T风格的汇编程序。

它将系统调用名称移动到EAX寄存器中,指向CPU的EBX寄存器中的参数的指针,然后发出软件中断号42.中断处理将切换到内核模式。在中断描述符表(IDT)中查找中断号,并调用在那里注册的函数syscall处理程序。此处理程序在内核模式下执行。返回用户模式后,代码会将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是了解更多相关信息的好点。

所以你不要只是切换到内核,但你可以让内核为你做点什么。然后内核会告诉你它是否已经完成。

答案 1 :(得分:6)

这是第8版中引入的拼写错误并保留在第9版。在第七版,第19页,它反而说:

  

“切换到用户模式的指令是特权的示例   指令“。

这显然更有意义。

答案 2 :(得分:3)

通常,一组指令并不是真正以一般方式切换到内核模式,而是请求系统服务。所以这些切换到内核模式,但仅限于调用操作系统为了被用户代码调用而设置的某些功能的上下文。

在大多数现代系统中,即使这被实现特定功能的API层隐藏,其中一部分功能可能正在进行上述操作系统调用。

但总的来说,用户代码无法做到相当于说“从现在开始,我希望在内核模式下运行”。

答案 3 :(得分:0)

在用户域中,您通过对内核的系统调用请求特权操作,内核根据需要执行切换到内核模式。用户正在使用API​​,内核正在执行特权操作。