前言

实模式,保护模式,分段,分页,虚拟内存,内核态,用户态,如果你对这些术语之间的关系非常熟悉,那就不用继续看了。这篇主要记录我对用户态/内核态的一些理解,如有不对还请指教。

下述说明均为 x86-32 模式。

简述

分段/分页机制实现了逻辑地址到物理地址的转换,为每个程序提供了自己独立的虚拟内存空间,与其他应用程序进行隔离,防止修改其他程序相关数据。开启了分页机制之后,CPU 硬件会对所有代码进行内存映射处理,不管是应用程序还是操作系统,都会使用虚拟内存机制。

对于4G 线性地址空间而言, linux 将最高 1G 空间映射为内存使用的空间,除去高端内存等小范围概念,基本上内核的地址减去 PAGE_OFFSET 偏移就是其实际物理地址。注意这里我没有说 4G 线性地址空间的主体,它的主体是所有的进程,甚至包括内核自身。 每个进程都有自己的 CR3 ,每个进程的 CR3 的地址映射的最高 1G 都是一样的,是通用的内核本身。

刚开始启动的时候内核是作为一个可执行程序启动,但在启动完成后当有系统调用时,内核代码开始执行,此时它所使用的 CR3 还是原进程的 CR3,所以我们会说一个程序在内核态运行。

我们为什么需要用户态/内核态之间的切换?

用户态/内核态 不是原因,只是结果,只看结果是看不出什么的。引入 用户态/内核态 的原因是因为 privilege level, 用户态/内核态的区分只是实现 privilege protection 的一种形式,而这种方式依赖于 分段/分页来实现。

内存隔离与保护 ----------------> 分段/分页
privilege(特权等级) ----------------> 用户态/内核态

假设只有分段/分页,其依赖于 GDT/LDT 与 CR3 寄存器指向的 page structure, 乍一看提供了隔离,但是如果没有 privilege level 的保护,应用程序可以自己修改自己的 CR3 指向的内存映射,这个内存保护也就形同虚设了,更不用提一些危险的指令了。

假设只有privilege level,那也肯定不行,甚至连多程序运行都不可能。

所以说区分内核态/用户态除了提供系统调用功能,更多的是进行 privilege 保护,不同模式下只允许运行对应的 CPU 指令。所有运行在内核态的代码共享一个虚拟内存空间,也就是通过分段/分页机制使得所有进程的 3G~4G 线性地址空间指向同一块区域,也就是内核区域。从这个方面来看,此时操作系统不再是启动时的可执行程序,更像是一个单例的共享库一样给所有进程使用。许多图片上将操作系统画成应用程序下的独立一层应该更符号这个结构。

总结

之所以写这篇文章是在自制操作系统的过程中对内核的虚拟地址配置有所疑问,不理解所有程序共用 3G~4G内存的原因,很多文章一上来就会告诉你这是内核态使用,我相信从 特权等级 的概念引申出去了解内核态和用户态会更为简单。

