0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

内核内存布局

电子工程师 来源:嵌入式开发AIoT 作者:嵌入式开发AIoT 2022-08-08 17:14 次阅读

一、内核内存布局

64位Linux一般使用48位表示虚拟地址空间,43位表示物理地址,通过命令:cat /proc/cpuinfo

32401ca6-16c0-11ed-ba43-dac502259ad0.png
  • ARM64架构处理器采用48位物理寻址机制,最大可寻找256TB的物理地址空间。对于 目前应用完全足够,不需要扩展到64位的物理寻址。虚拟地址也同样最大支持48位寻址,所以 在处理器架构设计上,把虚拟地址空间划分为两个空间,每个空间最大支持256TB,linux内核 在大多数体系结构上都把两个地址划分为:用户空间和内核空间。

  • 用户空间:0x0000_0000_0000_0000至0x0000_ffff_ffff_ffff;

  • 内核空间:0xffff_0000_0000_0000至0xffff_ffff_ffff_ffff;

QEMU平台,可以打印ARM64架构linux内核内存分布情况

327151a4-16c0-11ed-ba43-dac502259ad0.png

二、堆管理

堆是进程中主要用于动态分配变量和数据的内存区域,堆的管理对应程序员不是直接可见的。因为它依赖标准库提供的各个辅助函数(其中最重要的是malloc)来分配任意长度的内存区。malloc和内核之间的经典接口是brk系统调用,负责扩展/收缩堆。

329df57e-16c0-11ed-ba43-dac502259ad0.png
  • 堆是一个连续的内存区域,在扩展时自下至上增长。其中mm_struct结构,包含堆在虚拟地 址空间中的起始和当前结束地址(start_brk和brk)。
  • brk系统调用用于指定堆在虚拟地址空间中新的结束地址(如果堆将要收缩,当然可以小于当前值)。brk系统调用通过do_brk增长动态分配区(内核源码分mm/mmap.c)

三、sys_brk流程

  1. 检查资源限制;

  2. 将brk值对齐到页;

  3. 是否想增加brk值?(这个地方要结合源码看)

    是-->do_brk();返回新的brk的值;

    否-->do_munmap();返回新的brk的值;

brk机制不是一个独立的内核概念,而是基于匿名映射实现,以减少内部的开销。在检查过用brk的值的新地址未超出推的限制之后,sys_brk第一个重要操作是请求的地址按页长对齐。brk()用于进程向内核申请空间,用于扩展用户堆栈空间,或者回收堆栈空间。

  • malloc为小空间申请,brk()为大块空间申请。do_brk()用于增长动态分配区。do_munmap()释放动态分配区;
  • do_brk()源码分析:
