Linux的地址空间

linux进程中的内存分布 进程空间分布概述 对于一个进程,其空间分布如下图所示: 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码。 初始化过的数据(Data):在程序运行初已经对变量进行初始化的数据。 未初始化过的数据(BSS):在程序运行初未对变量进行初始化的数据。 栈 (Stack):存储局部、临时变量,函数调用时,存储函数的返回指针,用于控制函数的调用和返回。在程序块开始时自动分配内存,结束时自动释放内存,其操作方式类似于数据结构中的栈。 堆 (Heap):存储动态内存分配,需要程序员手工. 阅读详情

在支持MMU的系统中,当系统做完硬件初始化后就使能MMU功能,这样整个系统就运行在虚拟存储空间中,实现虚拟存储空间到物理存储空间映射功能的是处理器的MMU,而虚拟存储空间与5路存储空间的映射关系则是由Linux内核来管理的。32位系统中物理存储空间占4GB空间,虚拟存储空间同样占4GB空间,Linux把物理空间中实际存在的远远小于4GB的内存空间映射到整个4GB虚拟存储空间中除映射I/O空间之外的全部空间,所以虚拟内存空间远远大于物理内存空间,这就说同一块物理内存可能映射到多处虚拟内存地址空间上,这正是Linux内存管理职责所在。图18-5列出了Linux内核中虚拟内存空间的一般布局(其实I/O空间也在其中,通常占用高端内存空间,在此未标出)。

 

 

图18-5  Linux系统虚拟内存空间一般布局示意图

 

说明:

 

1)线性地址空间:是指Linux系统中从0x00000000到0xFFFFFFFF整个4GB虚拟存储空间。

 

2)内核空间:内核空间表示运行在处理器最高级别的超级用户模式(supervisor mode)下的代码或数据,内核空间占用从0xC0000000到0xFFFFFFFF的1GB线性地址空间,内核线性地址空间由所有进程共享,但只有运行在内核态的进程才能访问,用户进程可以通过系统调用切换到内核态访问内核空间,进程运行在内核态时所产生的地址都属于内核空间。

 

3)用户空间:用户空间占用从0x00000000到0xBFFFFFFF共3GB的线性地址空间,每个进程都有一个独立的3GB用户空间,所以用户空间由每个进程独有,但是内核线程没有用户空间,因为它不产生用户空间地址。另外子进程共享(继承)父进程的用户空间只是使用与父进程相同的用户线性地址到物理内存地址的映射关系,而不是共享父进程用户空间。运行在用户态和内核态的进程都可以访问用户空间。

 

4)内核逻辑地址空间:是指从PAGE_OFFSET(3G)到high_memory(物理内存的大小,最大896)之间的线性地址空间,是系统物理内存映射区,它映射了全部或部分(如果系统包含高端内存)物理内存。内核逻辑地址空间与图18-4中的系统RAM内存物理地址空间是一一对应的(包括内存孔洞也是一一对应的),内核逻辑地址空间中的地址与RAM内存物理地址空间中对应的地址只差一个固定偏移量(3G),如果RAM内存物理地址空间从0x00000000地址编址,那么这个偏移量就是PAGE_OFFSET。

 

5)低端内存:内核逻辑地址空间所映射物理内存就是低端内存(实际物理内存的大小,但是小于896),低端内存在Linux线性地址空间中始终有永久的一一对应的内核逻辑地址,系统初始化过程中将低端内存永久映射到了内核逻辑地址空间,为低端内存建立了虚拟映射页表。低端内存内物理内存的物理地址与线性地址之间的转换可以通过__pa(x)和__va(x)两个宏来进行,#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) __pa(x)将内核逻辑地址空间的地址x转换成对应的物理地址,相当于__virt_to_phys((unsigned long)(x)),__va(x)则相反,把低端物理内存空间的地址转换成对应的内核逻辑地址,相当于((void *)__phys_to_virt((unsigned long)(x)))。

 

6)高端内存:低端内存地址之上的物理内存是高端内存(物理内存896之上),高端内存在Linux线性地址空间中没有没有固定的一一对应的内核逻辑地址,系统初始化过程中不会为这些内存建立映射页表将其固定映射到Linux线性地址空间,而是需要使用高端内存的时候才为分配的高端物理内存建立映射页表,使其能够被内核使用,否则不能被使用。高端内存的物理地址于线性地址之间的转换不能使用上面的__pa(x)和__va(x)宏。

 

