Linux的内存寻址——浅谈分段和分页机制

Linux内核:内存管理(1)——内存寻址 内存控制单元(MMU)由分段单元和分页单元组成。 分段单元:将逻辑地址转换成一个线性(虚拟)地址,给一个进程分配不同的线性地址空间。 分页单元:将线性(虚拟)地址转化成一个物理地址,把同一线性地址空间映射到不同的物理空间。 其中,逻辑地址由一个段和偏移量组成;线性地址是一个uint32_t,可以表达4G的地址;物理地址用于内存寻址。 1分段单元:逻辑地址—>线性地址 给一个进程分配不同... 阅读详情

本文会以80x86架构,linux2.6为例,简单介绍内存的分段和分页机制。

1. 三种内存地址

关于内存地址,首先要了解它有三种,分别是

逻辑地址、线性地址和物理地址。

把逻辑地址转换为线性地址是由一个叫做分段单元的硬件电路完成的。

同样地,还有一个叫做分页单元的硬件电路负责把线性地址转换为物理地址。

那现在很明确地,当我们讨论分段的时候,就是讨论逻辑地址是如何转换成线性地址的。当我们讨论分页的时候,就是在讨论线性地址如何转换成了物理地址。

下面分开讨论分段和分页功能是如何实现。

2. 逻辑地址

介绍分段之前,先明确逻辑地址的构成分两部分:一个16位的段选择符,一个32位的偏移量。

其中段选择符由高到低是:13位index,1位TI,2位RPL。它们的作用在下文介绍。

3. 段选择符、段寄存器、段描述符

现在我们知道,段选择符是逻辑地址的一部分,为了方便找到段选择符,处理器提供了6个段寄存器,段寄存器的唯一目的就是存放段选择符。

段描述符有8个字节,负责描述段的特征,包括段的首字节的线性地址、段的最大长度、段的特权级、区分段是数据段还是代码段的标志位……一共9个字段。

段选择符和段描述符具有对应关系,那应该如何通过段选择符得到段描述符呢?答案是查找全局描述符表(GDT)或者局部描述符表(LDT)。

4. GDT\LDT

在linux中,每个CPU都有一个自己的GDT,用于存放本处理器寻址要用到的段描述符。linux有一个全局的cpu_gdt_table数组,放着每个cpu当前的GDT。每个GDT有32个表项,其中有14个空置,剩下的都是段描述符,包括了用户态代码段、用户态数据段、内核态数据段、内核态代码段、任务状态段TSS、3个局部线程存储段TLS……共18个段描述符。。

所谓LDT就是某些进程要有一些自己用的段,需要创建一个自己专用的描述符表,这就是LDT。

从硬件上看,处理器有两个寄存器专门存放GDT和LDT的基地址(是一个线性地址),分别叫做gdtr和ldtr。

5.分段单元的工作过程

Input:逻辑地址(段选择符和偏移量)

段选择符的TI字段决定了这个段的段描述符是在GDT还是LDT中,通过对TI字段的检查,分段单元可以知道它应该去gdtr还是ldtr去读表的基地址。

接下来看段选择符的index字段,这个字段说明了段描述符在表的第几项。因为每个段描述符是8字节,那么表的基地址+index*8就是段描述符的地址。

得到段描述符后,也就知道了段的基地址了。此时用段的基地址+段的偏移量,就得到最终的线性地址了。

Output:该逻辑地址对应的线性地址。

分段就介绍完了。而事实上,从2.6内核开始,Linux就只在80x80结构下才需要使用分段了。为什么linux偏爱分页呢?首先是因为忽略掉分段后,内存的管理简单了,相当于所有的段的基地址都相同,大家都是同一个段,linux只负责处理线性地址就好了;另外,不同的计算机体系结构对分段的支持不一,使用分段不利于linux的跨处理器平台。

所以在linux里,用户代码段、数据段,内核代码段数据段,它们的段描述符里,段的起始线性地址都是0x00000000。这意味着一个逻辑地址,它的偏移量就是它的线性地址。

好,接下来讨论分页。

6. 页,页框,页表

