Linux内存管理和寻址详解
1.概念
- 内存管理模式
段式:内存分为了多段,每段都是连续的内存,不同的段对应不用的用途。每个段的大小都不是统一的,会导致内存碎片和内存交换效率低的问题。
页式:内存划分为多个内存页进行管理,如在 Linux 系统中,每一页的大小为 4KB
。由于分了页后,就不会产生细小的内存碎片。但是仍然也存在内存碎片问题。
段页式:段式和页式结合。
- 地址类型划分
逻辑地址:程序所使用的地址,通常是没被段式内存管理映射的地址,称为逻辑地址
线性地址:通过段式内存管理映射的地址,称为线性地址,也叫虚拟地址
虚拟地址:通过段式内存管理映射的地址,称为线性地址,也叫虚拟地址
物理地址:物理内存地址
说明:
Inetel处理器中,逻辑地址是「段式内存管理」转换前的地址,线性地址则是「页式内存管理」转换前的地址。
段式内存管理映射而成的地址不再是“物理地址”了,Intel 就称之为“线性地址”(也称虚拟地址)。于是,段式内存管理先将逻辑地址映射成线性地址,然后再由页式内存管理将线性地址映射成物理地址。
linux内存主要是页式内存管理,同时也有涉及段式机制。当前Linux内核所采取的办法是使段式映射的过程实际上不起什么作用。
Intel最早处理器80286是纯段式管理,80386段式和页式均存在。
2.页式管理
x86架构32位cpu
二级页表选址方式,一个内存页4KB大小,一级页目录表1024项,二级页表1024项,一个页表项4字节。一级页目录表项全部分配,二级页表在需要的时候创建。(局部性原理)。
虚拟地址32位
10+10+12,分别索引1级页表号,2级页表项,记录物理基地址的偏移地址。使用PAE机制之后32bit系统支持最大的内存是64GB(地址是32+4=36位)。
线性地址寻址物理地址步骤
先根据10位寻址1级页表号,1级页表号中记录了2级页表的地址
找到2级页表地址后,接着根据虚拟地址的另10位寻找2级页表中表项的位置
找到2级页表的表项之后,表项中记录了该虚拟地址映射物理地址的起始地址,表项的大小是4字节32bit
根据找到的物理地址的起始地址结合虚拟地址的后12位作为偏移计算出最终的物理地址
x86架构 64位cpu
存在更多级页表
- 全局页目录项 PGD(Page Global Directory
- 上层页目录项 PUD(Page Upper Directory)
- 中间页目录项 PMD(Page Middle Directory)
- 页表项 PTE(Page Table Entry)
线性地址寻址物理地址步骤
- 线性地址为48bit,最大物理地址为52bit,实际物理内存地址总线宽度是40bit,也就是支持1TB物理内存
- x86_64有四级页表,原理同x86系统,也是一层层的寻址
- CR3寄存器保存最高层一级表的起始物理地址,因此寻址首先就是要获取到CR3寄存器中的值
- 每个PTE表项的大小是8个字节也就是64bit
TLB
在 CPU 芯片中,加入了一个专门存放程序最常访问的页表项的 Cache,这个 Cache 就是 TL(Translation Lookaside Buffer) 。通常称为页表缓存、转址旁路缓存、快表等。那么在CPU的内存管理单元MMU寻址时,会先查 TLB,如果没找到,才会继续查常规的页表。
专有名词
PDT:页目录表,多级页表一级页表,32bit系统有1024个页目录
PTT:页表项表,多级页表二级页表,32bit系统有每个页目录下有1024个页表项,每个表项4个字节
PDE:页表的基址,是PDT中一项
PTE:是页的基址,是PTT中一项
GDT:全局描述符表,逻辑地址转为线性地址用到
LDT:局部描述符表,逻辑地址转为线性地址用到
3.地址划分
32系统
内核1G: 0xC0 00 00 01 - 0xFF FF FF FF
用户3G: 0x00 00 00 00 - 0xC0 00 00 00
0xC0 00 00 00 == 3G64位系统:
内核128T: 0xFF FF 80 00 00 00 00 00 - 0xFF FF FF FF FF FF FF FF (高位)
0xFF FF 7F FF FF FF FF FF - 0xFF FF FF FF FF FF FF FF(自己计算)用户128T: 0x00 00 00 00 00 00 00 00 - 0x00 00 7F FF FF FF FF FF (低位)
0x00 00 80 00 00 00 00 00 - 0x00 00 80 00 00 00 00 00 (自己计算)
0x00 00 7F FF FF FF FF FF == 127T
疑问:64位系统128T是分界线是127T?
访问权限
进程在用户态时,只能访问用户空间内存
只有进入内核态后,才可以访问内核空间的内存PAE机制
CPU位宽指的是一个时钟周期内CPU能处理的二进制位数,普通场景中32位系统CPU的地址总线可以是32位,但是引入了PAE机制之后,16位CPU的地址总线位宽可以是20位(物理内存1M),32位CPU的地址总线可以是36位(物理内存64GB),64位CPU的地址总线位宽可以是40位(物理内存1TB)。因此我们不能简单的说32位系统只支持最大4GB的内存条。
4. 调试
程序寄存器
cs:是代码段寄存器
ds:是数据段寄存器
ss:是堆栈段寄存器
es:是扩展段寄存器
fs:是标志段寄存器 32位之后才有
gs:是全局段寄存器 32位之后才有示例一个内核宕机的日志:
RIP: 0010:[] [] xxxxxxxxxx+0x69/0x70
RSP: 0018:ffff886241737d98 EFLAGS: 00010246
RAX: ffff880034814d40 RBX: ffff881fc6248740 RCX: 0000000000000200
RDX: 0000000000000000 RSI: 0000000000000286 RDI: ffff881fc6381858
RBP: ffff886241737d98 R08: ffff886241734000 R09: 0000000000000000
R10: ffff880034814d40 R11: 0000000000000200 R12: ffff881fc62487a0
R13: 0000000000000000 R14: 00007fff86cb6260 R15: ffff881fc6381858
FS: 00007f78b59b8720(0000) GS:ffff885ffe3c0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f690a057180 CR3: 0000006208985000 CR4: 00000000003627e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400查看程序寄存器
使用GDB随意调试一个linux 32位上的ELF32的可执行文件,使用info r命令查看一下寄存器情况:
段寄存器有0x23和0x2b两种情况:
十六进制:0023
二进制:0000000000100 0 11 - 段序号:4 - 表类型:GDT - 特权级:Ring3
十六进制:002B
二进制:0000000000101 0 11 - 段序号:5 - 表类型:GDT - 特权级:Ring3段序号:从第四位开始 表类型:第三位 特权级:第1、2位
Linux下没有找到可以直接用什么命令或者工具查看GDT的方式,于是去源代码中寻找答案:
看到了吗,这两项所描述的段和Windows一样,基地址为0,大小为4GB。
Windows和Linux都选择了通过这种方式架空了CPU的分段内存管理机制。
但需要说明一下的时,虽然两个操作系统都是这种情况,但并不意味着段机制彻底没用到,CPU的任务管理TSS还是需要用到,这一点大家知道就行了,在linux64位系统下分段机制不被待见,但是操作系统仍然会保持先分段再分页的寻址方式。
5.参考资料:
图形化解释内存:https://segmentfault.com/a/1190000023055534#item-2-6
图形代码结合:https://www.cnblogs.com/alantu2018/p/9177356.html
当代操作系统内存管理:https://www.cnblogs.com/xuanyuan/p/15266447.html
GDT:https://en.wikipedia.org/wiki/Global_Descriptor_Table
线性地址转为物理地址实践:https://www.cnblogs.com/onetrainee/p/11721946.html
64位系统40位物理地址解释:https://zhuanlan.zhihu.com/p/69334474
Linux内存管理和寻址详解的更多相关文章
- Linux内存管理之mmap详解
转发之:http://blog.chinaunix.net/uid-26669729-id-3077015.html Linux内存管理之mmap详解 一. mmap系统调用 1. mmap系统调用 ...
- Linux 内存管理之mmap详解
找了好多,最后发现下面这篇时讲的比较通俗易懂的. Linux内存管理之mmap详解-heavent2010-ChinaUnix博客 http://blog.chinaunix.net/uid-2666 ...
- 转:Linux内存管理之mmap详解
一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进内存.文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零.munmap执行相 ...
- [转载] Linux内存管理之mmap详解
转载自http://blog.chinaunix.net/uid-26669729-id-3077015.html 一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进 ...
- Linux内存管理之mmap详解 【转】
转自:http://blog.chinaunix.net/uid-26669729-id-3077015.html 一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进 ...
- Linux内存管理之mmap详解 (可用于android底层内存调试)
注:将android底层malloc换为mmap来获取内存,可将获取到的内存添加tag,从而再利用meminfo进行分析,可单独查看该tag的内存,从而进行分析. 一. mmap系统调用 1. mma ...
- Linux服务管理 systemctl命令详解
Linux服务器,服务管理--systemctl命令详解,设置开机自启动 syetemclt就是service和chkconfig这两个命令的整合 任务 旧指令 新指令 使某服务自动启动 ch ...
- Linux权限管理命令chmod详解
命令chmod详解 命令chmod(英文原意:change permissions mode of a file),所在路径为: 可以看到,它的路径为:/usr/bin/chmod,因此,它的执行权限 ...
- JVM内存管理--GC算法详解
标记/清除算法 首先,我们回想一下上一章提到的根搜索算法,它可以解决我们应该回收哪些对象的问题,但是它显然还不能承担垃圾搜集的重任,因为我们在程序(程序也就是指我们运行在JVM上的JAVA程序)运行期 ...
随机推荐
- 洛谷 P4774 [NOI2018] 屠龙勇士
链接:P4774 前言: 交了18遍最后发现是多组数据没清空/ll 题意: 其实就是个扩中. 分析过程: 首先发现根据题目描述的选择剑的方式,每条龙对应的剑都是固定的,有查询前驱,后继(在该数不存在前 ...
- 到底能不能用 join
互联网上一直流传着各大公司的 MySQL 军规,其中关于 join 的描述,有些公司不推荐使用 join,而有些公司则规定有条件的使用 join, 它们都是教条式的规定,也没有详细说其中的原因,这就很 ...
- Typora和PicGo-Core搭配使用
作用:快速上传图片并获取图片 URL 链接的工具,图片存放到Gitee仓库中,在博客网站发布时不必担心图片转存失败问题 Gitee 创建一个新仓库 生成一个新令牌 生成后只显示一次,请妥善保管 Pic ...
- SpringBoot整合reids之JSON序列化文件夹操作
前言 最近在开发项目,用到了redis作为缓存,来提高系统访问速度和缓解系统压力,提高用户响应和访问速度,这里遇到几个问题做一下总结和整理 快速配置 SpringBoot整合redis有专门的场景启动 ...
- 你说说RPC的一个请求的流程是怎么样的?
前言 面试的时候经常被问到RPC相关的问题,例如:你说说RPC实现原理.让你实现一个RPC框架应该考虑哪些地方.RPC框架基础上发起一个请求是怎样一个流程等等.所以这次我就总结一波RPC的相关知识点, ...
- upload-labs通关攻略(1-11关)
upload-labs通关攻略 upload-labs是练习文件上传很好的一个靶场,建议把upload-labs关卡全部练习一遍 1.下载安装 下载地址 链接:https://pan.baidu.co ...
- GitHub 开源的小工具「GitHub 热点速览 v.21.45」
作者:HelloGitHub-小鱼干 Copilot 是 GitHub 官方出品的代码自动补全工具,之前使用该工具需要有一定的要求.而本周靠 2k+ star 上热点的 copilot-docs 则是 ...
- 【Python+postman接口自动化测试】(8)以青云客机聊天器人和图灵聊天机器人接口示范python发送get和post
以青云客机器人和图灵机器人接口示范python发送get和post 发送请求,我们这里主要使用Python的一个第三方包(需要先安装):requests. Python3自带的http.client和 ...
- 3D 穿梭效果?使用 CSS 轻松搞定
背景 周末在家习惯性登陆 Apex,准备玩几盘.在登陆加速器的过程中,发现加速器到期了. 我一直用的腾讯网游加速器,然而点击充值按钮,提示最近客户端升级改造,暂不支持充值(这个操作把我震惊了~).只能 ...
- [Vue warn]: Unknown custom element: <sapn> - did you register the component correctly? For recursive components, make sure to provide the "name" option. found in ---> <Evaluate> at src/views/index/
关于vue报错: [Vue warn]: Unknown custom element: <sapn> - did you register the component correctly ...