写在前面

  此系列是本人一个字一个字码出来的,包括示例和实验截图。如有好的建议,欢迎反馈。码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作。如想转载,请把我的转载信息附在文章后面,并声明我的个人信息和本人博客地址即可,但必须事先通知我

你如果是从中间插过来看的,请仔细阅读 羽夏看Linux系统内核——简述 ,方便学习本教程。

中断

  中断通常是由CPU外部的输入输出设备(硬件)所触发的,供外部设备通知CPU有事情需要处理,因此又叫中断请求,英文为Interrupt Request。中断请求的目的是希望CPU暂时停止执行当前正在执行的程序,转去执行中断请求所对应的中断处理例程,中断处理程序由哪有IDT表决定。

  80x86有两条中断请求线:非屏蔽中断线,NMI,全称NonMaskable Interrupt和可屏蔽中断线,INTR,全称Interrupt Require

不可屏蔽中断

  什么是不可屏蔽中断CPUEFLAG之中有一个位,它是IF位。如果它被置0。如果有可屏蔽中断告诉CPU有中断来了,你能先执行我的代码呢?可是IF位是0,对不起,我听不见。左耳朵进,右耳朵出。反之,我会处理。常见的不可屏蔽中断有电脑长按关机、键盘输入等等。当非可屏蔽中断产生时,CPU在执行完当前指令后会里面进入中断处理程序,非可屏蔽中断不受那个位的影响,一旦发生,CPU必须处理。为了方便观看,给个EFLAG图解:

  那么CPU是如何处理我们的不可屏蔽中断呢?我们先来看如下表格:

(IDT表)中断号 NMI 说明
0x2 不可屏蔽中断 80x86 中固定为 0x2

  如果处理不可屏蔽中断,CPU会调用2号中断。涉及的IDT表和中断门的知识如果忘却请查看前面的教程。

可屏蔽中断

  什么是可屏蔽中断,我就不赘述了。在硬件级,可屏蔽中断是由一块专门的芯片来管理的,通常称为中断控制器。它负责分配中断资源和管理各个中断源发出的中断请求.为了便于标识各个中断请求,中断管理器通常用IRQ,全称为Interrupt Request,后面加上数字来表示不同的中断。

  那么CPU是如何处理我们的可屏蔽中断呢?我们先来看如下表格:

(IDT表)中断号 IRQ 说明
0x30 IRQ0 时钟中断
0x31-0x3F IRQ1-IRQ15 其他硬件设备的中断

  如果自己的程序执行时不希望CPU去处理这些中断,可以用CLI指令清空EFLAG寄存器中的IF位,用STI指令设置EFLAG寄存器中的IF位。

  硬件中断与IDT表中的对应关系并非固定不变的,可以参考白皮书的Chapter 10 Advanced Programmable Interrupt Controller(APIC)进行了解。

异常

  异常通常是CPU在执行指令时检测到的某些错误,比如除0、访问无效页等。中断与异常之间有一些相似之处,但它们是不一样的:中断来自于外部设备,是中断源(比如键盘)发起的,CPU是被动的;而异常来自于CPU本身,是CPU主动产生的。INT N虽然被称为“软件中断”,但其本质是异常,EFLAGIF位对INT N是无效。

异常处理

  无论是由硬件设备触发的中断请求还是由CPU产生的异常,处理程序都在IDT表。常见的异常处理程序如下表所示:

错误类型 (IDT表)中断号
页错误 0xE
段错误 0xD
除零错误 0x0
双重错误 0x8

控制寄存器

  控制寄存器用于控制和确定CPU的操作模式。控制寄存器有Cr0Cr1Cr2Cr3Cr4Cr1被保留了,Cr3用于页目录表基址,其他的将继续详细讲解。