7)高端内存概念的由来:如上所述,Linux将4GB的线性地址空间划分成两部分,从0x00000000到0xBFFFFFFF共3GB空间作为用户空间由用户进程独占,这部分线性地址空间并没有固定映射到物理内存空间上;从0xC0000000到0xFFFFFFFF的第4GB线性地址空间作为内核空间,在嵌入式系统中,这部分线性地址空间除了映射物理内存空间之外还要映射处理器内部外设寄存器空间等I/O空间。0xC0000000~high_memory之间的内核逻辑地址空间专用来固定映射系统中的物理内存,也就是说0xC0000000~high_memory之间空间大小与系统的物理内存空间大小是相同的(当然在配置了CONFIG_DISCONTIGMEMD选项的非连续内存系统中,内核逻辑地址空间和物理内存空间一样可能存在内存孔洞),如果系统中的物理内存容量远小于1GB,那么内核线性地址空间中内核逻辑地址空间之上的high_memory~0xFFFFFFFF之间还有足够的空间来固定映射一些I/O空间。可是,如果系统中的物理内存容量(包括内存孔洞)大于1GB,那么就没有足够的内核线性地址空间来固定映射系统全部物理内存以及一些I/O空间了,为了解决这个问题,在x86处理器平台设置了一个经验值:896MB,就是说,如果系统中的物理内存(包括内存孔洞)大于896MB,那么将前896MB物理内存固定映射到内核逻辑地址空间0xC0000000~0xC0000000+896MB(=high_memory)上,而896MB之后的物理内存则不建立到内核线性地址空间的固定映射,这部分内存就叫高端物理内存。此时内核线性地址空间high_memory~0xFFFFFFFF之间的128MB空间就称为高端内存线性地址空间,用来映射高端物理内存和I/O空间。896MB是x86处理器平台的经验值,留了128MB线性地址空间来映射高端内存以及I/O地址空间,在嵌入式系统中可以根据具体情况修改这个阈值,比如,MIPS中将这个值设置为0x20000000B(512MB),那么只有当系统中的物理内存空间容量大于0x20000000B时,内核才需要配置CONFIG_HIGHMEM选项,使能内核对高端内存的分配和映射功能。什么情况需要划分出高端物理内存以及高端物理内存阈值的设置原则见上面的内存页区(zone)概念说明。

 

8)高端线性地址空间:从high_memory到0xFFFFFFFF之间的线性地址空间属于高端线性地址空间,其中VMALLOC_START~VMALLOC_END之间线性地址:(1)被vmalloc()函数用来分配物理上不连续但线性地址空间连续的高端物理内存,或者(2)被vmap()函数用来映射高端或低端物理内存,或者(3)由ioremap()函数来重新映射I/O物理空间。其中PKMAP_BASE开始的LAST_PKMAP(一般等于1024)页线性地址空间:被kmap()函数用来永久映射高端物理内存。FIXADDR_START开始的KM_TYPE_NR*NR_CPUS页线性地址空间:被kmap_atomic()函数用来临时映射高端物理内存,其他未用高端线性地址空间可以用来在系统初始化期间永久映射I/O地址空间。

 

Linux 2.6.10内核中的ARM处理器平台部分没有对高端内存的支持,图18-6和图18-7分别列出了SA1100和IXP4XX处理器平台的Linux线性地址空间布局。


【Linux】进程的地址空间 地址是一个很重要的名词,我们的每一个进程在内存中运行都会有若干个地址。在之前我们学习进程的时候,学过一个函数——fork(),这个函数仅仅被调用一次,却能够返回两次。这是为什么呢?那么这一篇博客将会解释这种现象——进程的地址空间。 阅读详情

相关推荐

Linux: 进程地址空间究竟是什么?进程地址空间存在意义何在?

一、内存究竟是什么?分为哪些? 二、内存是真实物理空间? 三、进程地址空间(虚拟地址) 3.1 为何同一个变量地址相同,保存的数据却不同? 四、为什么需要地址地址空间和页表的存在? 4.1 真实内存无序便有序 4.2 进行内存安全检查 4.3 进程管理和内存管理藕接 五、其他细节问题 5.1 操作系统如何获取进程页表相关信息 5.2 操作系统如何确定内存中是否分配空间、是否存在内容?

Zhenyu_Coder的博客 4250

linux的物理内存空间与线性地址空间的的对应关系

在支持MMU的32位处理器平台上,Linux系统中的物理存储空间和虚拟存储空间的地址范围分别都是从0x00000000到0xFFFFFFFF,共4GB,但物理存储空间与虚拟存储空间布局完全不同。Linux运行在虚拟存储空间,并负责把系统中实际存在的远小于4GB的物理内存根据不同需求映射到整个4GB的虚拟存储空间中。 物理存储空间布局Linux的物理存储空间布局与处理器相关,详细情况可以

游手好弦 信步涂鸦 4001

Linux中的物理和虚拟存储空间布局

Linux中的物理和虚拟存储空间布局

Linux内存管理 | 五、物理内存空间布局及管理

我是董哥,高级嵌入式软件开发工程师,从事嵌入式Linux驱动开发和系统开发,曾就职于世界500强企业!创作理念:专注分享高质量嵌入式文章,让大家读有所得!

