内核态权限和用户态权限

内核态权限和用户态权限

系统调用

这个可以看一下系统调用的过程,应用代码通过int 80发起对系统调用,通过中断处理后执行对应的系统函数,这时候的权限也变了,即内核态。比如cpu有0,1,2,3四种权限等级,有些操作是0等级才能做的,linux使用0和3两种,就是内核态和用户态。简单来说,就是低权限的应用代码通过高权限的操作系统去做某些事情,系统提供的入口就是系统调用。

这是处理器的两种工作模式。差别就是内核模式下什么指令都可以执行,用户模式下有些指令一执行就会引发内部中断。内核模式、用户模式,这只是个简单的两级划分。实际的处理器可以划分出若干层级来,但不管两级还是多级,道理都是一样的。内核模式跟用户模式之间切换,一条指令就可以完成。你把它想象成处理器这台机器身上的一个模式开关被拨动了一下即可。

本质就是权限管理,具体一点就是资源的管理。

OS的本质就是给用户提供服务。所以用户态的程序可以访问OS的接口,就是常说的系统调用,但是不能访问OS内部的数据。反过来,OS可以访问应用的数据,但是不能调用应用的接口,因为这样会有安全漏洞。

在这里有一个特例,就是root用户。严格设计的OS,应该是对所有用户同等对待,也就是连root都只能访问OS的接口而不能访问OS的内部数据,只不过root可以访问特权接口而普通用户不行。但是为了方便管理,有内核镜像文件系统这种设计。所以实际上root用户可以访问OS的内部数据。所以root用户始终是系统的安全隐患。所以安全系统需要对特权权限做分离,分成管理员和审核员的角色,不能一个人把所有的活全干完。

切换的本质就是切换身份,对于计算机资源,你是请求服务的还是提供服务的?

开机启动

按照传统BIOS的启动方式来说一下吧,不讨论UEFI了。

开机CPU处于16位的实模式,这个模式没有权限的概念,所有东西都是Ring0。

MBR(磁盘引导扇区里的代码)就是在这个模式下运行的。MBR的作用是加载PBR(分区的引导扇区的代码)或BootLoader(比如GRUB)
PBR的作用是加载BootLoader(比如Windows2000/XP/2003的ntldr和Windows Vista/2008/7/2008R2/8/2012/8.1/2012R2/10/2016的bootmgr)
PBR跟MBR一样,也是在实模式下运行的,那个模式只有RING 0。
BootLoader启动的时候也是实模式,BootLoader在内存里建立转换到32位保护模式/64位长模式需要的各种数据结构,然后把CPU转换到32位/64位模式,并跳转到BootLoader的32位/64位的部分,跳转时指定权限RING 0。
这部分代码加载各种内核的东西,初始化操作系统内核。
然后内核加载用户态的东西,调用的时候(怎么调用的不记得了)指定权限RING 3(CPU有个标志位来判断当前是RING几),于是被调用的东西只能执行一部分指令。
用户态的东西要调用系统的东西,通过Fast Fail/Sys Call之类的我记不清了的东西跳转到一个RING 0的状态下,然后调用系统的运行在RING 0模式的代码。

windows是使用了0和3,主要是因为兼容的原因(因为有些处理器只支持两种有些级别,比如Compaq Alpha处理器)。资料来源是《软件调试》第177页。

x86处理器

泻药,我只说x86上的情况吧。

x86是cs段选择子的rpl就是cpl,四种可能的取值对应ring0到ring3。在x86上面实现操作系统时ring0用来对应内核态,ring3对应用户态,其他两种一般不被使用。

可以参考这个CPU Rings, Privilege, and Protection,里面有图,可以看到cpl位于16位的选择子的低0到1位。

这个权限管理模式背后的原理其实很容易理解。就比如你是国家统治阶层,你不让民众使用你统治阶层的特权,那民众永远是民众没有机会成为统治阶级。

保护模式下CS寄存器的低两位rpl(请求特权级)决定了当前CPU的特权等级:

这部分虽然是显式的写在CS的值里的,但实际上是隐藏在段寄存器的隐藏部分的。

最开始的时候CS值是引导程序给的,引导程序置上PE位以后,代码还在16位模式下,CPU会给当前的CS寄存器隐藏部分添加一个RPL,这个RPL是0,之后等跳转到保护模式以后,由代码控制自己选择到那个RPL上跑。

如果自己写一个引导程序,到保护模式以后,不加准备直接切到R3级别的CS的话,那么后面的代码就是R3的权限了。

你懂机器码就一定能写出R0的代码吗?不一定。

你的代码是被OS的加载器加载的,加载的过程中,CS的初始值是确定的,如果操作系统没给你R0的权限,你的代码必然要在R3上执行,在保护模式下,R3状态下的指令想通过MOV来改变CS是有可能触发异常的,而OS能决定你的动作是否能触发异常。

所以如果OS把这些路否封死了,你的代码只能老老实实的在R3上执行。

我前面说了,引导程序可以在进入保护模式后直接把自己的代码设置成R3权限,这是没问题的,但如果切保护模式之前,没把该准备的东西准备好,那么你的代码可能就一直在R3模式下跑了,想从R3到R0是没门的。

另外,实模式下操作系统处于R0状态。

根据评论里的补充,前面有一块我说的不太正确,RPL虽然是在CS里,但CS只是个index selector,RPL实际保存的地方是段寄存器的隐藏部分,这部分是不可见也不能直接修改的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值