当前课程知识点:Linux 内核分析与应用 >  第2章 内存寻址 >  2.3分页机制 >  Video

返回《Linux 内核分析与应用》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《Linux 内核分析与应用》慕课在线视频列表

Video课程教案、知识点、字幕

大家好

这一讲我们来讲一下保护模式的分页机制

我们知道分页是在分段之后进行的

它的目的是完成从线性地址

到物理地址的转换过程

那么前面我们说段机制呢

它是把虚地址转换成线性地址

而分页机制进一步的呢

把线性地址再转化为物理地址

那么X86规定分页机制是可选的

但是这只是硬件厂家的一厢情愿

很多的操作系统的设计者呢

主要采用的是分页机制

那么什么是分页呢

所谓分页就是将虚拟地址空间

或者说线性地址空间呢

划分成若干个大小相等的片 也称为页

同样的我们对于物理地址空间进行划分

划分成什么样的划分成

与页大小相等的存储块

那么这个地方我们把它称为块或者页面

那么页的大小为多少比较合适

在32位的系统上一般默认的是4K的大小

但是也可以是2MB的大小和4MB的大小

那么在64位系统上就可选项比较多了

从4KB 8KB

最大可以达到256MB

那么 分页的原理是什么呢

我们说分页使得每个进程可以拥有自己独立的虚拟地址空间

为了达到这个目的 CPU在访存的时候 就需要进行

一次地址的变化

也就是说需要把虚地址转化为物理地址

于是我们给出了一个映射函数

Pa=f(va)

这种转化在时间和空间上实际上要付出代价的

因此就必须进行优化

进行哪些方面的优化 实际上进行两方面的优化

一方面就是时间的优化

因为访存很频繁因此呢

映射函数f一定要简单

否则效率就会比较低

所以需要简单的查表算法

这也就是页表引入的原因

那么第二个方面就是空间的优化

因为内存空间是按字节编址的

地址一一进行映射的 话效率实际上是很低的

于是要按照一定的粒度

也就是说页呢进行映射

那么这样的话粒度内的相对地址 也就是页的偏移量呢

在映射的时候就可以保持不变了

那么什么是页表呢?

实际上页表它就是一种影射机制

存放的是什么 存放的是虚拟地址空间

与物理地址空间的一种映射关系

也就是说页号对应的块号

那么页表项是什么样的结构呢

如图为32位的X86的页表项的具体结构

在32位的地址空间

通常页的大小是4KB

这样的话 每个页的起始地址最低12位就是0了

那么这样的话呢我们就可以用高20位表示页的起始地址

而低12位就可以用来表示页的属性

也就是说一个页表项就占四个字节

那么4KB的大小的页就可以存放1K个页表项

那么这里我们特别关注一下页表属性中的P位

也就是存在位

这一位它是来判别缺页的一个重要标志

那么更具体的信息 Intel的手册中都有特别详细的描述

大家手边务必有Intel的手册 那么问题来了

这种结构是由谁来确定的

仅仅是硬件厂家呢

还是os的设计者共同商定的

这个问题就留给大家来思考

那么我们前面给出的页表项是一级页表

如果只用一级页表的话

因为每个页表最大就可以占用

4MB的空间

而且还必须是连续的

这就为内存的分配带来困难 怎么办呢

依然采用分而治之的原则

于是我们将20位分为两部分

分别占十位 这样就形成了两级页表

那么两级页表如何进行地址转换

这张图呢

就是从线性地址到物理地址转换的一张图

下面我们对这张图给予详细的介绍

那么第一步我们就用

最高十位作为页目录项的索引

将它乘以4 4表示

每一个页表项占4个字节

然后与CR3中的页目录的起始地址相加

这样我们就获得相应目录项

在内存的地址

第二步我们从这个地址就开始读取

32位的页目录项

取出其最高的20位

然后再给最低的12位补零

就形成页表在内存的起始地址

第三步呢 我们用中间的十位作为

页表中的页表项的索引

依然将它乘以4