Donge's Blog 977

保姆级教程:2025新版JavPlayer 3.01整合修复版安装配置全流程(N卡/A卡/CPU通用)

本文提供2025新版JavPlayer 3.01整合修复版的保姆级安装配置教程,涵盖N卡、A卡和CPU环境。详细讲解硬件要求、分步安装流程、显卡优化配置及超分辨率模型选择,帮助用户高效完成视频修复任务。

weixin_42665255的博客 1875

各种AI的调试日记——辅助工作篇

记录使用各种AI(语言大模型)的心得和总结

m0_73056986的博客 1389

Linux内存布局详解

从堆段分配出nmemb*size字节的内存,即分配一块可容纳nmemb个元素、每个元素大小为size字节的数组的内存,将这块内存的初始化为0,并返回这块内存的起始地址。这个128KB可通过。:重新调整ptr所指向的已分配的内存大小为size字节,不会改变原来的内存的内容,也不会初始化新增的内存。从内存映射区申请内存,且释放时也可直接归还内存映射区的这块内存给内核,但是内核需要建立一系列复杂的数据结构来完成内存映射区的内存申请。:从堆段分配出size字节的内存,不会初始化这块内存,返回这块内存的起始地址。

llb_1203的博客 1900

trae CN 配置ida的mcp教程

本文介绍了在TraeCN中配置IDA Pro MCP服务的完整步骤:1)准备IDA Pro 9.0+和Python 3.11+环境;2)安装MCP服务端并配置插件;3)生成MCP配置文件;4)在TraeCN中添加HTTP类型MCP服务(默认端口13337);5)测试连接。重点说明了HTTP配置方式的操作流程,包括手动启动服务、正确填写JSON配置等关键环节。

2401_87915504的博客 1955

学习linux内核-- 内存,看一篇就够了(多图)

内存模块 1 linux内存总体布局:内存分成用户态和内核态 4G进程地址空间解析 内核地址空间 进程地址空间 2 地址转换和页表 2.1 地址转换 虚拟内存是指程序使用的逻辑地址。每个进程4G。所有进程共享物理内存4G,所以逻辑地址和物理地址不是一一对应,需要地址转换. 页表由3部分组成:页目录,页面,页内偏移 32bit只有3级 0 -11位:页内偏移OFFSET 12-21位:页面表偏移PT(PTE 页表项.指向一张具体的物理内存页) 22-31位:页面目录偏移.

csbmww的博客 1776

使用CubeMX生成的项目在Keil下添加DSP库并包含arm_math头文件后报错的解决办法

问题描述: 最近使用Cube生成工程后,在Keil中使用Manage Runtime Environment即绿色小饼干按钮添加CMSIS的DSP库后编译报错。很有意思的是,STM32论坛上有外国朋友报告的同样的错误,都是30个Errors,5个Warning。 问题分析: 参考国内论坛某帖子(具体想不起来了),认为因该是Cube复制了库后,Keil从原始Packs目录下引用DSP库导致和Cub...

qq_32256951的博客 7000

uniapp - H5网页打包运行报错Failed to load resource: net::ERR_FILE_NOT_FOUND(uniApp打包成H5部署到服务器,打包h5白屏并报错页面空白)

Failed to load resource: net::ERR_FILE_NOT_FOUND,uniapp 坑之打包之后白屏,uniapp打包h5,HBuilderX 打包H5后空白报错 Failed to load resource: net::ERR FILE NOT_FOUND,UNI-APP H5应用白屏(空白页)解决方案,白屏并报错Failed to load resource: net::ERR_FILE_NOT_FOUND,uniapp开发,打包成H5部署到服务器,uniapp打包之后首页

🏆 前端领域优质创作者 3576

【linux】地址空间

🔥个人主页Quitecoder🔥linux笔记仓。

Quietcoder的博客 1257

具身智能(40):主流 VLA 模型π₀

摘要: π₀是首款专为机器人设计的VLA(视觉-语言-动作)端到端基础模型,通过双阶段训练实现“感知-决策-执行”闭环。其创新点包括:1)FlowMatching技术实现连续平滑动作控制(精度0.3°);2)结合VLM预训练与多机器人实操数据,零样本任务完成率达76.4%,远超同类模型;3)支持模糊指令理解与动态场景适应(如遮挡识别)。开源版本涵盖不同规模模型,适用于工业装配、服务机器人等场景,在延迟(213ms)和稳定性(92%自主恢复率)上显著领先OpenVLA等竞品。

码农17年的博客 509

【Linux】地址空间

