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

    文章

    19242

    浏览量

    229593
  • 内核
    +关注

    关注

    3

    文章

    1372

    浏览量

    40272
  • Linux
    +关注

    关注

    87

    文章

    11279

    浏览量

    209264
  • AIoT
    +关注

    关注

    8

    文章

    1405

    浏览量

    30631

原文标题:接上一篇续集

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

收藏 人收藏

    评论

    相关推荐

    Linux下如何管理虚拟内存 使用虚拟内存时的常见问题

    在Linux系统中,虚拟内存管理是操作系统内核的一个重要功能,负责管理物理内存和磁盘上的交换空间。以下是对Linux下如何管理虚拟内存以及使用虚拟
    的头像 发表于 12-04 09:19 321次阅读

    逻辑内存和物理内存的区别

    逻辑内存和物理内存是计算机系统中两个重要的概念,它们在计算机的运行和数据处理中起着至关重要的作用。 1. 物理内存(Physical Memory) 物理内存,也称为RAM(Rando
    的头像 发表于 09-27 15:38 599次阅读

    内存管理的硬件结构

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

    操作系统的内存布局介绍

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

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

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

    台湾地区DRAM内存产能受地震影响停止报价

    报告显示,美光在台湾拥有丰富的产能布局,包含位于新北林口及台中的工厂,主要生产尖端的 1-beta 内存产品以及预定将陆续推出的 1-gamma 制程内存
    的头像 发表于 04-07 15:19 502次阅读

    微软发布Linux内核Rust模块优化补丁

    在此之前,Linux 内核中要想实现模块初始化,必须先创建一个实例,再将其移至特定内存空间。然而,经过新补丁调整后,各模块可直接在预设定好的内存地址上完成初始化工作。
    的头像 发表于 04-02 15:11 456次阅读

    linux内核常用调优参数

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

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

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

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

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

    LTM4620给fpga提供1.0V内核电源,4620输出电容量计算是否应该包含布局在fpga芯片附近的bulk电容?

    LTM4620给fpga提供1.0V内核电源,4620输出电容量计算是否应该包含布局在fpga芯片附近的bulk电容? 靠近FPGA布局的电容也比较大,比如470uF。但这些电容隔4620布局
    发表于 01-05 06:01

    Linux内核内存管理架构解析

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

    内存溢出与内存泄漏:定义、区别与解决方案

    内存溢出与内存泄漏:定义、区别与解决方案  内存溢出和内存泄漏是计算机科学中常见的问题,在开发和调试过程中经常会遇到。本文将详细介绍内存溢出
    的头像 发表于 12-19 14:10 2694次阅读