Cr0

  Cr0是一个十分重要的寄存器,可以说它是总开关的集合体。如下图所示:

  PE位是启用保护模式(Protection Enable)标志。若PE = 1是开启保护模式,反之为实地址模式。这个标志仅开启段级保护,而并没有启用分页机制。若要启用分页机制,那么PEPG标志都要置位。

  PG位是启用分页机制。在开启这个标志之前必须已经或者同时开启PE标志。PG = 0PE = 0,处理器工作在实地址模式下。PG = 0PE = 1,处理器工作在没有开启分页机制的保护模式下。PG = 1PE = 0,在PE没有开启的情况下无法开启PGPG = 1PE = 1,处理器工作在开启了分页机制的保护模式下。

  WP位对于Intel 80486或以上的CPU,是写保护(Write Proctect)标志。当设置该标志时,处理器会禁止超级用户程序(例如特权级0的程序)向用户级只读页面执行写操作;当CPL < 3的时候,如果WP = 0可以读写任意用户级物理页,只要线性地址有效。如果WP = 1可以读取任意用户级物理页,但对于只读的物理页,则不能写。

Cr2

  当CPU访问某个无效页面时,会产生缺页异常,此时,CPU会将引起异常的线性地址存放在CR2中,如下图所示:

Cr4

  Cr4的结构如下图所示:

  VME用于虚拟8086模式。PAE用于确认是哪个分页,PAE = 1,是2-9-9-12分页,PAE = 010-10-12分页。PSE是大页是否开启的总开关,如果置0,就算PDE中设置了大页你也得是普通的页。至于分页到底是什么,将会在下一篇进行讲解。

中断小节

  有些结构的位我并没有详细介绍,详情请查看白皮书的控制寄存器的篇章,如下图所示:

  如果对分页不了解看不懂没关系,下一篇将会介绍相关知识。

分页

  在讲解分页基础之前,我们先大体了解CPU是如何在保护模式下访问数据的,如下图所示:

  比如我们执行mov eax,ds:[0x12345678]这句汇编指令的时候,0x12345678这个线性地址会传递给CPU,先查询TLB缓存有没有,有的话直接取出来返回;如果没有,经过MMU(内存管理单元)处理得到物理地址,通过固定的分页模式直接找到,取出数据返回。

  前面的教程讲解了段的机制,接下来将介绍页的机制。CPU为了方便管理物理内存,按照页的方式进行管理内存。可用的所有内存可以类比为一本书,而所有的内存被分为这本书的一个页。对于32位来说,它有10-10-12分页和2-9-9-12分页。其中10-10-12分页最为简单,故拿其作为详细讲解,作为分页讲解的基础。

  我们都了解一个进程都有4GB的虚拟地址空间,它们并不是真正的地址,而是个索引。它通过某种方式进行转换,从而指向真正的物理地址,示意图如下所示:

  而虚拟地址也被称作线性地址。举个例子,比如某个进程里面我想读取一个0x12345678,它就是线性地址,通过一些转换,找到了对应的物理地址0x10101010,如下图所示:

  每个进程都有一个CR3,准确的说是都一个CR3的值。CR3本身是个寄存器,一核一套。CR3里面放的是一个真正的物理地址,指向一个物理页,一共4096字节,如下图所示:

  对于10-10-12分页来说,线性地址对应的物理地址是有对应关系的,它被分成了三个部分,每个部分都有它具体的含义。线性地址分配的结构如下图所示:

  第一个部分指的是PDEPDT的索引,第二部分是PTEPTT的索引,第三个部分是在PTE指向的物理页的偏移。PDT被称为页目录表,PTT被称为页表。PDEPTE分别是它们的成员,大小为4个字节。我们接下来将详细介绍每一个部分是咋用的。

10-10-12 分页整体结构

  通过实验我们了解了它们的结构,接下来将详细介绍了。根据实验结果的体验,可以给出如下图:

  分页并不是由操作系统决定的,而是由CPU决定的。只是操作系统遵守了CPU的约定来实现的。物理页是什么?物理页是操作系统对可用的物理内存的抽象,按照4KB的大小进行管理(Intel是按照这个值做的,别的CPU就不清楚了),和真实硬件层面上的内存有一层的映射关系,这个不是保护模式的范畴,故不介绍。

PDE 与 PTE

  前面我们简单了解PDEPTE,接下来将学习它们的属性结构,结构如下:

P 位

  表示PDE或者PTE是否有效,如果有效为1,反之为0

R/W 位

  如果R/W = 0,表示是只读的,反之为可读可写。

U/S 位

  如果U/S = 0,则为特权用户(super user),即非3环权限。反之,则为普通用户,即为3环权限。

PS位

  这个位只对PDE有意义。如果PS == 1,则PDE直接指向物理页,不再指向PTE,低22位是页内偏移。它的大小为4MB,俗称“大页”。

