linux 内存寻址

(持续更新)

相关概念

查看的书籍为 深入linux内核


内存地址

  当使用80x86(32位)微处理器时,一般分为三种不同的地址: 


逻辑地址

 包含在机器语言指令中用来指定一个操作数或一条指令的地址。每一个逻辑地址都由一个段(segment)和偏移量(offset或displacement)组成,偏移量指明了从段开始的地方到实际地址之间的距离。
所有段都从0x00000000开始,只需关注段内偏移即可。而段内偏移的值恰好等于线性地址的值。


线性地址(也称虚拟地址)

线性地址通常用十六进制数字表示,值的范围从0x00000000到0xffffffff。
物理地址
用于内存芯片级内存单元寻址。他们与从微处理器的地址引脚发送到内存总线上的电信号相对应。 

物理地址

用于内存芯片级内存单元寻址。他们与从微处理器的地址引脚发送到内存总线上的电信号相对应。 

页(page)

线性地址被分成以固定长度为单位的组,称为页。页内部连续的线性地址被映射到l连续的物理地址中。内核可以指定一个页的物理地址和其存储权限

页框(page frame)

分页单元把所有的RAM分成固定长度的页框(有时叫做物理页)。

每一个页框包含一个页,也就是说一个页框的长度与一个页的长度一致(目前操作系统应该不是)

页表 (page table)

把线性地址映射到物理地址的数据结构称为页表。

页表内存储页表项,页表项含有页所在页框的物理地址。

在启用分页单元之前必须由内核对页表进行适当的初始化。

地址转换

内存控制单元(MMU)通过一种称为分段单元的硬件电路把一个逻辑地址准换成线性地址;接着,第二个称为分页单元的硬件电路把线性地址转换成一个物理地址。 
这个地方有疑问! 逻辑地址一般等于线性地址,那不同的进程中相同的地址获取到的逻辑地址是一样?还要继续看。

段选择符

机器语言指令中出现的内存地址,都是逻辑地址。

一个逻辑地址由两部分组成: 段选择符以及偏移量。

段选择符字段

index 指定了放在GDT或LDT中的相对应段描述符的入口。 

TI      :TI (Table Indicator)标志 :指明段描述符实在GDT(TI=0)中或在LDT中 (TI=1)

RPL   :请求者特权级。

段描述符

每个段由一个8字节的段描述符表示,它描述了段的特征。段描述符放在全局描述符表(Global Descriptor Table,GDT)或局部描述符表(Local Descriptor Table, LDT中)。

Linux GDT(全局描述符表)

在单处理器系统中只有一个GDT,而在多处理器系统中每个CPU对应一个GDT。

通常只定义一个GDT,每个进程除了存放在GDT中的段之外如果还需创建附加的段,就有自己的LDT。GDT在主存中的地址和大小存放在gdtr控制寄存器中,当前正被使用的LDT地址和大小放在ldtr控制寄存器中。

段描述符类型

代码段描述符

数据段描述符

任务状态段描述符(TSSD)

局部描述符表描述符(LDTD)

段描述符字段 

Base  : 包含段的首字节的线性地址

.............

.............

分段单元

逻辑地址转换为线性地址,分段单元执行以下操作

1.通过逻辑地址(由段选择符及偏移量组成)得到段选择符;

2.先检查段选择符的TI字段,判断段选择符保存在哪一个描述符表中。TI字段指明描述符是在GDT中(在这种情况下,分段单元从gdtr寄存器中得到GDT的线性基地址)还是在LDT中(在这种情况下,分段单元从ldtr寄存器中得到LDT的线性基地址);

3.从段选择符的index 字段计算段描述符的地址,index字段的值乘以8(一个段描述符的大小),这个结果与gdtr或ldtr寄存器中的内容相加;

4.把逻辑地址的偏移量与段描述符Base字段的值相加就得到了线性地址。

简单说就是,通过逻辑地址找到段选择符,再找到对应的段描述符,最后得到最后的线性地址。

段描述符中有包含段的首地址的线性地址(base)。

常规分页

线性地址结构

