『阿男的Linux内核世界』*13 从User Space到Kernel Space(一)*

『阿男的Linux内核世界』*13 从User Space到Kernel Space(一)*

Linux操作系统在设计上分为两部分,分别是User Space和Kernel Space。我们在这篇文章里讲解一下,一个Process是如何在User Space与Kernel Space之间切换运行的。

首先我们得明白一点,就是一个Process在什么时候会在User Space运行,什么时候会在Kernel Space运行?

其实我们之前几篇文章已经学习了好多关于Process的只是,大家应该已经对Process有了一个直观的认识:Process就是正在运行的程序。既然是正在运行的程序,那么Process具有以下特征:

  • 代码被读入到内存之中
  • 使用内存保存所需数据
  • 使用CPU执行指令
  • 和输入输出设备打交道

此外,每一个Process是运行在Kernel提供的虚拟资源之上的:

  • Process使用的内存空间是Kernel提供的统一模型的虚拟内存空间
  • Process并不能访问所有的CPU寄存器
  • Process不可以执行一些CPU只允许Kernel执行的汇编指令
  • Process不可以直接和输入输出设备打交道

以上几条,阿男为大家逐一说明一下。

首先,我们使用Intel架构的CPU为例说明,因为大家基本上都使用Intel架构的CPU,可能很少人会使用RISC指令集架构的芯片,比如SPARC。此外,我们使用Intel架构的CPU说明,很多设计上面的思想在其它架构的CPU上也适用,只是细节的不同。我们的重点还是放在讲设计思想上面。

要知道,CPU有很多寄存器是不开放给User Space使用的,比如IDTR寄存器,,也就是保存Interrupt Descriptor Table起始地址的寄存器。类似这种寄存器是不会开放给User Space使用的。至于什么是Interrupt Descriptor Table,什么是IDTR寄存器,阿男后续会给大家讲,总之现在我们要知道,User Space不能访问所有的CPU寄存器就可以了。

其次,CPU还有很多指令是不开放给User Space使用的。所有的程序,不管你用什么语言写,运行在什么操作系统之下,最终都是转化为最底层的机器码。机器码因为都是1010这样的二进制代码,不好阅读,所以和它一一映射的就是汇编代码。我们所讲的CPU所执行的指令就是指汇编代码。

而汇编代码就是由CPU的指令集所组成。CPU有很多基本的内存操作和运算相关的指令,比如MOVADD这些。像这些指令,User Space是可以执行的,并没有问题。

但是还有很多和硬件设备以及真正的物理内存打交道的指令,是只有Kernel才有权运行的,比如LGDTLLDT这些掌管CPU与Kernel相关的特定寄存器的指令,User Space是无权执行的。就算你直接写汇编代码,里面使用这些高权限指令,编译完成后运行,你会发现CPU会抛出异常给Kernel,然后Kernel就会把异常直接报错给你。

因此要明白,CPU的这种权限管理是硬件级别的。在Intel的CPU架构下,这些不同的运行模式叫做Ring^1

输入图片说明

如上图所示,CPU有不同的运行模式,就是不同的Ring,每一层Ring所拥有的权限不一样,所能访问的寄存器和执行的指令集也不同。

因此当计算机开机启动以后,Kernel从BIOS手里接管过来CPU的时候,就是接管了最高权限Ring 0,后续User Space在Kernel的管理下,会运行在Ring 3,这个对于Windows NT内核也是一样的,现代的操作系统基本上都会使用CPU提供的这种硬件级别的安全保护功能。可以看到,现代操作系统和CPU之间的联系早已经非常紧密。

转载于:https://my.oschina.net/u/3195023/blog/821066

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值