A 位

  是否被访问,即是否被读或者写过,如果被访问过则置1

D 位

  脏位,指示是否被写过。若没有被写过为0,被写过为1

注意,下面的三个位的讲解将涉及 TLB 和控制寄存器相关知识,为了保证文章的完整性,故先介绍。之后将会详细讲解。

G 位

  表示是否为全局页。它的作用是什么呢?举个例子,操作系统的进程的高2G映射基本不变,如果Cr3改了,TLB刷新重建高2G以上很浪费。所以PDEPTE中有个G位,如果为1,刷新TLB时将不会刷新它指向的页。

PWT 位

  当PWT = 1,写缓存的时候也要将数据写入内存中。

PCD 位

  当PCD = 1时,禁止某个页写入缓存,直接写内存。比如,做页表用的页,已经存储在TLB中了,可能不需要再缓存了。

注意事项

  • PTE可以没有物理页,且只能对应一个物理页。
  • 多个PTE也可以指向同一个物理页。
  • PDEPTE重合的属性共同决定着最终物理页的属性。比如P位,如果有一个是0,那么最终的物理页就是无效的。但是PDEPTE它们的属性的影响范围是不一样的。数值上:物理页的属性 = PDE属性 & PTE属性。

PAE 分页

  PAE分页是啥,其实他就是2-9-9-12分页的英文缩写。为什么要有2-9-9-12分页,其实还是物理页不够用了,需要扩展。但想要足够的物理页,位数在那里,你想大也大不了。那么我就需要扩展物理页地址的位数,于是乎2-9-9-12分页诞生了,它整体分页的结构如下:

  与10-10-12分页不同的地方就是,多了一层名为页目录指针表的东西,英文缩写为PDPTT。每个PDEPTE被扩展为8个字节,物理地址描述的位数扩展为24位,故可以描述更多的物理页,但个数减半,变成了512个。下面详细查看它们的结构。

  首先看PDPTT的结构。由2-9-9-122可知第一部分由两位二进制组成,那么最多有4种结果。也就是为什么有五个成员,它的结构如下图所示:

  然后是PDE,既然学过了10-10-12分页,直接看下面的结构示意图吧:

非大页

大页

  然后是PTE,同理不多说了:

  我们之前做一道作业题目知道,我写的shellcode写到一个页上,它并没有执行权限,但它不是代码,仍然可以被我执行。为了弥补这个漏洞,Intel给我们补了一个硬件层面上的漏洞,它是一个位,处于PDEPTE的最高位,如下图所示:

  如果最高位是1,说明被保护。如果这个是数据,且这个X位被置为1,则会被报出异常不能执行。反之,和正常的10-10-12分页没什么两样。

  一个进程的线性地址仍是4GB的线性空间,有再多的物理页有啥用呢?在10-10-12分页下,假设进程一启动,就把所有的物理页都挂上,且没有任何交换。那么只能启动一个;如果在2-9-9-12分页下,同样的情况,它可以启动4个进程。这个就是2-9-9-12分页的意义。

TLB

  CPU通过页的方式对物理内存进行了,需要通过某种运算方式才能访问真正的内存。但是,如果频繁访问某一个线性地址,每次都得通过推算到真正的物理地址然后进行读写操作,是不是挺浪费效率的?Intel就考虑到性能的问题,提供了TLB这一个机制,提供缓存提高读写效率。

  TLB的全称为Translation Lookaside Buffer,它的结构如下:

LA(线性地址) PA(物理地址) ATTR(属性) LRU(统计)

  对于TLB,给出如下说明:

  1. ATTR(属性):如果是2-9-9-12分页,属性是PDPEPDEPTE三个属性共同决定的。如果是10-10-12分页就是PDEPTE共同决定。

  2. 不同的CPU这个表的大小不一样。

  3. 只要Cr3变了,TLB立马刷新,一核一套TLB

  如果Cr3改了,TLB刷新重建高2G以上很浪费。所以PDEPTE中有个G标志位,如果G位为1刷新TLB时将不会刷新PDE/PTEG位为1的页,当TLB满了,根据统计信息将不常用的地址废弃,最近最常用的保留。

  TLB有不同的种类,用于不同的缓存目的,它在X86体系里的实际应用最早是从Intel486CPU开始的,在X86体系的CPU里边,一般都设有如下4组TLB

  第一组:缓存一般页表(4K字节页面)的指令页表缓存:Instruction-TLB

  第二组:缓存一般页表(4K字节页面)的数据页表缓存:Data-TLB

  第三组:缓存大尺寸页表(2M/4M字节页面)的指令页表缓存:Instruction-TLB

  第四组:缓存大尺寸页表(2M/4M字节页面)的数据页表缓存:Data-TLB