32位的线性地址被分成3个域页表 (我的理解:这里怎么分具体要看有几级页表以及页的大小

Diretory(目录)                

        最高10位

Table(页表)          

        中间10位

Offset(偏移量)

        最低12位

这里分为两级页表,线性地址的转换就分两步完成,每一步都基于一种转换表,第一个种叫页目录表,第二种叫页表

个人理解:

如果进程使用全部4G线性地址空间,每个页框(物理页)代表4096个字节(2的12次方);一个页表最多存储1024个页表项(2的10次方),1个页表项含有页所在页框的物理地址,即1个页表项对应4k地址空间,一个页表能找到4M地址空间;1个页目录最多存储1024个页目录项(2的10次方),而一个页目录项指向适当的页表,那么一个页目录项就能找到一个4M地址空间,一个页目录就能找到4G地址空间。

由上图可知,一个页大小为2的10次方,那么内存就以2的十次方分页,知道页表项大小为2字节,

1.一个页表中的页表项数量为 1024(2的10次方) / 2 = 512(2的9次方)个,页号由9位表示,

2.一个页表能表示的空间大小为 512(2的9次方) *  1024(2的10次方) = 512K (2的19次方),

3.一个页目录包含表项的个数 为 总空间大小除以一个页表能表示的空间大小,即

(2的16次方) * (2的10次方) / 512K (2的19次方) = 128 (2的7次方)。

书看到这里有了疑惑点:

书上说,使用这种二级模式的目的是在于减少每个进程页表所需RAM的数量,二级模式通过只为进程实际使用的那些虚拟内存区请求页表来减少容量。

那么问题来了,我只用一级页表为什么不能对实际使用的那些虚拟内存区请求页表?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/618326.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

踩了一堆坑,终于掌握了postgreSQL主从流的精髓

📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…

【Linux】序列化与反序列化{服客编程/守护进程/JSON}

文章目录 1.引入2. 静态成员函数3.TCP:传输控制协议4.守护进程4.0前台进程4.1介绍4.2认识4.3会话4.3ps axj4.4理解4.5/dev/null4.6守护进程和孤儿进程 5.JSON6.完整代码6.1Makefile6.2Socket.hpp6.3Protocol.hpp6.4Log.hpp6.5Daemon.hpp6.6TcpServer.hpp6.7Client.c…

第二期书生浦语大模型训练营第三次作业

任务一:在茴香豆 Web 版中创建自己领域的知识问答助手 构建个人回答助手 进入web页面,传输属于自己的文件,此处进行输入大量投资领域资料,构建个人投资者问答助手 回答示例 茴香豆缺陷 此处会发现茴香豆仍然存在一些缺点&#…

Element-UI 自定义-下拉框选择年份

1.实现效果 场景表达&#xff1a; 默认展示当年的年份&#xff0c;默认展示前7年的年份 2.实现思路 创建一个新的Vue组件。 使用<select>元素和v-for指令来渲染年份下拉列表。 使用v-model来绑定选中的年份值。 3.实现代码展示 <template><div><el-…

数字乡村创新实践探索农业现代化与农村治理现代化新路径:科技赋能农村全面振兴与农民幸福生活

目录 引言 一、数字乡村与农业现代化 1、智慧农业技术的应用 2、农业产业链的数字化转型 二、数字乡村与农村治理现代化 1、农村信息化水平的提升 2、农村治理模式的创新 三、科技赋能农村全面振兴与农民幸福生活 1、提升农业生产效益与农民收入 2、促进农村产业结构…

DAY9|28. 实现 strStr()、459.重复的子字符串

28.实现 strStr&#xff08;&#xff09;、459重复的子字符串 28. 实现 strStr()减一版next数组时间复杂度分析前缀表统一减一 C代码实现前缀表&#xff08;不减一&#xff09;C实现 459.重复的子字符串移动匹配KMP前缀表统一减一前缀表&#xff08;不减一&#xff09;的C代码实…

深度学习图像处理基础工具——opencv 实战2 文档扫描OCR

输入一个文档&#xff0c;怎么进行文档扫描&#xff0c;输出扫描后的图片呢&#xff1f; 今天学习了 opencv实战项目 文档扫描OCR 问题重构&#xff1a;输入图像 是一个含有文档的图像——> 目标是将其转化为 规则的扫描图片 那么怎么实现呢&#xff1f; 问题分解&#…

LeetCode 94 二叉树的中序遍历

题目描述 二叉树的中序遍历 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入…

Linux登录访问限制

Linux系统下&#xff0c;用户密码的有效期可以通过编辑/etc/login.defs文件控制&#xff1b;密码复杂度规则设定需要通过/etc/pam.d/system-auth文件控制&#xff1b;登录失败次数限制通常由/etc/pam.d/login文件限制&#xff0c;可使用pam_tally2模块进行设置。 Linux系统下的…

城市选择器小程序实现

1.效果图 2.使用方法 # 城市选择器&#xff0c; 城市数据库可自己导出 ##后台数据API 由HotApp小程序统计提供并维护&#xff0c;如果需要导出并部署在公司的生产环境&#xff0c;最后有SQL导出下载地址 ## 使用方法 - 复制pages/district到你的项目目录 - 把样式文件distr…

mysql dll文件的缺失和Can‘t connect to MySQL server on ‘localhost‘ (10061)

个人笔记&#xff08;整理不易&#xff0c;有帮助&#xff0c;收藏点赞评论&#xff0c;爱你们&#xff01;&#xff01;&#xff01;你的支持是我写作的动力&#xff09; 笔记目录&#xff1a;学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 个人随笔…

Java-Scanner类进阶+题目

Scanner进阶 接收整数数据时&#xff1a; 接收小数数据时&#xff1a; 例子&#xff1a; 可以先这样弄出scanner的框架&#xff1a; 未完待续... ...