Linux 内存管理之highmem简介

32位系统有HIGHMEM_ZONE而64位没有HIGHMEM_ZONE的原因 查阅过很多的blog或者相关书,都说64位系统的空间足够所以不需要HIGHMEM ZONE,对于这句话一直是一知半解,今天仔细看了下相关的config,理解如下: 高端内存的由来: 在32位系统中总的地址空间是4GB,按照地址划分3G~4G为内核空间,0~3G为用户空间,此时PAGE_OFFSET为0xC0000000.如果物理内存的size为4GB,则后面3GB内核就无法访问,为了满足此要求... 阅读详情

一、Linux内核地址空间

一般来说Linux 内核按照 3:1 的比率来划分虚拟内存(X86等):3 GB 的虚拟内存用于用户空间,1GB 的内存用于内核空间。当然有些体系结构如MIPS使用2:2 的比率来划分虚拟内存:2 GB 的虚拟内存用于用户空间,2 GB 的内存用于内核空间,另外像ARM架构的虚拟空间是可配置(1:3、2:2、3:1)。内核线性地址空间用于为内核的运行提供最基本的支持,也是操作系统赖以存在的基础。所谓内核线性地址空间就是说内核态下虚拟地址与物理地址是线性关系,两者相差一个固定偏差,计算公式为VA(虚拟地址)=PA(物理地址)+PAGE_OFFSET。

二、什么是高端内存

以x86为例linux中内核使用3G-4G的线性地址空间,也就是说总共只有1G的地址空间可以用来映射物理地址空间。但是,如果内存大于1G的情况下内核态线性地址就不够用了。为此内核引入了一个高端内存的概念,把1G的线性地址空间划分为两部分:小于896M物理地址空间的称之为低端内存,这部分内存的物理地址和3G开始的线性地址是一一对应映射的,也就是说内核使用的线性地址空间(VA)3G--(3G+896M)和物理地址空间(PA)0-896M一一对应,PAGE_OFFSET=0xC0000000;剩下的128M的线性空间用来映射剩下的大于896M的物理地址空间,这也就是我们通常说的高端内存区,这部分空间需要MMU通过TLB表来建立动态的映射关系。

三、高端内存映射

高端内存映射有三种方式:

1、  临时映射空间

固定映射空间是内核线性空间中的一组保留虚拟页面空间,位于内核线性地址的末尾即最高地址部分。其地址编译时确定,用于特定用途(如VSYSCALL系统调用,MIPS的cache着色)。由枚举类型  fixed_addresses决定,内核在FIXADDR_START 到 FIXADDR_TOP 之间

在这个空间中,有一部分用于高端内存的临时映射。这块空间具有如下特点: 每个 CPU 占用一块空间;可以用在中断处理函数和可延迟函数的内部,从不阻塞,禁止内核抢占;在每个 CPU 占用的那块空间中,又分为多个小空间,每个小空间大小是 1 个 page,每个小空间用于一个目的,这些目的定义在 kmap_types.h 中的 km_type 中。

当要进行一次临时映射的时候,需要指定映射的目的,根据映射目的,可以找到对应的小空间,然后把这个空间的地址作为映射地址。这意味着一次临时映射会导致以前的映射被覆盖。

接口函数:kmap_atomic/kunmap_atomic。 使用从FIX_KMAP_BEGIN到FIX_KMAP_END之间的物理页

2、  长久映射空间

长久映射地址空间是预留的线性地址空间。访问高内存的一种手段。使用方式是先通过alloc_page() 获得了高端内存对应的 page,然后内核从专门为此留出的线性空间分配一个虚拟地址,在 PKMAP_BASE 到 FIXADDR_START 之间。

接口函数:void*kmap(struct *page)、 void kumap(struct *page)

该接口函数在高/低内存都能使用,可以睡眠,数量有限。对于不使用的的 page,及应该时从这个空间释放掉(也就是解除映射关系)。

#definePKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE * (LAST_PKMAP + 1)) & PMD_MASK)

#defineLAST_PKMAP 1024

3、非连续映射地址空间

非连续映射地址空间适用于为不频繁申请释放内存的情况,这样不会频繁的修改内核页表。总的来说,内核主要在以下情况使用非连续映射地址空间:映射设备的I/O空间;为内核模块分配空间;为交换分区分配空间

每个非连续内存区都对应一个类型为vm_struct 的描述符,通过next字段,这些描述符被插入到一个vmlist链表中。

这种方式下高端内存使用简单,因为通过vmalloc() ,在”内核动态映射空间“申请内存的时候,就可能从高端内存获得页面(参看 vmalloc 的实现),因此说高端内存有可能映射到”内核动态映射空间“中。