页是为了提高效率,把线性地址分成了固定长度的组,所以页就是一组连续的线性地址。在转换成物理地址的时候一次转换一页。

既然这样,那物理地址也要分组。分页单元把所有的RAM也分成了固定长度的组,叫做页框(所以页框就是一组连续的物理地址),页框和页长度一致,一个页框可以放一页。

知道了页和页框以后,那么我们怎么知道该把哪一页放进哪个页框里呢?这就要查页表了。页表放在主存里,页表可能分多级。

7.常规分页,扩展分页,64位系统的分页

从这里开始,我们默认分页单元处理的一页是4096字节。

一个32位的线性地址被分成三部分,从高位到地位分别是:10位的Directory,10位的table,12位的offset。

首先为什么要分多级呢?因为如果只有一级目录的话,那么表项会非常多。因为一页是4096 = 2^12字节,那么offset是一定要占12位的,剩下的20位将产生2^20个表项,一个表项4字节,载入一个页表就要占4MB的RAM,这太浪费了内存了。而当使用这种二级模式时,可以通过目录表先找到要读的页,这样一次只读2^10个表项,小了一半。

现在我们可以基本想象到分页单元是怎么把线性地址变成物理地址的了:假设有一个线性地址0x20180601,低12位offset是0x601,中间10位的table是0x180,高十位directory是0x080,directory表的物理地址在寄存器cr3中,读到directory后从第0x80项找到table,从table的第0x180项找到本页对应页框的起始物理地址,最后这个地址+0x601得到最终的物理地址。

但是实际操作中还有些细节,比如说,1024项directory,1024项table,和12位的偏移,一共可以寻址2^32个地址,涵盖了整个内存,但事实上一个进程只会从有限的线性地址空间内分配空间,假设内核给了一个线程64页,这已经是可以分配给进程的上限了,假设它的空间是0x2000 0000 到0x2003 ffff,目录项只有0x080是有用的,其他都要设置成0,同理,table里只有0到0x3f号的64个表项有用,其他也都设置成0。

如果这个进程想要访问超过这64页之外的空间,比如0x3000 0000,那必然是非法的,这个页根本不会在内存中,这就要返回一个缺页异常。我们需要一个标志位来表明这个页到底在不在主存里。可见,directory表和table表,每个表项除了要有对应的页表或者页框地址之外,还要有一些标志位。实际上,有一个present标志负责记录该页是否在主存中。如果试图访问一个present=0的表项,就会产生缺页异常。

除了这种常规分页,从Pentium开始,还引入了扩展分页PAE,允许一个页框达到4MB项,引入扩展分页后,offset有22位,高10位做目录,不再有二级模式。

分页到了64位系统中又有不同,因为在64位地址,4kb页框的情况下,除去12位的offset,剩下了48位做directory或者table。那这样显然会造成每张表的表项非常高。

那应该怎么解决呢?一个是增加分页级别,从原来的二级升高到3级或4级;另外可以让64位并不全用来寻址。至于寻址用多少位,分页分几级,会因处理器类型而异。像x64_64,用48位寻址,按9+9+9+9+12划分,一共有4级页表。

8. Linux分页

既然32位系统和64位系统分页方法不同,不同硬件系统分页的策略也不同,Linux是怎么适应这诸多硬件模型的呢?

linux采用了4级分页模型:分别是页全局目录PGD,页上级目录PUD,页中间目录PMD,页表PTE。如果是32位系统,而且没有PAE,那么PUD和PMD就不启用,全部置0。

Linux内用pte_t、pmd_t、pud_t和pgd_t描述页表、页中间目录、页上级目录和页全局目录,提供了丰富的api,可以操作每一级页表,进行读、写、清空等一系列操作。

OK,到此为止,本文简单的介绍了几个和分段分页相关的概念,包括分段相关的逻辑地址、段描述符、段选择符、段寄存器、GDT和LDT,以及分页相关的页、页框、页表、PAE、PTE、PMD、PUD和PGD等,并简单描述了分段单元和分页单元的工作过程。