处理器在 protected mode 下的 protection的更多相关文章

  1. 【初学者常见问题】一脚踏入protected埋下的陷阱

    受保护的(protected)——声明该成员的类的子类可以访问这个类的成员(但有一定的限制),并且,声明该成员的包内部的任何类也可以访问这个成员 protected修饰符参考:http://www.3 ...

  2. ASP.NET Core 数据保护(Data Protection 集群场景)【下】

    前言 接[中篇],在有一些场景下,我们需要对 ASP.NET Core 的加密方法进行扩展,来适应我们的需求,这个时候就需要使用到了一些 Core 提供的高级的功能. 本文还列举了在集群场景下,有时候 ...

  3. Intel汇编语言程序设计学习-第二章 IA-32处理器体系结构-下

    2.2  IA-32处理器体系结构 如前所述,IA-32是指始于Intel386直到当前最新的奔腾4的系列的处理器(额...这本书是什么时候写的啊,表示现在应该是I7啊),在IA-32的发展过程中,I ...

  4. ARM 处理器:RISC与CISC 是什么?【转】

    转自:https://blog.csdn.net/willsun2017/article/details/83388990 完全看懂 ARM 处理器:RISC与CISC 是什么? 历史.架构一次看透 ...

  5. Linux下开启关闭SeLinux

    SELinux (Security-Enhanced Linux) in Fedora is an implementation of mandatory access control in the ...

  6. Centos下搭建ftp服务器

    完全不用那么麻烦,直接可以用xshell中自带的传输文件功能,下载客户端xftp安装就行,不用配置,可以在windows系统向Linux系统的任何文件地方上传下载文件,简单方便,大大节约时间, vsf ...

  7. Linux下禁用、启用SeLinux

    一些Linux默认都是启用SeLinux的,在安装操作系统的时候我们可以选择开启或者关闭SeLinux,但是在安装完系统之后又如何开启与关闭呢? 在/etc/sysconf下有一个SeLinux文件, ...

  8. CentOS_5.6下使用cmake编译MySQL_5.5.11

    MySQL 最新的版本5.5.11需要cmake编译安装,估计以后的版本也会采用这种方式,网上找了一些安装方法有些地方是错的,自己整理一份 所以特地记录一下安装步骤及过程,以供参考!1 mysql 5 ...

  9. CentOS_5.6下使用cmake编译MySQL_5.5.11教程

    注:资料来自网络    Centos 5.6编译安装mysql 5.5.11 2011年06月24日 星期五 05:33 MySQL 最新的版本5.5.11需要cmake编译安装,估计以后的版本也会采 ...

随机推荐

  1. java spring 使用注解来实现缓存

    这里举例使用spring3.1.4 + ehcache 注解的方式使用cache 是在spring3.1加入的 使用方法: 1.ehcache依赖+spring依赖 <!-- ehcache依赖 ...

  2. thinkphp中的分表方法

    public function getPartitionTableName($data=array()) { // 对数据表进行分区 if(isset($data[$this->partitio ...

  3. pydev+python+Eclipse环境搭建+ 调试快捷键汇总

    http://www.cnblogs.com/Bonker/p/3584707.html 编辑器: Eclipse + pydev插件 1. Eclipse是写JAVA的IDE, 这样就可以通用了,学 ...

  4. php 正则中文匹配

    汉字一定注意是gbk还是utf8编码 UTF-8匹配:在javascript中,要判定字符串是中文是很简朴的.比如:var str = "php编程";if (/^[\u4e00- ...

  5. Columbus’s bargain

    Columbus’s bargain Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  6. Integer的缓存和自动拆装箱

    先看一个简单的例子: public class TestInteger { public static void main(String[] args) { System.out.println(&q ...

  7. iOS类别(category)不能添加成员变量但是可以添加属性的问题

    类别不需要介绍了把,网上一大堆(利用Objective-C的动态运行时分配机制,可以为现有的类添加新方法,这种为现有的类添加新方法的方式称为类别catagory,他可以为任何类添加新的方法,包括那些没 ...

  8. Oracle 经典语法(二)

    --提示:工资 = 薪金 + 佣金 1. 找出EMP表中的姓名(ENAME)第三个字母是A 的员工姓名.SELECT ENAME FROM SCOTT.EMP WHERE ENAME LIKE '__ ...

  9. javaweb学习总结四(反射技术)

    一:反射的概念 反射就是加载类,然后获取类的属性.方法.构造函数等. 二:加载类到内存(有硬盘字节码文件到内存) 三种加载类的方式: @Test // 测试加载类 public void test1( ...

  10. 关于JDK中的运算符和变量

    类名首字母必须大写.多个单词组成的类名,每个单词的首字母大写. 只要起名称就要让他有意义.Java中的关键字都是由小写字母组成的. 在项目中给标示符起名字在公司中大都有固定的规则.一般加上标示符和$符 ...