与页表的起始地址相加

获得相应页表项在内存的地址

那么最后一步呢

我们从这个地址开始读取32位的页表项

取出它高20位

再将线性地址的第11到0位呢

放在低12位

最终呢形成32位的页面物理地址

那么这个转换过程听起来很复杂

到底是谁来完成的

是硬件呢还是操作系统

这个问题也抛给大家来思考

那么整个地址转换过程我们看起来是比较复杂的

由于在分页的情况下呢

页表是放在内存中的

这就使得CPU在每次存取一个数据的时候呢

都要至少两次访存

从而大大的降低了访问的速度

所以呢为了提高速度呢

在X86中设置了一个高速缓存硬件机制

也叫做转换旁路缓冲器TLB

那么当CPU访问地址空间的某个地址时候呢

实际上是先检查对应的页表项

是不是在高速缓存中

如果在也就是说命中了

就不必经过两级访存了

如果失败 这个时候再进行两级访存

平均来说呢页面的高速缓存呢

大约有90%的命中率

也就是说每次访存的时候呢

只有10%的情况呢

必须访问两级页表

这就大大的加快了访存的速度

那么Linux中到底是如何分页的呢

这个图就是Linux中的分页机制

那么Linux中主要采用

分页机制来实现虚拟存储器的管理

为什么这么说这是因为有以下两个原因

第一个原因是Linux巧妙的绕过了段机制

第二个原因呢Linux设计的目标之一呢

就是具有可移植性

但是很多CPU并不支持段

目前许多处理器都采用64位的结构了

为了保持这种可移植性呢

Linux目前采用了四级分页模式

为此就定义了四种类型的页表

那么第一级叫页总目录PGD((Page Global Directory))

第二级叫页上级目录PUD(Page Upper Directory)

第三级叫页中间目录PMD(Page Middle Derectory)

那么最低的一级就叫页表PT(Page table)

不管是四级

或者三级页表

那么如何与我们前面所讲的二级页表兼容

Linux内核代码中进行了巧妙的处理

这个需要大家来通过源代码进一步的来理解它

那么源代码中呢

与页表相关的头文件有哪些呢

我们这里列出了五个相关的头文件

大家感兴趣的话 一定要打开这些头文件

来一一查看相关的数据结构

前面我们对分页的原理进行了简单的介绍

那么下面我们通过一个例子 什么样的例子呢

就是分页的初始化的例子 把前面的知识应用起来

在了解了页表的基本原理以后呢

通过代码可以模拟内核的初始化页表的过程

那么在这个代码中我们看到呢

第1到7行呢

是页目录的基地址

偏移量以及页表属性的定义

第14行是在为物理内存的第二个页呢

设置了页目录

然后第9到23行的循环呢

初始化了页目录中的四个页目录项

也就是四个页表

第27到31行呢

循环初始化了四个页表中的第一个页表

也就是说映射了4MB的物理内存

到此页表已经初始化了

那么剩下的工作是什么

就是将页目录的地址呢

传递给CR3寄存器

这是由第33到38行的嵌入式汇编代码来完成的

并且设置了CR0寄存器中的

分页允许位

虽然上述的代码比较简单

但却描述了页表初始化的整个过程

以此为模型呢我们可以很容易地理解

Linux内核中关于页表的代码

最后我们需要动手实践

那么在Linux内核之旅网站的电子杂志栏目的第二期呢

i386体系结构下呢

实现了一个最短小的可启动内核

一是为了加深大家对X86体系的了解

第二是演示了系统开发的原始过程

大家可以下载代码并进行调试

那么最后我们给出参考资料

大家可以参考

《深入理解Linux内核》的第二章

以及Intel的64位和32位的手册

那么最后给大家抛出一个问题

我们说页的大小不仅仅只有4KB

还可以是4M或者更大的

那么在海量内存中如何使用大页内存

这个问题留给大家来思考

谢谢大家

Linux 内核分析与应用课程列表:

第1章 概述

-1.1 Linux操作系统概述

