1. 内存寻址概述
1.1 图灵机
- 内存寻址的历史某种程度上来说就是现代计算机的历史。从最早的图灵机说起。如下图:
- 输入,输出,状态转移函数是图灵机的三要素,图灵机通过纸带完成内存寻址。
- 图灵机是现代计算机的鼻祖。
1.2 冯诺依曼体系结构
- 冯诺依曼体系核心思想:数据连续存储和选择读取思想。
- 计算机背后的核心问题之一,就是如何有效的进行内存寻找,因为所以数据运算的前提都是需要从内存中取得数据。冯诺依曼体系给出了一种解决方案。
1.3 CPU体系结构关系图
1.4 x86架构不同内存寻址的时期
1.4.1 原始时期——>4位寻址
- 这是由intel在1971年推出的4bit的处理器,这里不多做介绍
1.4.2 石器时期——>8位寻址
- intel8080是intel在1974推出的一款地址总线16bit,数据总线8bit的处理器,当时还没有段的概念,访问内存必须给出绝对地址,且重定位也不方便。
1.4.3 青铜时期——>16位寻址(段概念引入)
- Intel8086是Intel在1978年推出的16bit的处理器,这个时候就引入了段的概念。
- 由于8086需要寻址范围为1M所以其地址总线为20bit,而数据总线只有16bit所以其需要将1M大的空间分为数个64kB的段来管理。
- 段描述了一块有限的内存区域,区域的起始位置存在专门的寄存器,也就是段寄存器中。
1.4.3.1 8086的寻址方式
- 8086,如何通过16bit的地址寻址到1M的地址空间如图
- 8086的寻址过程其实就是将16位的段地址左移4位后与16位段偏移地址相加得到了20位的内存地址。也就是从16位内存地址到20位实际地址的转换,或者叫“映射”。这种模式也叫“实模式”。
1.4.4 白银时期——>24位寻址(保护模式的引入)
- intel80286是Intel1982年推出的一款内部和外部数据总线皆为16位,地址总线24位,可寻址16MB内存芯片。80286的推出是实模式和保护模式CPU分水岭。
- 此时引用了保护模式,cpu不在能直接访问段寄存器获得段的起始地址,而是需要通过额外的转换和检查。
1.4.5 黄金时期——>32,64位寻址
- inteli386是一个32位的cpu,其寻址能力达到4GB。
- intel在段机制的基础上增加保护模式,使段寄存器虽然还是16位但是在保护模式下,它的段范围不再受限于64K,可以达到4GB。
- 自i386推出后,后续cpu无论是32位还是64位都是在现有的基础上改进和加强,并无本质区别,所以i386以后的cpu被统称为x86架构。
2. 实模式和保护模式
2.1 实模式和保护模式寄存器对比
- 可以看出实模式和保护模式在寄存器上有很大的差异。
- 在状态和控制寄存器中,有用于分页的寄存器cr0-cr3。
2.2 保护模式下的页表寄存器
- 页表寄存器有CR0-CR3这里主要介绍CR0寄存器。
- CR0包含了6个预定义的标志,这里介绍内核中用到的0位和31位。
- 0位是保护允许位PE(protedted enable)主要是用于启动保护模式。
- 31位是分页允许位(paging enable),表示芯片上的分页部件允许工作。
- PG位和PE位比较可以很容易得出下表:
PG | PE | 方式 |
---|---|---|
0 | 0 | 实模式, 8080操作 |
0 | 1 | 保护模式, 但不允许分页 |
1 | 0 | 出错 |
1 | 1 | 允许分页的保护模式 |
3. 问题
3.1 为什么要引入保护模式?
- 因为随着计算机不断发展,人们必将不再满足于,CPU只跑一个程序。这不可避免的就会出现两个程序,地址冲突的问题。这时可以将内存地址抽象化的保护模式方案就应运而生啦,程序员不需要在关心地址冲突的问题,而是交个系统管理。
3.2 保护模式到底保护什么?
-
内存保护
根据上述详细的解析,我们可以知道,保护模式针对内存的保护主要有以下几方面:- 分段、分页将内存切分,让每个进程独有内存空间,限定和保护整个物理内存
- 通过分段机制实现线性地址对物理地址的隐藏,通过分页机制实现虚拟地址对物理地址的隐藏,他们都实现了对物理地址的保护
- 通过段描述符、页表项属性的描述,提供了不同划分级别下内存块的属性保护
- 通过特权级与栈切换,实现了不同层级程序切换时的保护
保护模式下中断描述附表的引入,让中断的切换和处理也被保护起来,包括中断处理程序使用的内存、特权级等
-
IO 的保护
-
通过 eflags 上的 IOPL 特权级与 TSS 指向的 IO 位图,IO 敏感操作也具有了严格的权限限制
-
IO 端口被保护了起来,不同特权级的程序能使用的 IO 端口不同,不同一个特权级内,不同的进程能够使用的 IO 端口也不同,这样就实现了最细粒度的 IO 保护
-
3.3 为什么能达到保护这些对象的目的?
- 在保护模式下,内存以4Kb为粒度称为页,每个页表项都有自己的属性,用来达到保护对象的目的。
- 此外保护模式下,还有特权级的概念,并规定低特权级不能访问高特权级,而高特权级可以访问低特权级。
4.参考文献
- 深入理解linux内核第二章
- 保护模式究竟“保护”了什么