接口函数:vmalloc(vfree):物理内存(调用alloc_page)和线性地址同时申请,物理内存是 __GFP_HIGHMEM类型(分配顺序是HIGH, NORMAL , DMA )(可见vmalloc不仅仅可以映射HIGHMEM页框,它的主要目的是为了将零散的,不连续的页框拼凑成连续的内核逻辑地址空间... );

vmap(vumap):vmalloc的简化版;

ioremap(iounmap):分配I/O映射空间;

下图简单表达了linux内核对虚拟地址的映射,其中highmem区域用于对高端内存映射:

 

四、MIPS的高端内存

         Mips的highmem管理可参见其官方简介:http://www.linux-mips.org/wiki/Highmem

在MIPS32 CPU中不经过MMU转换的内存窗口只有kseg0和kseg1 的512MB的大小,而且这两个内存窗口映射到同一得0~512M的物理地址空间。其余的3G虚拟地址空间需要经过MMU转换成物理地址,这个转换规则是由CPU 厂商实现的。换句话说,在MIPS32 CPU下面访问高于512M的物理地址空间,必须通过MMU地址转换。即按VA=PA+PAGE_OFFSET公式映射的空间最大只有512M,其中PAGE_OFFSET=0x80000000,而在Linux中MIPS32只使用其中的256MB。

  MIPS在higmem使用过程中需要注意两个问题:一是要考虑由higmem带来的整个系统性能和稳定性间的平衡,二是highmem不支持cache aliases。

五、总结

高端内存含义为:线性地址空间 PAGE_OFFSET+HIGHSTART至4G的最后线性地址 <==映射==> HIGHSTART以上的物理页框,非直接映射。有3种方法:非连续内存区映射,永久内核映射,临时内核映射(固定映射)。

用户空间当然可以使用高端内存,而且是正常的使用,内核在分配那些不经常使用的内存时,都用高端内存空间(如果有),所谓不经常使用是相对来说的,比如内核的一些数据结构就属于经常使用的,而用户的一些数据就属于不经常使用的。

用户在启动一个应用程序时,是需要内存的,而每个应用程序都有3G的线性地址,给这些地址映射页表时就可以直接使用高端内存。

总之,内核的高端线性地址是为了访问内核固定映射以外的内存资源。实际上高端内存是针对内核一段特殊的线性空间提出的概念,和实际的物理内存是两码事。进程在使用内存时,触发缺页异常,具体将哪些物理页映射给用户进程是内核考虑的事情。在用户空间中没有高端内存这个概念。

注:1、本文中本文中虚拟地址和线性地址没做细致区分,可认为是一个概念。
2、关于highmem的代码分析可参见《 关于高端内存的一些笔记》一文:http://bbs.chinaunix.net/thread-1938084-1-1.html
Linux内核高端内存(High Memory)简介 由于 32 位系统的虚拟地址空间最大为 4GB(默认内核空间占用 1GB,用户空间 3GB),当物理内存超过内核可直接映射的范围(通常是 896MB)时,剩余的内存需要通过特殊机制进行管理,这就是高端内存的由来。在 64 位架构(如 x86_64)中,内核虚拟地址空间极大(如 128TB),可直接线性映射所有物理内存(`phys_base` 偏移),因此不再需要高端内存机制。- 内核默认将虚拟地址空间的 `0xC0000000`(3GB)到 `0xFFFFFFFF`(4GB)划分为内核空间(共 1GB)。 阅读详情

相关推荐

[内存管理] linux kernel内存映射实例分析

作者:JHJ(jianghuijun211@gmail.com) 日期:2012/08/24 欢迎转载,请注明出处   引子 现在android智能手机市场异常火热,硬件升级非常迅猛,arm cortex A9 + 1GB DDR似乎已经跟不上主流配置了。虽说硬件是王道,可我们还是不禁还怀疑这么强大的硬件配置得到充分利用了吗?因此以后我都会正对ARM平台分析kernel的内容。  正文

crazyjiang的专栏 1万+

Linux HighMemory(高端内存)

目前。32位的x86架构是最受欢迎的计算机架构。在这种架构中,传统上Linux内核将4GB的虚拟内存地址空间分为3GB用户内存和1GB内核空间。在传统大小的32位系统上,这意味着内核可以将所有物理内存映射到其地址空间,这使得以下内容成为可能:直接从内核中访问任何内存,这使事情变得更加简单和快捷。使用从内核对象到另一个对象的指针。 另一种方法是跟踪物理地址,映射到物理地址,并在访问之前计算结构的虚拟...

lzf的博客 3890

学习Linux内核内存管理要看的布局图

