内核如何知道CPU是处于用户模式还是内核模式?

19

由于CPU在用户/内核模式下运行,我想知道内核如何确定这一点。我的意思是,如果调用了系统调用,内核会代表进程执行它,但内核如何知道它正在内核模式下执行?


也许你指的是用户上下文/进程上下文与内核上下文/中断上下文? - ninjalj
5个回答

42
可以通过代码段寄存器(CS)中设置的特权级别来判断当前是否处于用户模式或内核模式。从由RIP或EIP寄存器(取决于您使用的是x86_64还是x86)指向的内存加载到CPU中的每条指令都将从全局描述符表(GDT)中描述的段中读取当前代码段描述符所描述的段。代码段描述符的低两位将确定代码执行的当前特权级别。当发生系统调用时,通常是通过软件中断完成的,CPU会检查当前的特权级别,并且如果它处于用户模式,则会根据系统调用的软件中断门描述符将当前代码段描述符更换为内核级别,并在新的内核级别堆栈上进行堆栈切换并保存当前的标志、用户级别CS值和RIP值。当系统调用完成后,用户模式CS值、标志和指令指针(EIP或RIP)值将从内核堆栈中恢复,并进行堆栈切换以返回当前正在执行的进程的堆栈。请注意,html标记应该原样保留。

1
这是一个非常丰富的评论,谢谢。+1。如果你恰好有一些进一步阅读的文档,我很想了解更多关于它的信息。 - qdii
5
保护级别以及如何检测它们的信息,记录在英特尔开发者指南第三卷A的第5章中。请点击此链接获取更多信息:http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html - Jason
@Jason,当你说“代码段描述符的低两位”时,你指的实际上是代码段选择器吗? - daniel
@ngwdaniel 嘿,丹尼尔,你能澄清一下你的问题吗? - Jason

7

如果它正在运行内核代码,那么它就处于内核模式。从用户空间转换到内核模式(例如进行系统调用)会导致上下文切换发生。在这个上下文切换的过程中,CPU模式会被改变。


3

内核代码只能在内核模式下执行。不存在内核代码可以在用户模式下执行的情况。当应用程序调用系统调用时,它将生成一个陷阱(软件中断),并且模式将切换到内核模式并执行系统调用的内核实现。一旦完成,内核将切换回用户模式,并且用户应用程序将继续在用户模式下处理。


这个问题还没有得到答复。 - Varun Sharma

2
术语称为“监管者模式”,适用于x86 / ARM以及许多其他处理器。
阅读此文(仅适用于x86 CPU):

http://en.wikipedia.org/wiki/Ring_(computer_security)

“Ring 0到3是x86 CPU的不同特权级别。通常只使用Ring0和3(内核和用户),但现在Ring1也有用途(例如,VMWare用它来模拟客户机对Ring0的执行)。只有Ring0具有完全权限运行某些特权指令(如lgdt或lidt),因此在汇编级别进行良好的测试当然就是执行这些指令,并查看您的程序是否遇到任何异常。”
“阅读此内容以真正确定您当前的特权级别(寻找CPL,这是Jason答案的图解):”

http://duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection


第一个链接不是一个正确的链接。 - Hafiz Muhammad Shafiq

1

这是一个简单的问题,不需要像上面提供的专家评论。

问题是CPU如何知道它是内核模式还是用户模式。 答案是“模式位”...

它是CPU寄存器集中状态寄存器中的一位。 当“模式位=0”时,被认为是内核模式(也称为监视器模式、特权模式、保护模式等等...) 当“模式位=1”时,被认为是用户模式...用户现在可以执行其个人应用程序而不受任何特殊内核干扰。

如此简单...是吧?


1
提供更少的细节。由于这个问题期望有解释,但不需要详细阐述。 - Hafiz Muhammad Shafiq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接