Linux内存寻址之分段机制及分页机制 前言 最近在学习Linux内核,读到《深入理解Linux内核》的内存寻址一章。原本以为自己对分段分页机制已经理解了,结果发现其实是一知半解。于是,查找了很多资料,最终理顺了内存寻址的知识。现在把我的理解记录下来,希望对内核学习者有一定帮助,也希望大家指出错误之处。 分段到底是怎么回事 相信学过操作系统课程的人都知道分段分页,但是奇怪的是书上基本没提分段分页是怎么产生的,这就导致我们知其然不知 阅读详情

相关推荐

内存寻址之分页机制

写在前面:分页机制完成线性地址到物理地址的转换 80x86 规定分页机制是可选的。分段和分页没有什么必然联系,分段可以说是 Intel 的 CPU 一直保持着的一种机制,而分页只是保护模式下的一种内存管理策略。想开启分页机制,CPU必须工作在保护模式,而工作在保护模式可以不开启分页。分页机制由控制寄存器 CR0 中的 PG 位启用,如PG=1则启用分页机制,把线性地址转换为物理地址;如果PG=0则直

Tanswer_ 5833

大模型API成本优化:推理压缩与调用策略实战

大模型API调用成本已成为企业落地AI应用的核心瓶颈之一。其本质源于模型参数量、上下文长度与并发请求共同决定的计算资源消耗,遵循典型的算力-成本正相关原理。通过量化压缩、KV缓存复用、请求批处理等轻量级推理优化技术,可在不显著牺牲效果前提下降低30%~60%的单位token成本。该方案广泛适用于智能客服、内容生成、RAG增强检索等高并发低延迟场景,尤其适配当前主流开源模型(如Qwen、DeepSeek系列)的私有化部署与云API混合调用架构。

diaoju3333的博客 466

Linux内存寻址——分段机制

一、物理地址、虚拟地址和线性地址 将主板上的物理内存条所提供的内存空间定义为物理内存空间,其中每个内存单元的实际地址是物理地址;将应用程序员看到的内存空间定义为虚拟地址空间,其中的地址是虚拟地址。线性地址空间是指一段连续的,不分段的,范围从0到4GB的地址空间,一个线性地址就是线性地址空间的一个绝对地址。 MMU内存管理单元是硬件电路,包含两个部件,分段部件(分段机制)和分页部件(分页机制)。...

xiezhi123456的博客 357

Linux内存寻址-分段

对linux内核内存分段的学习

weixin_40822211的博客 549

【速通版!语义通信基础与前沿学习计划】

🧠语义通信基础与前沿学习计划

dally2的博客 1412

MaxEnt软件的下载与安装

1、下载网站:http://lucky-boy.ys168.com/ (这是之前在网上搜到的,里面有许多软件安装包,感谢网页主的资源共享,违权必删)

weixin_42191203的博客 2万+

GDT与LDT的区别

GDT(Global Descriptor Table)和LDT(Local Descriptor Table)是在x86架构中使用的两种描述符表,用于定义内存段的属性和访问权限。它们之间的主要区别在于作用域和使用方式。需要注意的是,现代操作系统往往不使用LDT,而是使用分页机制来实现虚拟内存管理和内存保护。因此,在现代操作系统中,GDT的使用更为常见,而LDT的使用相对较少。

weixin_62911043的博客 1885

成分数据的闭合效应对地球化学数据的影响及其解决方案

封闭效应 (Closure Effect),也称为常数和效应 (Constant Sum Effect),是地球化学数据分析中一个需要特别注意的统计现象。它的产生是由于我们通常使用成分数据 (Compositional Data)百分比 (%)百万分率 (ppm)由于这些数据表示的是各组分占总体的比例,它们的总和必然是一个常数 (例如 100% 或 1,000,000 ppm)。这意味着每个元素的含量不是独立的,而是与其他元素的含量相互制约。改变其中一个元素的含量必然会影响其他元素的相对比例。

qq_59349063的博客 1534

Linux内核之浅谈内存寻址