有一天,小明睡觉的时候不小心越过了三八线,于是他按照规定,将三八线向自己移动了 10 cm,他的课桌区域变为了 40 cm长,小红的课桌区域变为了 60 cm长。此时,私生子都向大富翁申请了一笔金额:A 申请了 2 万,B 申请了 10 万,C 申请了 2k,D 申请了 900。不可以,因为此时的 g_val 是父子共用的,如果修改后父进程又拿 g_val 参与运算,就会影响到父进程的运行,破坏了。如果进程直接与内存进行交互,万一发生越界修改数据了,不仅会对此进程造成影响,还可能会导致其他进程的崩溃。

Hello World! 1716

Android插件化和组件化面试题及参考答案

如何使用 Gradle 来管理 Android 项目中的模块依赖? Gradle 是一个强大的构建工具,在 Android 项目中管理模块依赖主要通过以下方式。 首先,在项目的根目录下的 build.gradle 文件中,需要配置仓库。一般会添加如 Google 的 Maven 仓库和 JCenter 等,例如在 repositories 部分添加: repositories { google() jcenter() } 对于模块依赖,在每个模块(例如 app

大模型大数据攻城狮的专栏 1182

QGis二次开发 —— 5、基于qgis开发多种在线地图预览,并加入经纬度坐标显示等(附:源码)

QGis二次开发 —— 5、基于qgis开发多种在线地图预览,并加入经纬度坐标显示等(附:源码

368

【Linux】进程地址空间

进程地址空间的组织和它的优势,以及页表的一些补充说明

s_little_monster的博客 8992

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Linux进程地址空间

我们知道对于C/C++程序来说,程序占用的内存地址分为栈区,堆区,静态区等等,每一个程序在编译时都会分配这些空间,这些空间只是规划的虚拟地址空间,并不是分配的真实的物理空间,这样划分虚拟地址空间是操作系统为了更好的管理和使用内存空间而做的,那么虚拟地址(也称逻辑地址)是如何与物理地址联系起来的呢?本节将为您介绍!进程地址空间的介绍到这里就告一段落了,相信大家认识了Linux底层的虚拟地址空间后,对很多进程地址相关的问题一定有所解答!

ARMCSKGT的博客 5511

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

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

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

【Linux系统】进程地址空间详解

进程地址空间是操作系统为每个运行中的进程分配的一个虚拟内存视图,它是所能访问的所有内存地址的集合。这给抽象层使得每个进程看起来都像是占用了整个计算机的内存资源,而实际上这些需您地址会v欸操作系统映射到物理内存中。本篇我将介绍进程地址空间的概念及使用这种方法带来的好处。在学习这块之前,我们需要一些背景知识作为铺垫学完上面的我们就可以知道为什么说进程相互独立:进程的PCB结构体是独立的、进程地址空间是独立的、页表是独立的、对进程切换时只需要切换PCB结构体对象就可以了。

2301_80774875的博客 2022

Linux —— 虚拟进程地址空间

页表是虚拟内存系统的核心数据结构,是连接虚拟地址和物理地址的“地图”或“翻译官”;是Kernel为每个进程维护的一个映射表,它记录了该进程的虚拟内存页对应到物理内存帧的映射关系简单来说,它的工作就是回答这个问题:“这个进程看到的虚拟地址 X,实际上在物理内存的哪个地方?OS 会将进程物理地址隐藏起来,我们只能观测到进程的虚拟地址。

2401_87692970的博客 1958

【Linux】Linux进程地址空间

RWX 属性:代表虚拟地址对应的物理地址是否具有读(R)、写(W)和执⾏权限 (X)。前⾯提到,每⼀个进程地址空间区域都由指定的起始值和终⽌值进⾏划分,⽽这些区 域有的是可以写,有的不可以写只能读,但是对于物理内存来说,绝⼤部分的空间都 是可以写的,所以对于限制指定的物理地址是否可以写⼊就是通过 RWX 属性进⾏控制例如,前⾯学习到的栈区和堆区,在程序代码运⾏时,可以在栈区和堆区申请空间并 进⾏写⼊,但是对于字符串常量等具有常性的值就不可以进⾏随意修改和写⼊。

2301_79582015的博客 1755

Linux 程序地址空间(重要)

Linux程序地址空间详解

yanxiao07的博客 1600

初识Linux · 地址空间

本文介绍的是有关地址空间,咱们的介绍的大体思路是,先直接看现象,通过现象我们引入地址空间的概念,然后是简单的介绍地址空间,如何理解地址空间等,在往后的学习中,我们大概会介绍地址空间3 - 4次,因为地址空间有很多内容一次性还介绍不完,并且在本文中,我们能够理解之前颠覆代码三观的函数——fork(),现在就进入正题。

更新各种计算机技能~ 2509

Linux:进程地址空间

对进程地址空间的认识

2301_82256131的博客 1829
上一篇: 文件系统概念理解
下一篇: 什么是接口技术
LinuxJoey
博客等级 码龄15年 117粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值