staticunsignedlongdo_brk(unsignedlongaddr,unsignedlonglen)
{
structmm_struct*mm=current->mm;
structvm_area_struct*vma,*prev;
unsignedlongflags;
structrb_node**rb_link,*rb_parent;
pgoff_tpgoff=addr>>PAGE_SHIFT;
interror;

//首先对len这个长度进行页面对齐去判断页面对齐之后是否超出边界
len=PAGE_ALIGN(len);
if(!len)
returnaddr;

flags=VM_DATA_DEFAULT_FLAGS|VM_ACCOUNT|mm->def_flags;

//检查是否有足够内存空间来分析len大小的内存。判断虚拟地址空间是否足够
error=get_unmapped_area(NULL,addr,len,0,MAP_FIXED);
if(offset_in_page(error))
returnerror;

error=mlock_future_check(mm,mm->def_flags,len);
if(error)
returnerror;

/*
*mm->mmap_semisrequiredtoprotectagainstanotherthread
*changingthemappingsincasewesleep.
*/
verify_mm_writelocked(mm);

/*
*Clearoldmaps.thisalsodoessomeerrorcheckingforus
*/
//循环遍历用户进程红黑树中VMA,然后根据addr来查找合适的插入点
while(find_vma_links(mm,addr,addr+len,&prev,&rb_link,
&rb_parent)){
if(do_munmap(mm,addr,len))
return-ENOMEM;
}

/*Checkagainstaddressspacelimits*after*clearingoldmaps...*/
//检查是否要对此虚拟区间进行扩充
if(!may_expand_vm(mm,len>>PAGE_SHIFT))
return-ENOMEM;

if(mm->map_count>sysctl_max_map_count)
return-ENOMEM;
//判断系统是否有足够内存
if(security_vm_enough_memory_mm(mm,len>>PAGE_SHIFT))
return-ENOMEM;

/*Canwejustexpandanoldprivateanonymousmapping?*/
//判读是否可以合并,如果可以合并就合并成为一个vam区
vma=vma_merge(mm,prev,addr,addr+len,flags,
NULL,NULL,pgoff,NULL,NULL_VM_UFFD_CTX);

//如果能合并直接gotoout
if(vma)
gotoout;

/*
*createavmastructforananonymousmapping
*/

//如果没有办法合并,只有新创建一个VMA,VMA地址空间是【addr,addr+len】
vma=kmem_cache_zalloc(vm_area_cachep,GFP_KERNEL);
if(!vma){
vm_unacct_memory(len>>PAGE_SHIFT);
return-ENOMEM;
}

//指向匿名域指针
INIT_LIST_HEAD(&vma->anon_vma_chain);
vma->vm_mm=mm;//指向VMA所属于进程structmm_struct结构
vma->vm_start=addr;
vma->vm_end=addr+len;
vma->vm_pgoff=pgoff;
vma->vm_flags=flags;
vma->vm_page_prot=vm_get_page_prot(flags);
vma_link(mm,vma,prev,rb_link,rb_parent);
out://增加进程地址空间长度
perf_event_mmap(vma);
mm->total_vm+=len>>PAGE_SHIFT;
if(flags&VM_LOCKED)
mm->locked_vm+=(len>>PAGE_SHIFT);
vma->vm_flags|=VM_SOFTDIRTY;
returnaddr;
}

- END -


审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    19095

    浏览量

    228788
  • 内核
    +关注

    关注

    3

    文章

    1360

    浏览量

    40183
  • Linux
    +关注

    关注

    87

    文章

    11204

    浏览量

    208697
  • AIoT
    +关注

    关注

    8

    文章

    1378

    浏览量

    30513

原文标题:接上一篇续集