ZONE_NORMAL大小760MB,从0xc0000000 - 0xef800000,ZONE_HIGHMEM大小264MB,从0xef800000 - 0xffffffff。swapper_pd_dir的大小为16KB,对应的虚拟地址空间是从0xc0004000 - 0xc0008000,物理地址空间是0x6000400~0x60008000。从mem_init中打印的log,可以看出:_text - _etext,0xc060a09c - 0xc0008000=6153KB,采用1K对齐。

m0_74282605的博客 719

Linux Highmem的使用

Linux kernel zone有如下类型:ZONE_DMA, ZONE_NORMAL和ZONE_HIGHMEM。 每一种zone类型适合不同的使用类型: ZONE_DMA是低端物理内存范围适合于ISA设备的请求,ZONE_DMA的物理页框映射到kernel线性地址空间。 ZONE_NORMAL则被直接映射到kernel线性地址空间,常见的内核操作都发生在ZONE_NORMAL。 ZON

kickxxx的专栏 7082

VLA、世界模型与端到端在智驾中的本质关系与工程落地

世界模型并非3D重建,而是对环境状态转移函数的可微分建模;VLA不是视觉+语言+动作的简单拼接,核心在于跨模态语义对齐。二者共同支撑具身智能系统实现从感知到行动的闭环推演,其技术价值体现在长尾场景泛化能力提升与决策延迟降低。在自动驾驶领域,真实量产方案均采用VLA架构作为多模态感知基础,嵌入轻量级世界模型以支持反事实轨迹推演,并通过WA硬件封装保障实时性,最终由端到端控制层完成像素到扭矩的语义贯通。这种混合架构已成L2+/L3智驾系统的工程共识。

weixin_34163553的博客 365

ZYNQ 系统的IEEE1588 实现方法

zynq IEEE588/PTP 实现方案(讨论稿)

姚家湾博客 1万+

linux内存管理子系统采用基于内存区域,Linux 内存管理之highmem简介

一、Linux内核地址空间一般来说Linux 内核按照 3:1 的比率来划分虚拟内存(X86等):3 GB 的虚拟内存用于用户空间,1GB 的内存用于内核空间。当然有些体系结构如MIPS使用2:2 的比率来划分虚拟内存:2 GB 的虚拟内存用于用户空间,2 GB 的内存用于内核空间,另外像ARM架构的虚拟空间是可配置(1:3、2:2、3:1)。内核线性地址空间用于为内核的运行提供最基本的支持,也是...

weixin_39652646的博客 463

告别误唤醒!S32K3xx低功耗设计避坑指南:Fast Standby模式与WISR寄存器操作详解

本文深入解析了NXP S32K3xx系列MCU在低功耗设计中常见的误唤醒问题,并提供了基于Fast Standby模式的解决方案。文章重点剖析了DCMRWF5寄存器的配置方法、WISR/WISR_64唤醒中断状态寄存器的标志位处理策略,以及如何利用32KB Standby SRAM保存唤醒状态,从而帮助开发者构建稳定可靠的汽车电子低功耗系统。

weixin_29163857的博客 361

linux 高端内存

Linux对内存的管理划分成三个层次,分别是Node、Zone、Page。对这三个层次简介如下: 层次说明 Node(存储节点)CPU被划分成多个节点,每个节点都有自己的一块内存,可以参考NUMA架构有关节点的介绍 Zone(管理区)每一个Node(节点)中的内存被划分成多个管理区域(Zone),用于表示不同范围的内存 Page(页面)每一个管理区又进一步被划分为多个页面,页面是内...

zzt4326的博客 303

嵌入式存储进阶:除了KV存储,EasyFlash的IAP和LOG功能怎么玩?

本文深入探讨了嵌入式存储方案EasyFlash的高级功能,包括在线固件升级(IAP)和闪存日志存储(LOG)。通过详细解析IAP的双区备份设计和LOG的环形缓冲区架构,提供硬件适配、安全升级流程和日志管理技巧等实战指南,帮助开发者在物联网设备中实现可靠的数据存储和固件更新。

weixin_29280219的博客 413

NVIDIA DGX Spark实战:如何在桌面上轻松运行200B参数大模型?

本文详细介绍了如何利用NVIDIA DGX Spark在桌面端轻松运行200B参数大模型。通过实战演示,从系统初始化、模型获取部署到内存管理与性能调优,重点解析了其统一内存架构如何解决本地推理的显存瓶颈,并探讨了进行轻量化微调(如LoRA)的可能性,为AI开发者和研究团队提供了高效的本地化大模型操作方案。

weixin_29054195的博客 882

Linux 内存管理之 highmem

Linux,内存管理,highmem

JiMoKuangXiangQu的专栏 447

DeepSeek安装教程

两分钟讲述deepseek正确安装教程