--1.1 Linux 操作系统概述

-1.2 Linux内核结构以及内核模块编程

--Video

-1.3 Linux内核源码中的双链表结构

--Video

-1.4 源码分析-内核中的哈希表

--Video

-1.5 动手实践-Linux内核模块的插入和删除

--Video

-第1章 概述--章节测验

-第1章导学--引领你进入Linux内核的大门

第2章 内存寻址

-2.1 内存管理之内存寻址

--Video

-2.2 段机制

--Video

-2.3分页机制

--Video

-2.4 动手实践-把虚拟地址转换成物理地址

--Video

-第2章 内存寻址--章节测验

-第二章导学-从零打造自己的操作系统

第3章 进程管理

-3.1 进程概述

--Video

-3.2 Linux进程创建

--Video

-3.3 Linux进程调度

--Video

-3.4 动手实践-打印进程描述符task_struct中的字段

--Video

-3.5工程实践-基于内核模块的负载监控

--Video

-第3章 进程管理--章节测验

-第三章导学-进程背后琳琅满目的宝贝到哪里挖?

第4章 内存管理

-4.1 Linux内存管理机制

--Video

-4.2 进程用户空间管理机制

--Video

-4.3 物理内存分配与回收机制(上)

--Video

-4.4 物理内存分配与回收机制(下)

--Video

-4.5 动手实践-Linux内存映射基础(上)

--Video

-4.6 动手实践-Linux内存映射实现(中)

--Video

-4.7 动手实践-Linux内存映射测试(下)

--Video

-4.8 初学者对内存管理的常见疑惑

--初学者对内存管理的常见疑惑(一)

--初学者对内存管理的常见疑惑(二)

--初学者对内存管理的常见疑惑(三)

-第4章 内存管理--章节测验

第5章 中断

-5.1 中断机制概述

--Video

-5.2 中断处理机制

--Video

-5.3 中断下半部处理机制

--Video

-5.4 时钟中断机制

--Video

-5.5 动手实践-中断上半部的代码分析及应用

--Video

-5.6 动手实践-中断下半部的代码分析及应用

--Video

-第5章 中断--章节测验

第6章 系统调用

-6.1 Linux中的各种API

--Video

-6.2 系统调用机制

--Video

-6.3 动手实践-添加系统调用(系统调用日志收集系统)

--Video

-第6章 系统调用--章节测验

第7章 内核同步

-7.1 内核同步概述

--Video

-7.2 内核同步机制

--Video

-7.3 动手实践-内核多任务并发实例(上)

--Video

-7.4 动手实践-内核多任务并发实例(下)

--Video

-第7章 内核同步--章节测验

第8章 文件系统

-8.1 虚拟文件系统的引入

--Video

-8.2 虚拟文件系统的主要数据结构

--Video

-8.3 文件系统中的各种缓存

--Video

-8.4 页高速缓存机制以及读写

--Video

-8.5 动手实践-编写一个文件系统(上)

--Video

-8.6 动手实践-编写一个文件系统(中)

--Video

-8.7 动手实践-编写一个文件系统(下)

--Video

-第8章 文件系统--章节测验

第9章 设备驱动

-9.1 设备驱动概述

--Video

-9.2 I/O空间管理

--Video

-9.3 设备驱动模型

--Video

-9.4 字符设备驱动程序简介

--Video

-9.5 块设备驱动程序简介

--Video

-9.6 动手实践-编写字符设备驱动程序

--Video

-9.7工程实践-编写块设备驱动的基础(上)

--Video

-9.8 工程实践-块设备驱动程序分析(中)

--Video

-9.9 工程实践-块设备驱动程序实现(下)

--Video

-第9章 设备驱动--章节测验

致谢与说明

-致谢与说明

--Video

直播视频:从Linux内核学习到自主操作系统研发

-从Linux内核学习到自主操作系统研发

附录:实验代码、课件以及相关素材

-各章实验代码

-《Linux内核分析与应用》课件

-《Linux操作系统原理与应用》教材课堂视频

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。