我一直在学习Windows中驱动程序开发的基础知识我一直在找到术语 Ring 0 和 Ring 3 。这些是指什么?它们与内核模式和用户模式相同吗?
答案 0 :(得分:46)
Linux x86响铃使用情况概述
了解Linux中的环如何使用可以让您很好地了解它们的用途。
在x86保护模式下,CPU始终处于4个环之一。 Linux内核仅使用0和3:
这是kernel vs userland最硬,最快的定义。
为什么Linux不使用第1和第2环:CPU Privilege Rings: Why rings 1 and 2 aren't used?
目前的戒指是如何确定的?
当前的戒指是通过以下组合选择的:
全局描述符表:GDT条目的内存表,每个条目都有一个字段Privl
,用于对环进行编码。
LGDT指令将地址设置为当前描述符表。
段注册CS,DS等,它指向GDT中条目的索引。
例如,CS = 0
表示GDT的第一个条目当前对执行代码有效。
每枚戒指可以做什么?
CPU芯片是物理构建的,因此:
ring 0可以做任何事情
ring 3无法运行多条指令并写入多个寄存器,最值得注意的是:
无法改变自己的戒指!否则,它可以将自己设置为响铃0并且响铃将是无用的。
换句话说,无法修改当前确定当前响铃的当前segment descriptor。
无法修改页面表:How does x86 paging work?
换句话说,无法修改CR3寄存器,并且分页本身会阻止修改页表。
这可以防止一个进程看到其他进程的内存,以确保安全/易于编程。
无法注册中断处理程序。这些是通过写入内存位置来配置的,这也可以通过分页来防止。
处理程序在环0中运行,会破坏安全模型。
换句话说,不能使用LGDT和LIDT指令。
无法执行in
和out
等IO指令,因此可以进行任意硬件访问。
否则,例如,如果任何程序可以直接从磁盘读取,则文件权限将毫无用处。
更确切地说,感谢Michael Petch:操作系统实际上可以在环3上允许IO指令,这实际上是由Task state segment控制的。
如果戒指3首先没有这样做,那么戒指3是否允许这样做是不可能的。
Linux总是不允许它。另见:Why doesn't Linux use the hardware context switch via the TSS?
程序和操作系统如何在响铃之间转换?
当CPU打开时,它开始在环0中运行初始程序(很好,但它是一个很好的近似值)。您可以将此初始程序视为内核(但它通常是一个引导加载程序,然后仍然在内环0中调用内核)。
当userland进程希望内核为其执行某些操作(如写入文件)时,它会使用生成中断的指令(如int 0x80
or syscall
)来通知内核。 x86-64 Linux系统调用hello world示例:
.data
hello_world:
.ascii "hello world\n"
hello_world_len = . - hello_world
.text
.global _start
_start:
/* write */
mov $1, %rax
mov $1, %rdi
mov $hello_world, %rsi
mov $hello_world_len, %rdx
syscall
/* exit */
mov $60, %rax
mov $0, %rdi
syscall
编译并运行:
as -o hello_world.o hello_world.S
ld -o hello_world.out hello_world.o
./hello_world.out
当发生这种情况时,CPU会调用内核回调处理程序,内核在引导时注册该处理程序。这是concrete baremetal example that registers a handler and uses it。
此处理程序在ring 0中运行,它决定内核是否允许此操作,执行操作,并在ring 3中重新启动userland程序.x86_64
当使用exec
系统调用(或内核will start /init
)时,新用户空间进程的内核prepares the registers and memory,然后它跳转到入口点,将CPU切换到响铃3
如果程序试图做一些顽皮的事情,比如写入禁止的寄存器或内存地址(因为分页),CPU也会调用第0环中的一些内核回调处理程序。
但是由于用户区很淘气,这次内核可能会杀死进程,或者发出信号警告。
内核启动时,会设置一个固定频率的硬件时钟,定时产生中断。
此硬件时钟生成运行0的中断,并允许它安排唤醒哪些用户进程。
这样,即使进程没有进行任何系统调用,也可能发生调度。
有多个戒指有什么意义?
分离内核和用户空间有两个主要优点:
如何玩它?
我创建了一个裸机设置,应该是直接操纵戒指的好方法:https://github.com/cirosantilli/x86-bare-metal-examples
不幸的是,我没有耐心做出用户名的例子,但我确实做了分页设置,所以userland应该是可行的。我很乐意看到拉动请求。
或者,Linux内核模块在ring 0中运行,因此您可以使用它们来尝试特权操作,例如:读取控制寄存器:How to access the control registers cr0,cr2,cr3 from a program? Getting segmentation fault
这是一个convenient QEMU + Buildroot setup来试用它而不会杀死你的主机。
内核模块的缺点是其他kthread正在运行并且可能会干扰您的实验。但理论上你可以用内核模块接管所有中断处理程序并拥有系统,这实际上是一个有趣的项目。
否定次数
虽然在英特尔手册中实际上没有引用负环,但实际上CPU模式还具有比环0本身更多的功能,因此非常适合负极环#34;名。
一个例子是虚拟化中使用的虚拟机管理程序模式。
有关详细信息,请参阅:https://security.stackexchange.com/questions/129098/what-is-protection-ring-1
<强> ARM 强>
在ARM中,环被称为异常级别,但主要思想保持不变。
ARMv8中存在4个异常级别,通常用作:
EL0:userland
EL1:内核(&#34;主管&#34;在ARM术语中)。
使用svc
指令(SuperVisor Call)输入,以前称为swi
before unified assembly,这是用于进行Linux系统调用的指令。 Hello world ARMv8示例:
.text
.global _start
_start:
/* write */
mov x0, 1
ldr x1, =msg
ldr x2, =len
mov x8, 64
svc 0
/* exit */
mov x0, 0
mov x8, 93
svc 0
msg:
.ascii "hello syscall v8\n"
len = . - msg
在Ubuntu 16.04上使用QEMU进行测试:
sudo apt-get install qemu-user gcc-arm-linux-gnueabihf
arm-linux-gnueabihf-as -o hello.o hello.S
arm-linux-gnueabihf-ld -o hello hello.o
qemu-arm hello
EL2:hypervisors,例如Xen。
使用hvc
指令(HyperVisor Call)输入。
虚拟机管理程序是指操作系统,操作系统属于用户空间。
例如,Xen允许您同时在同一系统上运行多个操作系统(如Linux或Windows),并且它将操作系统彼此隔离,以确保安全性和调试的简便性,就像Linux用于用户程序一样。
虚拟机管理程序是当今云基础架构的关键部分:它们允许多台服务器在单个硬件上运行,使硬件使用率始终接近100%并节省大量资金。
例如,AWS使用Xen直到2017年its move to KVM made the news。
EL3:又一个级别。 TODO的例子。
使用smc
指令(安全模式呼叫)输入
ARMv8 Architecture Reference Model DDI 0487C.a - 第D1章 - AArch64系统级程序员模型 - 图D1-1说明了这一点:
请注意,ARM可能由于后见之明的优势而具有比x86更好的命名约定,而不需要负级别:0表示较低级别,3表示最高级别。较高级别往往比较低级别创建更多。
可以使用MRS
指令查询当前的EL:what is the current execution mode/exception level, etc?
ARM不要求存在所有异常级别,以允许不需要该功能的实现来节省芯片区域。 ARMv8&#34;异常级别&#34;表示:
实现可能不包括所有异常级别。所有实现必须包括EL0和EL1。 EL2和EL3是可选的。
例如,QEMU默认为EL1,但可以使用命令行选项启用EL2和EL3:qemu-system-aarch64 entering el1 when emulating a53 power up
在Ubuntu 18.10上测试的代码片段。
答案 1 :(得分:12)
英特尔处理器(x86和其他)允许应用程序限制功率。为了限制(保护)IO,内存,端口等关键资源,CPU与操作系统(本例中为Windows)联络,分别提供映射到内核模式和用户模式的权限级别(0最高权限为3)。
因此,操作系统在环0中运行内核代码 - 由CPU提供的最高权限级别(0) - 以及环3中的用户代码。
有关详细信息,请参阅http://duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection/
答案 2 :(得分:2)
嗯,这是一个相当广泛的问题。但是,您可以使用谷歌或只是阅读维基百科上有关这些内容的文章,以获得第一个概述。