背景 : 在此文章里会从分页分段机制去解析Linux内存管理系统如何工作的,由于Linux内存管理过于复杂而本人能力有限。会尽量将自己总结归纳的部分写清晰。

从实模式到保护模式的寻址方式的不同 :

  16位CPU的寻址方式 : 在 8086 CPU 中,提供了两类寄存器来进行寻址,分别为段寄存器(例如 CS,DS,SS)段偏移寄存器(例如 SI,DI,SP)。而这几种寄存器的长度都为16bit,寻址方式也很简单 : cs:ip = (cs << 4 + ip)。也就是说 cs寄存器的值左移4位加上ip的值得到的就是物理地址(物理地址就是内存中真实的值)。

  32位CPU的寻址方式 : 在80X86 CPU 中,提供了分段与分页机制。对于CPU的寻址而言,不再像 8086 CPU 那般将 段寄存器段偏移寄存器 直接运算得到结果。

  1)那么在32位CPU中是如何寻址的呢?

  i)如何开启分页分段模式?

    首先要介绍的就是 CR0 寄存器(如下图):

    

    对于CR0来说,存在两个bit :

    PE位 :  如若置位(1)则表示开启保护(分段)模式。

    PG位 : 在PE位置位的前提下置位PG位表示开启分页模式。

  ii)分段机制如何进行寻址(得到线性地址)?

    简述 : 段寄存器(例如CS) 里面存在一个索引(index),它会根据GDTR寄存器找到一个表(GDT),然后这个表里面有元素,元素内部含有段基址。而这个段基址加上段变址寄存器的值就直接得到了线性地址的值。

    详述 :

    在开启分段模式之后,段寄存器里面的值的含义就不再只是一个简单段基址了(也就是 (cs << 4)得到段基址),当下段寄存器加载的值称为段选择子,结构如下:

    

    可以看到这里有一个由几个bit组成的 描述符索引(也就是简述里所说的index),以及TI和RPL位(但目前不用管它)。

    GDTR :

    

    可以看到GDTR和IDTR(这个其实是另一个类似于GDTR的寄存器)都是由线性基地址表长度组成,线性基地址也就是说这个表的头部所在的线性基地址(类似于数组名),表长度也就是这个表的长度啦。

    那么自然我们就能得到一个类似于数组(由连续的地址组成)的表。

    对于这个"数组"来说,它的元素则被称为 段描述符:

    

    可以看到段描述符很长(一共64bit)...但是没关系,我们当下只需要把其分为三个部分 : 段基地址,段限长,段属性。即可。(这里之所以基地址和段限长啥的分了几个部分主要是因为历史遗留问题,但是没关系,他们只不过需要把几个分开的连在一起就能得到了真正的段基地址了)。

    那么得到了段基址,我们自然将其与段变址寄存器内的值相加就得到了线性地址了!

    iii)分页机制如何进行寻址(得到物理地址)?

    如若我们开始分页了,那么就表示我们已经得到了一个线性地址(分页是在分段的基础上进行的)。

    简述 : 首先我们把线性地址分为几个部分,目录(本质是页目录表的索引),页面(本质是页表的索引),页内偏移(本质是偏移量)

    由 CR3寄存器 作为 页目录表 的指针,通过CR3寄存器就可以得到一个表称为页目录表,页目录表内元素 称为 页目录项, 页目录项本质也是一个指针,指向一个 页表, 而页表内元素称为页表项,页表项内存在着 页基地址, 物理地址 = 页基地址(物理基地址) + 页内偏移(物理偏移地址)。

    简单来说我们可以把 页目录表和页表想象成一个二维的数组。页目录表元素是页表(一维数组),页表元素则是页基地址。

    

    我们只需要有两个元素(页目录表索引和页表索引)就可以得到一个物理(页)基地址,然后我们再将 页内偏移加上物理基地址,就得到了真正的物理地址了!而一个页在80x86中是4K大小(页基址 至 页基址 + 4K 为一页)。所以内存管理的页也是4K大小。

    附图(寄存器数据) :

    

    由图我门可以知道,页基地址(页帧),是4K对齐的(2^12 = 4K),也就是说页表项内只有12 - 31位是页基地址,其他的位是页属性,每次通过页表项计算物理地址只需要将 0 - 11位复位(0),即可。

    对于页属性 : 表述这个页的权限之类的,因为有的页面是属于内核才能去使用的。更重要的一点是 : 这个页是否存在。

    页目录和页表的表项格式:

  

    如图所示 : 我们可以知道当 P位 被置位则表示页面存在,当 P位复位(为0) 则表示页面不存在,如若页面不存在,那么就会产生缺页中断,执行缺页中断处理程序