CPU缓存

  CPU缓存是位于CPU与物理内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。它可以做的很大,但不是TLB,它们有很大的不同。TLB存的是线性地址与物理地址的对应关系,CPU缓存存的是物理地址与内容对应关系。

  更多的细节请参考白皮书的Chapter 11 Memory Cache Control,本篇教程主要是针对内核安全层面,就不再赘述了。

PWT 与 PCD

  PWT全称为Page Write ThroughPWT = 1时,写Cache的时候也要将数据写入内存中。

  PCD全称为Page Cache DisablePCD = 1时,禁止某个页写入缓存,直接写内存。比如,做页表用的页,已经存储在TLB中了,可能不需要再缓存了。

下一篇

  羽夏看Linux内核——内核加载

羽夏看Linux内核——中断与分页相关入门知识的更多相关文章

  1. 羽夏看Linux内核——门相关入门知识

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...

  2. 羽夏看Linux内核——启动那些事

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...

  3. 羽夏看Linux内核——引导启动(下)

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...

  4. 羽夏看Linux内核——段相关入门知识

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...

  5. 羽夏看Linux内核——引导启动(上)

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...

  6. 羽夏看Linux内核——环境搭建

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...

  7. 羽夏看Win系统内核——保护模式篇

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  8. 羽夏看Win系统内核——驱动篇

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  9. 羽夏看Win系统内核——进程线程篇

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

随机推荐

  1. 124_Power Pivot&Power BI DAX优化计算最大连续次数

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 最大连续次数或者是最大连续子序列问题,在DAX中如何快速计算呢? 思路 1.N-1:按照INDEX错位 2.ST ...

  2. 使用instanceof操作符判断对象类型及方法的重载

    学习内容: 一.使用instanceof操作符判断对象类型 1.instanceof操作符可以判断一个实例对象是否属于一个类. 语法:对象名 instanceof 类名 2.使用instanceof表 ...

  3. lnav-日志查看器

    lnav是一个基于控制台的高级lnav是一个基于控制台的高级日志文件查看器(浏览器). lnav支持日志高亮显示内容以及查看压缩的日志文件,而且它可以使用较小的内存实时查看较大的日志文件.日志文件查看 ...

  4. SAP Web Dynpro-版本管理

    您可以使用版本管理来管理对象的旧版本,比较版本,也可以重置它们. 在版本管理中,您可以存储ABAP开发对象的不同版本. 在ABAP工作台中,您可以比较不同版本的- 视图 视窗 控制器 您也可以存储对象 ...

  5. SAP 定义客户端

    SCC4  定义客户端 点击新建条目按钮  Client(客户端) R 200 Client Name(客户端名称) O   City(城市) R   Logical system(逻辑系统) R   ...

  6. ASP.NET MVC的核心-Controller(控制器)

    "每一个请求都必须通过Controller处理,然而其中有些请求是不需要模型和视图的" MVC框架规定带Controller后缀的类称为所谓的"控制器",在xx ...

  7. ms10_002 IE浏览器漏洞

    一.环境说明 kali linux 靶机:xp 二.ms10_002漏洞利用 msf5 exploit(windows/smb/ms08_067_netapi) > search ms10_00 ...

  8. ReentrantLock 公平锁源码 第1篇

    ReentrantLock 1 这篇还是接着ReentrantLock的公平锁,没看过第0篇的可以先去看上一篇https://www.cnblogs.com/sunankang/p/16456342. ...

  9. JavaWEB04-Maven&Mybatis

    今日内容 `Maven` Maven `Maven`概念&简介 Maven `Maven`安装配置 Maven `Maven`基本使用 Idea集成 `Idea`集成`Maven` Maven ...

  10. Error:(4, 13) java: -source 1.5 中不支持默认方法 (请使用 -source 8 或更高版本以启用默认方法)