我们知道计算机是由硬件和软件组成,硬件主要包括运算器、控制器、存储器、输入设备和输出设备,软件主要是操作系统和用户应用软件,其中操作系统是联系硬件和软件的桥梁。文本主要分享运算器关于内存寻址的重点内容,从内存寻址的硬件机制重点和内核代码动手实践两部分来分享,欢迎交流。

金荣的个人技术博客 1628

【学习笔记】人群归因分数 PAF 以及combined PAF

人群归因风险比例(Population Attributable Fraction,PAF)是一个流行病学指标,它估计了在总体中,如果能消除一个特定的危险因素,能预防多少百分比的疾病或健康结果。简单来说,PAF回答的是:“如果没有这个风险因素,总体中会有多少病例是可以避免的?

weixin_53499537的博客 4899

手把手教你学Simulink--使用Simulink进行双冗余电机驱动系统的故障切换验证

提高系统可靠性:当一个电机或其驱动器出现故障时,另一个可以立即接管,避免系统停机。增强安全性:对于一些关键任务的应用场景(如飞行控制),确保即使在硬件故障情况下也能维持基本操作能力。简化维护:允许在不影响系统正常工作的情况下进行维护和更换故障部件。确定可能发生的故障类型(如过流、欠压、温度过高),以及每种故障对应的条件。通过上述步骤,我们简要介绍了如何基于Simulink实现双冗余电机驱动系统的故障切换验证。

MHD0815的博客 438

基于80x86的Linux的分段和分页机制

1 基于80x86的Linux分段机制80386的两种工作模式:80386的工作模式包括实地址模式和虚地址模式(保护模式)。Linux主要工作在保护模式下。在保护模式下,80386虚地址空间可达16K个段,每段大小可变,最大达4GB。逻辑地址到线性地址的转换由80386分段机制管理。段寄存器CS、DS、ES、SS、FS或GS各标识一个段。这些段寄存器作为段选择器,用来选择该段的描述符。分段逻辑

云(存储),松(耦合) 9950

第十届MathorCup高校数学建模挑战赛-B题:养老服务床位需求预测与运营模式研究

当养老床位数增加时存在的商机,提出了相应的养老服务床位的运营商业模式。就业的可能性,建立多目标规划模型,尽可能同时满足三方面的要求。务床位的需求、制定合理的养老服务床位发展规划,是构建和谐社会、幸福社会。问题一的床位需求与市场类型的分类结果,查找关于国内养老院的相关数据,探。求,又能持续发展养老事业,同时还能促进社会就业的养老服务床位运营的商业。养老服务床位数的增加能够带来的就业方面因素的影响,并对这些因素进行一个。你们的模型及其结论为科学依据,对政府管理部门针对养老床位规划提出合理的。

getusushu的博客 1139

Linux内存管理:内存寻址之分段机制与分页机制

目录 Linux 内存寻址之分段机制 前言 分段到底是怎么回事? 实模式的诞生(16位处理器及寻址) 保护模式的诞生(32位处理器及寻址) IA32的内存寻址机制 寻址硬件 IA32的三种地址 MMU地址转化过程 IA32的段寄存器 分段机制的实现 段描述符 段描述符表 总结 Linux中分段的实现 总结 Linux 内存寻址之分页机制 硬件中的分页 为什么使用两级页表 两级页表结构 页目录项 页面项 线性地址到物理地址的转换 扩展分页 页面高速缓存 Li

RToax 1007

YOLOv11改进策略【Backbone/主干网络】|替换HGNetV2骨干,包含RT-DETR中的l、x模型

本文记录的是基于HGNetv2的YOLOv11目标检测改进方法研究。本文利用HGNetv2替换YOLOv11的骨干网络,HGNetv2 通过其 GPU 推理友好的 3×3 标准卷积和层次化 HG Block 结构,能够为骨干网络提供高效且完整的特征提取能力。并且其中的和可在降低计算量的同时丰富特征表达,增强对多尺度目标特征的捕获能力,进而提高模型精度。本文配置了原论文中rtdetr-lrtdetr-x,以满足不同算力和检测精度的需求。

Limiiiing的博客 669

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Linux内存地址的分段、分页机制(上)

Linux内存地址的分段、分页机制(上),涉及Linux存储器结构等……

