首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用陷阱表的目的是什么?

使用陷阱表的目的是什么?
EN

Stack Overflow用户
提问于 2020-09-16 02:57:52
回答 2查看 1.1K关注 0票数 0

我在读奥斯特的时候有个问题。问题是陷阱如何知道在操作系统中运行哪些代码?我知道这是个糟糕的主意,因为它意味着用户可以在内核中做任何事情。但我不清楚“想象一下跳进代码来访问一个文件,但在权限检查之后”一书中给出的例子,有人能解释一下吗?如果程序可以直接发出系统调用而不使用陷阱表,那么会发生什么情况呢?谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-16 03:14:03

陷阱表是系统调用处理程序通常用来调用所请求的操作服务例程的工具。它是一个受内核保护的表,因此不允许在任意地址上执行。相反,它将请求的服务(通常是少量的syscall.h)映射到提供该服务的函数。

应用程序执行如下操作:

代码语言:javascript
运行
复制
_open:
mov   $_SYS_OPEN, %r0
syscall
jmp-on-carry seterrno
ret

在syscall运算符上调用的内核中的一些代码执行以下操作:

代码语言:javascript
运行
复制
int n;
if ((n = Proc->reg[0]) < 0 || n >= _N_SYSCALLS) {
    return seterror(Proc, ENOSYS);
} else {
    return (*sys_call_table[n])(Proc);
}

您所使用的操作系统的细节各不相同,但总体思路是相同的,并且自1970年代以来一直保持相对不变。

票数 1
EN

Stack Overflow用户

发布于 2022-06-18 13:17:47

嘿,我也是学习这一章节的同学。我也把这个问题搞糊涂了。然而,我在网上找到了这张幻灯片来帮助我。

https://my.eng.utah.edu/~cs5460/slides/Lecture03.pdf

(旁注:截至发帖之时,有1到24节讲座可供选择,似乎不公开上课。)感谢约翰·雷格尔教授!)

总结一下我的理解,对单个系统调用(如读取I/O、叉进程等)的陷阱调用是不存在的。相反,我们使用一个陷阱来表示指令的类。当这个“系统调用”陷阱被调用时,硬件就会预先形成一个从用户模式到内核模式的上下文切换。但是,由于只为系统调用定义了一个陷阱,因此内核需要知道应用程序要执行哪些操作(同样是read、叉等),以及系统调用指令的参数。(我的意思是,当执行系统调用陷阱时,参数位于CPU中的指定寄存器中,以供内核读取。)

为了解决这个问题,我们可以让用户模式应用程序直接传递给它要执行的指令的内存引用以及它的参数(例如,内核空间中的内存地址0x8F0FA可能是读取函数的入口点)。因此,当发生上下文切换时,硬件将内核PC直接置于系统调用指令需要的位置。这是个坏主意,因为如果用户模式可以传递内存位置在内核空间中运行代码.然后,用户模式应用程序可以直接调用任何内核指令,从而绕过操作系统的安全性和安全性。我们需要对这种功能进行某种限制。

更好的解决方案是使用陷阱表。与所需函数的直接内存位置不同,用户模式应用程序将一个“映射密钥”传递给系统调用陷阱,而不是“直接内核指令”。在系统启动后,用户模式应用程序可以公开使用这些密钥。硬件不是将PC放在任意的内存位置,而是总是将内核放在陷阱处理程序函数上。然后,该函数将获取映射的密钥,并在应用程序所需的陷阱表的私有化值中找到确切的系统调用函数。

如果没什么用的话,去看看滑梯吧!

编辑:我犯了一个错误,在应用程序已经处于内核模式之后不会调用陷阱。陷阱是用来做开关的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63912466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档