Linux内存管理解析(一) : 分段与分页机制的更多相关文章

  1. Linux内存管理解析(二) : 关于Linux内存管理的大体框架

    什么是内存管理 ? 首先内存管理管理的主要对象是虚拟内存,但是虚拟内存对应的映射主要为物理内存,其次也可能通过交换空间把虚拟内存与硬盘映射起来,既然如此,那我们先了解物理内存的管理. 对于物理内存而言 ...

  2. linux内存管理解析1----linux物理,线性内存布局及页表的初始化

    主要议题: 1分页,分段模式及实模式 2Linux分页 3linux内存线性地址空间布局及物理内存空间布局 4linux页表初始化及代码解析 1.1.1内存寻址和保护模式 在X86平台上,内存控制单元 ...

  3. Linux内存管理解析(三) : 内核对内核空间的内存管理

    内核采用 struct page 来表示一个物理页,在其中记载了诸多物理页的属性,比如 物理页被几个线程使用(如若没有则表示该页可以释放),页对应的虚拟地址. 首先需要知道的是,分配物理页可以分为两个 ...

  4. 【转帖】linux内存管理原理深入理解段式页式

    linux内存管理原理深入理解段式页式 https://blog.csdn.net/h674174380/article/details/75453750 其实一直没弄明白 linux 到底是 段页式 ...

  5. 非常好的博客!!!linux内存管理概述【转】

    转自:http://blog.csdn.net/bullbat/article/details/7166140 inux内存管理建立在基本的分页机制基础上,在linux内核中RAM的某些部分将会永久的 ...

  6. [转帖]Linux分页机制之分页机制的演变--Linux内存管理(七)

    Linux分页机制之分页机制的演变--Linux内存管理(七) 2016年09月01日 20:01:31 JeanCheng 阅读数:4543 https://blog.csdn.net/gatiem ...

  7. [转帖]Linux分页机制之概述--Linux内存管理(六)

    Linux分页机制之概述--Linux内存管理(六) 2016年09月01日 19:46:08 JeanCheng 阅读数:5491 标签: linuxkernel内存管理分页架构更多 个人分类: ┈ ...

  8. Linux内存管理 (23)一个内存Oops解析

    专题:Linux内存管理专题 关键词:DataAbort.fsr.pte.backtrace.stack.   在内存相关实际应用中,内存异常访问是一种常见的问题. 本文结合异常T32栈回溯.Oops ...

  9. Linux内存管理 【转】

    转自:http://blog.chinaunix.net/uid-25909619-id-4491368.html Linux内存管理 摘要:本章首先以应用程序开发者的角度审视Linux的进程内存管理 ...

随机推荐

  1. 与正则有关的JS方法结合其在项目中的应用

    与正则有关的JS方法结合其在项目中的应用 前言 最近项目中用到正则匹配比较多,因此打算深入理解和总结下各个与正则有关的方法,再结合在项目中使用的情况.与正则有关的JS方法共有7个,分别是RegExp对 ...

  2. vue-cli 3.0 eslint

    1.关闭eslint module.exports = { configureWebpack: { devtool: 'source-map' }, lintOnSave: false } 2.修改e ...

  3. C语言中的断言

    一.原型定义:void assert( int expression ); assert宏的原型定义在<assert.h>中,其作用是先计算表达式 expression ,如果expres ...

  4. 基于jquery的带事件显示功能的日历板插件calendar.js

    项目中需要用到一个日历板控件,要求能显示事件,于是想到了一年前在app项目上写的一个粗略版日历板,然后又想着这个可能以后还会用 于是我就封装了一下,能满足基本要求,如果有需要更多功能的也可以自行修改源 ...

  5. Hadoop集群分布式安装

    一 整体介绍 1.1 硬件环境 本文使用三台服务器搭建hadoop集群,使用Centos7.5系统,服务器均有独立ip 1.2 部署的软件 部署服务:namenode(HA),resourcemana ...

  6. $splay$学习总结$QwQ$

    省选之前就大概搞了下$splay$,然后因为时间不太够就没写总结了,,,然后太久没用之后现在一回想感觉跟没学过一样了嘤嘤嘤 所以写个简陋的总结,,,肥肠简陋,只适合$gql$复习用,不建议学习用 然后 ...

  7. j接近50道经典SQL练习题,附建表SQL解题SQL

    说明 本文章整理了47道常见sql联系题,包括建表语句,表结构,习题列表,解题答案都涵盖在本文章内.文末提供了所用SQL脚本下载链接.所有解题答案都是本人自己写的,广大读者如果在阅读使用中,有任何问题 ...

  8. 利用shell脚本实现每隔60秒磁盘内存数据监控脚本

    #!/bin/bash #Author:GaoHongYu #QQ: #Time:-- :: #Name:ncjk.sh #Version:V1. clear xtip=$(hostname -I) ...

  9. AcWing 220. 最大公约数 | 欧拉函数

    传送门 题目描述 给定整数N,求1<=x,y<=N且GCD(x,y)为素数的数对(x,y)有多少对. GCD(x,y)即求x,y的最大公约数. 输入格式 输入一个整数N 输出格式 输出一个 ...

  10. [小技巧] Windows 命令行显示英文

    在 Windows 里 " 运行" 使用 cmd 进行命令行, 如果是Windows 中文版的话,里面的命令输出是中文. 如果要显示英文的话,可以使用如下的命令: chcp 437 ...