linux内核如何在用户模式和内核模式堆栈之间切换?

时间:2016-07-13 19:38:48

标签: linux linux-kernel

当系统调用或中断出现时,linux内核如何在用户模式和内核模式堆栈之间切换?我的意思是什么是确切的机制 - 用户模式堆栈指针会发生什么以及内核模式堆栈指针来自何处?硬件做了什么,软件必须做什么?

1 个答案:

答案 0 :(得分:4)

以下所有字词均为x86。

我将描述整个系统调用路径,此答案将包含所请求的信息。

首先,您需要了解interrupt descriptor table是什么。该表存储异常/中断向量的地址。系统调用是一个例外。要引发异常用户代码,请执行

int x

装配说明。每个例外,包括系统调用都有自己的编号。在x86 linux上,这将看起来像

int 0x80

int指令是一个复杂的多步指令。以下是对其作用的解释:

1。)从IDT中提取descriptor(存储在特殊寄存器中的IDT地址)并检查CPL< = DPL。 CPL是当前的权限级别,可以从CS寄存器中读取。 DPL存储在IDT描述符中。 因此,您无法通过int指令直接从用户空间生成一些异常(例如页面错误)。如果您尝试这样做,您将获得general protection exception

2.)处理器切换到TSS中定义的堆栈。 TSS之前已初始化,并且已包含ESP和SS的值,它保存内核堆栈地址。所以现在ESP指向内核堆栈。

3.)处理器推送到新切换的内核堆栈用户空间寄存器:ss, esp, eflags, cs, eip。我们需要在服务系统调用后返回,对吗?

4.)下一个处理器从IDT描述符设置CS和EIP。该地址定义了异常向量入口点。

5.)这里我们在内核的syscall异常向量中。

关于ARM的话很少。 ARM没有TSS,它已经禁止每模式寄存器。因此,对于SVC和USR模式,您有单独的堆栈指针。如果您对此感兴趣,请查看trap entry code

Interestring链接: MIT JOS lab 3XV6 manual