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

    文章

    20149

    浏览量

    247197
  • 内核
    +关注

    关注

    4

    文章

    1436

    浏览量

    42492
  • Linux
    +关注

    关注

    88

    文章

    11628

    浏览量

    217984
  • AIoT
    +关注

    关注

    8

    文章

    1596

    浏览量

    33811

原文标题:接上一篇续集

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux内核模块的加载机制

    \"GPL\") bool sig_ok;// 签名验证结果 };然后进行内存分配 1、使用vmalloc()在内核空间分配内存,映射模块的代码和数据段。 2、标记可执行页(需
    发表于 11-25 06:59

    开源鸿蒙技术大会2025丨OS内核与视窗分论坛:筑基开源鸿蒙核心内核,共拓视窗技术边界

    开源鸿蒙技术大会2025 OS内核与视窗分论坛在湖南长沙国际会议中心圆满举行。来自西北工业大学、浙江大学、厦门大学、华为等高校和企业的学者专家齐聚一堂,围绕鸿蒙内核通信机制、智能渲染、内存缓存优化、端云协同备份及空间视窗架构等前
    的头像 发表于 11-20 17:29 471次阅读
    开源鸿蒙技术大会2025丨OS<b class='flag-5'>内核</b>与视窗分论坛:筑基开源鸿蒙核心<b class='flag-5'>内核</b>,共拓视窗技术边界

    通过sysmem接口扩展内存空间

    和0x90000000起始的64k空间范围内时,内核会访问ITCM和DTCM;如果不在上述空间范围内,内核会通过sysmem接口访问外部存储器。这里通过sysmem接口扩展内存空间是简单方便的方法。
    发表于 10-24 08:12

    蜂鸟E203内核优化方法

    。 修改内核参数:对蜂鸟E203的内核参数进行相应修改,可以优化内核运行效率,提高系统性能,比如调整缓存大小、内存分配策略等。 资源管理:进行有针对的资源管理,例如调度算法的修改,调整
    发表于 10-21 07:55

    华邦电子重新定义AI内存:为新一代运算打造高带宽、低延迟解决方案

    本文将探讨内存技术的最新突破、AI 应用日益增长的影响力,以及华邦如何透过策略性布局响应市场不断变化的需求。
    的头像 发表于 08-28 11:17 4245次阅读
    华邦电子重新定义AI<b class='flag-5'>内存</b>:为新一代运算打造高带宽、低延迟解决方案

    强实时运动控制内核MotionRT750(一):驱动安装、内核配置与使用

    强实时运动控制内核MotionRT750的驱动安装与内核配置
    的头像 发表于 07-03 15:48 3455次阅读
    强实时运动控制<b class='flag-5'>内核</b>MotionRT750(一):驱动安装、<b class='flag-5'>内核</b>配置与使用

    网格布局介绍

    概述 网格布局是由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。网格布局具有较强的页面均分能力,子组件占比控制能力,是一种重要自适应布局,其使用场
    发表于 06-25 06:27

    HarmonyOS NEXT应用元服务布局合理使用布局组件

    选择合适的布局组件 在布局时,子组件会根据父组件的布局算法得到相应的排列规则,然后按照规则进行子组件位置的摆放。不同的布局容器使用的布局算法
    发表于 06-20 15:48

    基于 IAR Embedded Workbench 的自研 MCU 芯片软件函数与变量内存布局优化精控方法

    在嵌入式软件开发领域,MCU芯片软件的架构设计与内存布局的精细规划对系统性能和稳定性起着关键作用。本文档聚焦于IAR Embedded Workbench环境下,为自研MCU芯片软件提供了一套详尽
    的头像 发表于 04-30 16:38 589次阅读
    基于 IAR Embedded Workbench 的自研 MCU 芯片软件函数与变量<b class='flag-5'>内存</b><b class='flag-5'>布局</b>优化精控方法

    C语言中结构体与联合体的深度解析:内存布局与应用场景

    例: struct Student { char name[20];// 20字节 int age;// 4字节 float score; // 4字节 }; 内存布局:总大小为32字节(考虑
    发表于 04-08 09:18

    iMX8MPlus SoC M7核心是否需要单独的RAM内存

    对于 iMX8MPlus SoC ,M7 核心是否需要单独的 RAM 内存?或者是否有用于 M7内核的内部 SRAM?
    发表于 03-28 08:03

    hyper 内存,Hyper内存:如何监控与优化hyper-v虚拟机的内存使用

    在日常工作中,我们常常需要处理大量的文件和数据,这些重复性任务不仅耗时耗力,还容易因疲劳而导致错误。幸运的是,批量管理工具的出现为这一问题提供了高效的解决方案。今天就为大家介绍Hyper内存
    的头像 发表于 01-24 14:15 1681次阅读
    hyper <b class='flag-5'>内存</b>,Hyper<b class='flag-5'>内存</b>:如何监控与优化hyper-v虚拟机的<b class='flag-5'>内存</b>使用

    Linux服务器卡顿救星之一招释放Cache内存

    为了加速操作和减少磁盘I/O,内核通常会尽可能多地缓存内存,这部分内存就是Cache Memory(缓存内存)。根据设计,包含缓存数据的页面可以按需重新用于其他用途(例如,应用程序)。
    的头像 发表于 01-16 10:04 2162次阅读

    美光新加坡HBM内存封装工厂破土动工

    光在亚洲地区的进一步布局和扩张。 据美光方面介绍,该工厂将采用最先进的封装技术,致力于提升HBM内存的产能和质量。随着AI芯片行业的迅猛发展,HBM内存的需求也在不断增长。为了满足这一市场需求,美光决定在新加坡建设这座先进的封装
    的头像 发表于 01-09 16:02 1089次阅读

    飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核启动流程

    关于内核启动流程涉及内容较多而且复杂,过度的分析意义不大,因此,这里不做详细讲解,只做一个大概的介绍。初学者只做了解,有一定基础的可以深入理解。 内核镜像被uboot加载到内存空间之后,获得控制权
    发表于 01-06 09:51