28

CPU从用户模式切换到内核模式:它到底做了什么?它是如何实现这种转变的?

编辑:

即使它依赖于架构,也请给我一个答案。架构由您决定。告诉我你知道的架构。

我想知道所有事情都会涉及到什么。

4

4 回答 4

35

注意:这主要与 x86 架构相关。这是一个稍微简化的解释。

过渡通常由以下原因之一引起:

  • 错误(例如页面错误或由执行指令引起的其他异常)
  • 中断(例如键盘中断或 I/O 完成)
  • 陷阱(例如系统调用)

通常发生的是系统检查中断描述符表 (IDT)。每个异常(中断、故障等)都有一个与之关联的数字,用于索引到该表中。

从这个表中,CPU 可以确定要运行的中断处理程序。

作为过渡的一部分,以下更改(通常)生效:

  • 切换到内核栈
  • EFLAGS 已保存
  • 代码段选择器和 EIP 被保存。
  • 堆栈段选择器和堆栈指针被保存
  • 开始执行中断处理程序
  • 保存通用寄存器(处理程序的工作)
  • 段选择器更改为内核选择器(处理程序的工作)

您现在处于内核模式。

希望有帮助:)

于 2010-03-20T21:43:57.900 回答
4

这取决于系统,但通常的机制是某些用户态操作会导致软件中断。该中断使处理器切换模式并跳转到内核代码,然后内核代码检查程序尝试执行的操作(系统调用?),然后执行请求的操作并跳回用户模式代码。除了软件中断之外的其他机制也可能导致转换;例如,在抢占式多任务系统中,定时器中断可能会触发调度程序运行。

于 2010-03-19T17:04:59.103 回答
3

我的理解是,任何段寄存器的两个 LSB 为零的程序都将在内核模式下运行,而任何段寄存器的两个 LSB = 1 的程序都将在用户模式下运行。实际上,段 rgeisters 的两个 LSB 定义了特权级别(0 最高到 3 最低)

因此,要使 prgram 在内核模式下运行,您必须将段寄存器设置为 0010 hex(我相信)。我不确定如何在不覆盖其他内容的情况下将程序放置在该内存空间中 - 换句话说,链接器如何确保这一点?另外,如果你想从用户模式代码中调用内核模式代码,你必须弄清楚如何传递参数——它们没有使用相同的内存空间,所以不能通过内存引用传递数据。我想你必须在寄存器中传递它。

如果任何人能填补以上空白,我将不胜感激。

于 2012-11-18T07:28:07.350 回答
1

在 Windows 中,当您进行系统调用时,库例程会调用驻留在操作系统地址空间中的内核入口点。它反过来通过执行特定于此目的的指令(例如sysenter )将 CPU 带入管理员模式。它所做的基本上是在标志寄存器中设置一个位。这使操作系统能够使用特权指令。

于 2010-03-19T21:29:13.430 回答