Linux内存管理:虚拟地址空间布局

您所在的位置:网站首页 linux查物理地址 Linux内存管理:虚拟地址空间布局

Linux内存管理:虚拟地址空间布局

2023-03-15 17:53| 来源: 网络整理| 查看: 265

【推荐阅读】

Linux文件系统详解

linux进程管理---实时调度

linux内核内存管理-缺页异常

linux内核内存管理-brk系统调用

虚拟内存地址空间

  Linux内核属于微内核的范畴,内核控制计算机的硬件资源,运行在特权模式;用户态应用程序运行在普通用户模式,无法直接访问硬件资源,必须依托于内核提供的资源,如CPU资源、Memory资源、I/O资源等。

  Linux采用沙箱机制,每一个进程运行在独立的虚拟地址空间,最大限度避免单个进程异常导致整个系统崩溃。

  每一个进程的虚拟地址空间分为内核虚拟地址空间和用户虚拟地址空间两部分,内核虚拟地址空间为内核态代码和内核堆栈,所有进程的内核虚拟地址空间是复用的;用户虚拟地址空间则是各进程的代码段、数据段、BSS段、mmap段(动态加载库以及各库运行数据段、运行栈等)、堆、栈、环境变量等信息。

  Linux中可以通过cat /proc//maps命令查看指定进程的用户虚拟地址空间的映射,也可以通过pmap -x 查看,该命令实质上是基于/proc//maps实现的。

ARM32

用户虚拟地址空间范围:0x0000 0000 ~ 0xbfff ffff

内核虚拟地址空间范围:0xc000 0000 ~ 0xffff ffff

ARM64

ARMv7架构(32位CPU)早期CPU采用32位物理地址空间,支持最大物理内存为4GB。但是随着内存容量和软件的扩张,4GB物理内存寻址范围已经不够用了,所以引入了LPAE(Large Physical Address Extension)机制,用户可以通过CPU寄存器扩展物理地址宽度。

ARMv8架构(64位CPU)开始,ARM公司从长远地角度考虑,优化了LPAE机制,可以支持32~48位物理地址寻址,满足了物理内存寻址的要求。同时做了兼容32位应用程序的考虑。

ARMv8在硬件体系结构上支持4级的4KB页大小的页表转换,也支持3级的64KB页大小的页表转换。

在Linux ARM64中,如果页大小为4KB,使用3级或者4级页表转换,用户虚拟地址空间和内核虚拟地址空间都支持39位(512GB)或者48位(256TB)寻址范围。

如果页大小为64KB,就只有2级页表转换,用户虚拟地址空间和内核虚拟地址空间支持42位(4TB)寻址范围。

上面这张表格,整理了ARMv7和ARMv8的物理地址位宽、用户虚拟地址空间范围和内核虚拟地址空间范围。

ARMv8架构开始,Linux内核新增了几个内核配置选项用来设定虚拟地址位宽和页表层级以及页大小:

  1)CONFIG_ARM64_64K_PAGES 可以使能64KB大页,如果没有使能,则延用4KB页;

  2)CONFIG_COMPAT 设置是否兼容32位应用程序;

#ifdef CONFIG_COMPAT #define TASK_SIZE_32 UL(0x100000000) #define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \ TASK_SIZE_32 : TASK_SIZE_64) #else #define TASK_SIZE TASK_SIZE_64 #endif /* CONFIG_COMPAT */

3)CONFIG_ARM64_VA_BITS 设置虚拟地址位宽,常用的虚拟地址位宽为39位或者48位;(实际生效的是内核VA_BITS宏)

ARM64内核虚拟地址空间布局可以通过arch/arm64/include/asm/memory.h文件查看,也可以查看也可以看看 arch/arm64/mm/init.c 和 arch/arm64/include/asm/pgtable.h。

pr_notice("Virtual kernel memory layout:\n" " vmalloc : 0x%16lx - 0x%16lx (%6ld MB)\n" #ifdef CONFIG_SPARSEMEM_VMEMMAP " vmemmap : 0x%16lx - 0x%16lx (%6ld MB)\n" #endif " modules : 0x%16lx - 0x%16lx (%6ld MB)\n" " memory : 0x%16lx - 0x%16lx (%6ld MB)\n" " .init : 0x%p" " - 0x%p" " (%6ld kB)\n" " .text : 0x%p" " - 0x%p" " (%6ld kB)\n" " .data : 0x%p" " - 0x%p" " (%6ld kB)\n", MLM(VMALLOC_START, VMALLOC_END), #ifdef CONFIG_SPARSEMEM_VMEMMAP MLM((unsigned long)virt_to_page(PAGE_OFFSET), (unsigned long)virt_to_page(high_memory)), #endif MLM(MODULES_VADDR, MODULES_END), MLM(PAGE_OFFSET, (unsigned long)high_memory), MLK_ROUNDUP(__init_begin, __init_end), MLK_ROUNDUP(_text, _etext), MLK_ROUNDUP(_sdata, _edata));【文章福利】小编推荐自己的Linux内核技术交流群:【977878001】整理一些个人觉得比较好得学习书籍、视频资料!进群私聊管理领取内核资料包(含视频教程、电子书、实战项目及代码)

内核资料直通车:Linux内核源码技术学习路线+视频教程代码资料

学习直通车:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈

实例如下:

ARM64用户虚拟地址空间布局和ARM32类似,但是地址范围略有差异。

ARM64兼容ARM 32位应用程序,所以ARM 32位应用程序可以无需修改运行在ARMv8上。为了运行ARM 32位应用程序,Linux内核仍然从init进程创建一个64位的进程(clone系统调用)、但是将其用户虚拟地址空间限制到4GB。通过这种方式,64位的Linux内核可以同时运行32位和64位应用程序。

需要注意到,ARM64上32位应用程序仍然拥有512GB的内核地址空间,并且不与内核共享自己的4GB用户虚拟地址空间;但是ARM32上,32位应用程序只有3GB用户虚拟地址空间。

原文作者:首页 - 内核技术中文网 - 构建全国最权威的内核技术交流分享论坛

原文地址:(版权归原文作者所有,侵权留言联系删除)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3