_IronMan's 博客 2123

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

第一讲 内存寻址

引子一段代码:#include <stdio.h> int foo; void main() { foo = 100; printf("%d\n",foo); } 问题:变量foo存放在内存的什么位置,printf又在什么位置,CPU如何访问(修改)它们?

li_boxue的博客 8318

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【Linux 内核知识梳理 10】Linux内存寻址之分段机制

【Linux 内核知识梳理 10】Linux内存寻址之分段机制及分页机制一、分段的由来1、实模式的诞生(16位处理器及寻址) 一、分段的由来 相信学过操作系统课程的人都知道分段分页,但是奇怪的是书上基本没提分段分页是怎么产生的,这就导致我们知其然不知其所以然。下面我们先扒一下分段机制产生的历史。 1、实模式的诞生(16位处理器及寻址) 在8086处理器诞生之前,内存寻址方式就是直接访问物理地址。 本文学自:《Linux内存寻址之分段机制及分页机制》 ...

|~~~热爱生活、努力学习的小伙汁~~~| 604

linux分段和分页机制其实很简单

       前面我们讲了linux操作系统在保护模式下的一些情况,在保护模式下段寄存器存放的不再是段地址,而是段选择符,用来索引段描述符。接下来我们来说一说一个逻辑地址如何使如何转换成线性地址的。        为此我画了一张图,如下:  &nb...

qq_32740495的博客 1196

Linux 内存管理(一)之分段机制

Linux 操作系统采用了分段机制来实现进程的内存管理。分段允许进程以逻辑上连续的方式访问内存,而无需将整个进程存储在连续的物理内存地址上。本文将介绍 Linux 的分段机制,包括分段的基本概念、分段表的组织方式和进程访问内存的原理。我们还将讨论 Linux 中的段选择子和段描述符,以及如何使用它们来管理进程的内存空间。现在大致了解了分段的基本原理,系统运行时,地址空间中不同段被重定位到物理内存中,与之前的整个物理地址空间中只有一个基地址+偏移量的方式相比,大量的节省了物理内存。

Projectsauron 的博客 6万+

linux进程内存空间分段包含,深入理解Linux内存寻址的分段机制

一、前言最近在学习Linux内核,读到《深入理解Linux内核》的内存寻址一章。原本以为自己对分段分页机制已经理解了,结果发现其实是一知半解。于是,查找了很多资料,最终理顺了内存寻址的知识。现在把我的理解记录下来,希望对内核学习者有一定帮助,也希望大家指出错误之处。二、分段到底是怎么回事相信学过操作系统课程的人都知道分段分页,但是奇怪的是书上基本没提分段分页是怎么产生的,这就导致我们知其然不知其所...

weixin_35816287的博客 325

linux内存寻址原来那么简单

以上就是计算机进行内存寻址的全过程,当然分页单元的过程主要是软件实现的,这里没有对linux的实现接口进行说明,如果感兴趣的可以下载linux 2.6版本查看,虽然新版本的linux分页单元有改动,但是还是推荐你看下2.6版本的,这个版本的功能实现更加的纯粹,也更容易理解。段是代码段、数据段、栈段,按照是否是内核态,又可以分为内核代码段、内核数据段、内核栈段,用户代码段、用户数据段、用户栈段,图中给出的Selector就是用来确定使用哪个段的。因为分段主要靠硬件,而分页主要靠软件。

andrewbytecoder 1182

Linux学习总结—内存分段和分页管理

1.x86 内存架构和Linux的分段管理x86 内存架构在 x86 架构中,内存被划分成 3 种类型的地址:·         逻辑地址 (logical address) 是存储位置的地址,它可能直接对应于一个物理位置,也可能不直接对应于一个物理位置。逻辑地址通常在请求控制器中的信息时使用。·         线性地址 (linear address) (或称为平面地址空间)是

cxy的Linux技术专栏 7765
上一篇: DPDK如何针对cache提高性能
下一篇: 浅谈linux的进程的静态特性——pid,进程状态,进程链表,等待队列
HelloNerd
博客等级 码龄12年 10粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值