一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情。
原文链接 xv6-riscv文档
2.2 用户模式、特权模式和系统调用
强大的隔离性需要在应用和操作系统之间有坚实的边界。如果应用程序出错了,我们不希望操作系统崩溃或者其他应用程序崩溃。相反的,操作系统因公能够清理失败的应用程序并且运行其他的应用程序。为了实现强大的隔离,操作系统必须让应用程序不能修改甚至读取操作系统的数据结构和指令,应用程序不能获取其他进程的数据。
CPU提供硬件支持来实现强大的隔离性。比如,RISC-V有三种CPU可以执行指令的模式:机器模式、特权模式和用户模式。在机器模式执行的指令拥有全部的特权,CPU从机器模式开始运行。机器模式通常情况下是用来构建计算机的。Xv6在机器模式执行一些代码然而跳转到特权模式。
在特权模式洗啊,CPU允许执行特权指令,比如,开中断和关中断,读写存储寄存器地址的页表。如果一个用户态的应用程序执行了一条特权执行,CPU不会执行这条指令并且会切换到特权模式,这样特权模式的代码可以终止这个进程,因为这个进程做了它不该做的事情。在第一章出现的图1.1展示了这个过程。引用程序只能执行用户模式指令,例如add指令,并且只能在用户空间运行,但是在特权模式下的软件可以执行特权指令并且被认为在内核空间执行。运行在内核空间或者特权模式的软件被称为内核。
想要调用像xv6中的read系统调用这样的内核函数的应用程序必须跳转到内核,应用程序不能直接调用内核函数。CPU提供了特殊的指令可以将CPU从用户模式切换到特权模式,并且从一个特定的位置进入内核。RISC-V提供ecall指令来实现这样的目的。一旦CPU切换到了特权模式,内核可以验证系统调用的参数,例如检查系统调用传递来的参数是不是应用程序的内存,然后决定应用程序是否允许进行请求的操作,例如检查应用程序是否允许写入到指定文件,然后拒绝或者指令该调用。内核控制进入到特权模式的进入点是很重要的,如果应用可以决定内核进入点的话,一个恶意的应用程序可以进入内核的某一段而跳过调用有效性的验证。
忙于毕设和工作,感谢阅读~