文章出处:【微信号:嵌入式开发AIoT,微信公众号:嵌入式开发AIoT】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    内存管理的硬件结构

    常见的内存分配函数有malloc,mmap等,但大家有没有想过,这些函数在内核中是怎么实现的?换句话说,Linux内核内存管理是怎么实现的?
    的头像 发表于 09-04 14:28 216次阅读
    <b class='flag-5'>内存</b>管理的硬件结构

    操作系统的内存布局介绍

    32位操作系统的内存布局很经典,很多书籍都是以32位系统为例子去讲解的。32位的系统可访问的地址空间为4GB,用户空间为1GB ~ 3GB,内核空间为3GB ~ 4GB。
    的头像 发表于 08-07 15:47 211次阅读
    操作系统的<b class='flag-5'>内存</b><b class='flag-5'>布局</b>介绍

    ESP-IDF内核中的内存管理如何验证?

    请教一下,ESP-IDF 内核中的内存管理如何验证
    发表于 06-19 06:30

    linux内核常用调优参数

     1. vm.swappiness:该参数控制系统在内存不足时,内核将页面交换到磁盘的程度。默认值为60,建议值为10-30。   2. vm.overcommit_memory:该参数控制系统是否允许超额分配内存。默认值
    的头像 发表于 04-01 10:31 1195次阅读

    什么是HBM3E内存?Rambus HBM3E/3内存控制器内核

    Rambus HBM3E/3 内存控制器内核针对高带宽和低延迟进行了优化,以紧凑的外形和高能效的封装为人工智能训练提供了最大的性能和灵活性。
    发表于 03-20 14:12 2174次阅读
    什么是HBM3E<b class='flag-5'>内存</b>?Rambus HBM3E/3<b class='flag-5'>内存</b>控制器<b class='flag-5'>内核</b>

    Linux内核内存管理之内核非连续物理内存分配

    的主要优点是避免了外部碎片,而缺点是需要修改内核页表。显然,非连续内存区域的大小必须是4096的倍数。Linux使用非连续物理内存区的场景有几种:(1)为swap区分配数据结构;(2)为模块分配空间
    的头像 发表于 02-23 09:44 836次阅读
    Linux<b class='flag-5'>内核</b><b class='flag-5'>内存</b>管理之<b class='flag-5'>内核</b>非连续物理<b class='flag-5'>内存</b>分配

    Linux内核内存管理之ZONE内存分配器

    内核中使用ZONE分配器满足内存分配请求。该分配器必须具有足够的空闲页帧,以便满足各种内存大小请求。
    的头像 发表于 02-21 09:29 840次阅读

    linux内核主要由哪几个部分组成,作用是什么

    Linux内核主要由以下几个部分组成: 进程管理:Linux内核负责管理和调度系统中的进程。它通过进程调度算法来决定哪个进程在什么时间运行以及如何分配系统资源。 内存管理:Linux内核
    的头像 发表于 01-22 14:34 2563次阅读

    Linux内核内存管理架构解析

    内存管理子系统可能是linux内核中最为复杂的一个子系统,其支持的功能需求众多,如页面映射、页面分配、页面回收、页面交换、冷热页面、紧急页面、页面碎片管理、页面缓存、页面统计等,而且对性能也有很高
    的头像 发表于 01-04 09:24 618次阅读
    Linux<b class='flag-5'>内核</b><b class='flag-5'>内存</b>管理架构解析

    获取Linux内核源码的方法

    (ELF1/ELF1S开发板及显示屏)Linux内核是操作系统中最核心的部分,它负责管理计算机硬件资源,并提供对应用程序和其他系统组件的访问接口,控制着计算机的内存、处理器、设备驱动程序和文件系统等
    的头像 发表于 12-13 09:49 605次阅读
    获取Linux<b class='flag-5'>内核</b>源码的方法

    Linux内核自解压过程分析

    uboot完成系统引导以后,执行环境变量bootm中的命令;即,将Linux内核调入内存中并调用do_bootm函数启动内核,跳转至kernel的起始位置。
    的头像 发表于 12-08 14:00 827次阅读
    Linux<b class='flag-5'>内核</b>自解压过程分析

    Linux内核slab性能优化的核心思想

    今天分享一篇内存性能优化的文章,文章用了大量精美的图深入浅出地分析了Linux内核slab性能优化的核心思想,slab是Linux内核小对象内存分配最重要的算法,文章分析了
    的头像 发表于 11-13 11:45 577次阅读
    Linux<b class='flag-5'>内核</b>slab性能优化的核心思想

    Linux内核内存规整总结

    1.前言 伙伴系统作为内核最基础的物理页内存分配器,具有高效、实现逻辑简介等优点,其原理页也尽可能降低内存外部碎片产生,但依然无法杜绝碎片问题。外部碎片带来的最大影响就是内存足够,但是
    的头像 发表于 11-11 11:17 1249次阅读
    Linux<b class='flag-5'>内核</b><b class='flag-5'>内存</b>规整总结

    linux内存性能优化介绍

    【1】内存映射 Linux 内核给每个进程都提供了一个独立且连续的虚拟地址空间,以便进程可以方便地访问虚拟内存;虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同字长的处理器,地
    的头像 发表于 11-10 15:23 654次阅读
    linux<b class='flag-5'>内存</b>性能优化介绍

    Linux 内存管理总结

    一、Linux内存管理概述 Linux内存管理是指对系统内存的分配、释放、映射、管理、交换、压缩等一系列操作的管理。在Linux中,内存被划分为多个区域,每个区域有不同的作用,包括
    的头像 发表于 11-10 14:58 484次阅读
    Linux <b class='flag-5'>内存</b>管理总结