ARM32 内核内存布局【转】

转自:https://www.cnblogs.com/linhaostudy/p/12857407.html

Linux内核在启动时会打印出内核内存空间的布局图,下面是ARM Vexpress平台打印出来的内存空间布局图:

ARM32 内核内存布局【转】

这部分信息打印是在mem_init()函数中实现的。

[start_kernel->mm_init->mem_init]
    pr_notice("Virtual kernel memory layout:\n"
          "    vmalloc : 0x%16lx - 0x%16lx   (%6ld GB)\n"

编译器在编译目标文件并且链接完成之后,就可以知道内核映像文件最终的大小,接下来打包成二进制文件,该操作由 arch/arm/kernel/vmlinux.ld.S控制,其中也划定了内核的内存布局。

内核image本身占据的内存空间从_text段到 _end段,并且分为如下几个段:

  • 代码段:_text和 _etext为代码段的起始和结束地址,包含了编译后的内核代码。
  • init段: __init_begin__init_end为init段的起始和结束地址,包含了大部分的模块初始化的数据。
  • 数据段: _sdata_edata为数据段的起始和结束地址,包含了大部分内核的变量;
  • BSS段: __bss_start__bss_stop为BSS段的开始和结束地址,包含初始化为0的所有静态全局变量。

上述几个段的大小在编译链接时根据内核配置来确定,因为每种配置代码段和数据段长度都不相同,这取决与要编译哪些内核模块,但是起始地址 __text总是相同的。内核编译完成后,会生成一个System.map文件,查询这个文件可以找到这些地址的具体数值。

ARM32 内核内存布局【转】

内核使用虚拟地址从MODULES_VADDR到MODULES_END这段14MB大小的内存区域。

用户空间和内核空间使用3:1的划分方法时,内核空间只有1GB大小。这1GB的映射空间,其中有一部分用于直接映射物理地址。这个区域称为线性映射区。在ARM32平台上,物理地址[0:760MB]的这一部分内存被线性映射到[3GB:3GB+768MB]的虚拟地址上。 线性映射区的虚拟地址和物理地址相差PAGE_OFFSET,即3GB。内核中有相关的宏来实现线性映射区虚拟地址与物理地址的查找过程,例如 __pa(x)__va(x)

[arch/arm/include/asm/memory.h]
#define __pa(x) __virt_to_phys((unsigned long)(x))
#define __va(x) ((void *)__phys_to_virt(phys_addr_t)(x))
static inline phys_addr_t __virt_to_phys(unsigned long x)
{
    return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET;
}

static inline unsigned long __phys_to_virt(phys_addr_t x)
{
    return x - PHYS_OFFSET + PAGE_OFFSET;
}

其中,__pa()把线性映射区的虚拟地址转换为物理地址,转换公式很简单,即用虚拟地址减去PAGE_OFFSET(3GB),然后再加上PHYS_OFFSET(这个值在有的ARM平台上为0,在ARM Vexpress平台该值为0x6000_0000)。

那么高端内存的起始地址(760MB)如何确定呢?

在内核初始化内存时,在 santiy_check_meminfo()函数中确定高端内存的起始地址,全局变量high_memory来存放高端内存的起始地址。

static void * __initdata vmalloc_min =
    (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET);
void __init sanity_check_meminfo(void)
{
    phys_addr_t vmalloc_limit = __pa(vmalloc_min - 1) + 1;
    arm_lowmem_limit = vmalloc_limit;
    high_memory = __va(arm_lowmem_limit - 1) + 1;
}

vmalloc_min计算出来的结果是0x2F80_0000,即760MB;

为什么内核只线性映射760MB呢?剩下的264MB的虚拟地址空间用来做什么呢?

那是保留给vmallc,fixmap和高端向量等使用的。内核许多驱动使用vmalloc来分配连续的虚拟地址的内存,因为有的驱动不需要连续的物理地址的内存;除此之外,vmalloc还可以用于高端内存的临时映射。一个32bit系统中实际支持的内存数量会超过内核线性映射的长度,但是内核具有对所有内存的寻找能力。

vmalloc区域在ARM32内核中,从VMALLOC_START开始到VMALLOC_END结束,即从0xf000_0000到0xff00_0000,大小为240MB。从VMALLOC_START开始之前有一个8MB的洞,用于捕捉越界访问。

内核通常把物理内存低于760MB的称为线性映射内存(Normal Memory),而高于760MB以上的称为高端内存(High Memory)。由于32位系统的寻址能力只有4GB,对于物理内存高于760MB而低于4GB的情况,我们可以从保留240MB的虚拟地址划出一部分用于动态映射高端内存,这样内核就可以访问到全部的4GB的内存了。如果物理内存高于4GB,那么在ARMv7-A架构中就要使用LPE机制来扩展物理内存访问了。用于映射高端内存的虚拟地址空间有限,所以又可以划分为两部分,一部分是临时映射区,另一部分为固定映射区。PKMAP指向的就是固定映射区。如图2.6所示是ARM Vexpress平台上画出内核空间的内存布局图,详细可以参考文档documentation/arm/memory.txt文件。

ARM32 内核内存布局【转】
如果您觉得阅读本文对您有帮助,请点一下"推荐"按钮,您的"推荐"将是我最大的写作动力!

Original: https://www.cnblogs.com/sky-heaven/p/16423433.html
Author: sky-heaven
Title: ARM32 内核内存布局【转】

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/545612/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • HR-901FH卫星信号安全防护装置-授时安全防护装置

    HR-901FH卫星信号安全防护装置-授时安全防护装置 HR-901FH卫星信号安全防护装置-授时安全防护装置 京准电子科技官微——ahjzsz 产品简介 HR-901FH卫星时空…

    技术杂谈 2023年6月21日
    084
  • 软件测试基础理论(2)

    一, 为什么要进行软件测试 &#x4E3A;&#x4E86;&#x901A;&#x8FC7;&#x8F6F;&#x4EF6;&amp…

    技术杂谈 2023年7月25日
    061
  • CEF4Delphi 常用设置 CefSettings设置

    CEF4Delphi 基于Henri Gourvest 的 DCEF3。DCEF3的原始许可证仍适用于CEF4Delphi。阅读任何* .pas文件的第一行中的许可条款。 CEF4…

    技术杂谈 2023年5月30日
    0117
  • 5分钟搞定MySQL/PostgreSQL/Oracle到StarRocks数据迁移同步-CloudCanal实战

    简述 CloudCanal 2.1.0.x 版本开始支持 StarRocks 作为对端的数据迁移同步能力 本文通过 MySQL->StarRocks 的数据迁移同步案例简要…

    技术杂谈 2023年7月24日
    095
  • 无向图求所有路径C#版

    无向图求所有路径 using System; using System.Collections.Generic; using System.Linq; using System.T…

    技术杂谈 2023年5月31日
    0100
  • MySQL-sql_mode=only_full_group_by解决方式

    报错问题: SQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and …

    技术杂谈 2023年6月21日
    0108
  • pip3安装库时报超时问题小结

    在Linux测试服务器上使用pip3安装组件时,遇到下面错误: 查了一下相关资料弄清楚了这个错误出现的原因:一般出现这个错误跟本地网络状况或配置有关。一般而言,你可能默认使用了国外…

    技术杂谈 2023年5月31日
    089
  • Elasticsearch性能优化汇总——写入&搜索

    在Elasticsearch的默认设置下,是综合考虑数据可靠性、搜索实时性、写入速度等因素的。当离开默认设置、追求极致的写入速度时,很多是以牺牲可靠性和搜索实时性为代价的。有时候,…

    技术杂谈 2023年7月24日
    061
  • Docker存储卷

    Docker存储卷 1、COW机制 Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层。 如果运行中的容器修改了现有的一个已…

    技术杂谈 2023年6月21日
    079
  • 景深计算公式

    δ——容许弥散圆直径f——镜头焦距F——镜头的拍摄光圈值L——对焦距离ΔL1——前景深ΔL2——后景深ΔL——景深 从上图表公式(1)和(2)可以看出,后景深>前景深。 景深…

    技术杂谈 2023年5月31日
    0116
  • 域名ICP备案<阿里云>

    阅读指引 适用人:想要通过国内域名访问页面或者接口,需要进行ICP备案解决问题:备案过程中发生的问题阅读耗时:3分钟参考链接:阿里云ICP流程-视频、备案相关问题、注销备案相关问题…

    技术杂谈 2023年6月21日
    0100
  • HelloWorld

    新的起点,新的征程,未来可期! posted @2022-07-27 10:57 旅程~ 阅读(10 ) 评论() 编辑 Original: https://www.cnblogs…

    技术杂谈 2023年7月24日
    086
  • 小巧快速的ZooKeeper可视化管理+实时监控工具

    Zookeeper: 是一个分布式的、开源的程序协调服务,是 hadoop 项目下的一个子项目。他提供的主要功 能包括:配置管理、名字服务、分布式锁、集群管理。 平时用zkCli….

    技术杂谈 2023年7月23日
    0136
  • spring-boot-starter-actuator

    使用: HTTP方法 路径 描述 鉴权 GET /autoconfig 查看自动配置的使用情况 true GET /configprops 查看配置属性,包括默认配置 true G…

    技术杂谈 2023年7月25日
    080
  • ADC平台与低代码开发

    1.什么是ADC ADC(Application Development Center)是一个低代码、多体验的开发平台,提供面向业务开发者的全场景开发平台,以及完整的资产生命周期工…

    技术杂谈 2023年5月30日
    0103
  • 浅谈WebSocket

    WebSocket 为什么需要 WebSocket? 初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?…

    技术杂谈 2023年7月11日
    052
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球