weixin_45906703的博客 1662

Linux内存管理之高端内存

Linux对内存的管理划分成三个层次,分别是Node、Zone、Page。对这三个层次简介如下: 层次 说明 Node(存储节点) CPU被划分成多个节点,每个节点都有自己的一块内存,可以参考NUMA架构有关节点的介绍 Zone(管理区) 每一个Node(节点)中的内存被划分成多个管理区域(Zone),用于表示不同范围的内存 Page(页面) 每一个管理区又进...

ibless的博客 6685

零基础实战:云开发家政维修小程序搭建指南

欢迎来到这本关于构建家政维修小程序的电子书!在当今数字化的浪潮中,线上服务已成为我们生活中不可或缺的一部分。从点餐购物到居家维修,人们越来越习惯通过指尖轻点来解决各种需求。正是基于这样的背景,我们希望通过这个系列,手把手地带领大家从零开始,搭建一个功能完备、体验流畅的家政维修平台。这不仅仅是一本技术教程,更是一次将想法变为现实的探索之旅。我们将深入浅出地讲解如何运用云开发等现代技术,实现从用户下单、支付,到客服派单、工人接单,再到订单完成和权限管理等一系列核心业务流程。

低代码布道师的博客 3425

【时时三省】tessy 进入调试模式 教程

山不在高,有仙则名。水不在深,有龙则灵。----优快云 时时三省。

时时三省的博客 769

linux内核内存管理(zone_dma zone_normal zone_highmem)

Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中。 Linux内核地址空间划分 通常32位Linux内核地址空间划分0~3G为用户空间,3~4G为内核空间。注意这里是32位内核地址空间划分,64位内核地址空间划分是不...

mayi_xiaochaun的博客 1073

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Linux中内存管理详解

逻辑地址和地址映射 如果用户进程直接操作物理地址会有以下的坏处: 1、 用户进程可以直接操作内核对应的内存,破坏内核运行。 2、 用户进程也会破坏其他进程的运行 CPU中寄存器中存储的是逻辑地址,需要进行映射才能转化为对应的物理地址,然后获取对应的内存。 通过引入逻辑地址,每个进程都拥有单独的逻辑地址范围。 当进程申请内存的时候,会为其分配逻辑地址和物理地址,并将逻辑地址和物理地址做一个映射。 不同进程的逻辑地址可以一样,但是其映射的物理地址是不一样的。 逻辑地址 分为 内核空间 和 用户空间。 内核空间

qq_40276626的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Linux内核架构浅谈34-Linux内存域:ZONE_DMA、ZONE_NORMAL与ZONE_HIGHMEM解析

Linux内核通过内存域(zone)机制对物理内存进行逻辑分区,主要包括ZONE_DMA(供硬件设备直接访问的低地址内存)、ZONE_NORMAL(内核直接映射的核心区域)和ZONE_HIGHMEM(32位系统突破4GB限制的高端内存)。内存域的设计平衡了硬件限制与软件需求:ZONE_DMA兼容老式设备,ZONE_NORMAL提供高效访问,ZONE_HIGHMEM扩展32位系统内存容量。

文石_2009的博客 939

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

深入linux内核架构--内存管理(简介)

前言   内存管理其实是一个很基本的概念,但是真正能把linux内存管理梳理清楚的人很少,也看过网上很多关于内存管理的文章,但是总感觉他们其实也是照搬的一些概念,都不是很系统,看起来冰山一角,似懂非懂。那么今天就系统的结合linux源码来记录一下内存管理,希望能形成一套完整体系,对Linux内存有一个完整的了解。(文章后续的很多内存数字举例都是基于4GB物理内存大小的系统)。   关于内存管理一...

jinking01的专栏 2373

Linux的ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM及分配页释放页函数的简单介绍

Linux的ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM及分配页释放页函数的简单介绍

aoeaoao的博客 1546

linux内核之内存管理

虽然处理器的最小可寻址单位是字,但是内存管理单元(MMU,将虚拟地址转为物理地址的硬件)通常以页为单位进行处理(一般为32位系统为4k,64位系统为8k,如果页为4k,物理内存为1G,则物理内存会被划分为1G/4k=262144个页,这些页信息通过page结构体全部保存在内存中)。按照如上直接映射的方式,会发现内核只能访问1G的内存,但我们的物理内存实际上会达到8G、16G,甚至更高,所以必须要有一种灵活的方式来让内核访问到全部的物理内存,因此linux高端内存十分必要。这也是用户空间分配方式。

抱猫人的博客 1348
上一篇: linux内核启动地址 解压缩 启动参数
下一篇: 视频与图像RGB/YUV格式
evenness
博客等级 码龄15年 99粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值