欢迎光临散文网 会员登陆 & 注册

一文带你解析Linux内核内存布局!(学习起来吧~)

2022-05-31 17:38 作者:补给站Linux内核  | 我要投稿

内核内存布局

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


cat /proc/meminfo


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

用户空间:0x0000_0000_0000_0000至0x0000_ffff_ffff_ffff。 内核空间:0xffff_0000_0000_0000至0xffff_ffff_ffff_ffff。


【文章福利】小编推荐自己的Linux内核技术交流群:【891587639】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!前100名进群领取,额外赠送一份价值699的内核资料包(含视频教程、电子书、实战项目及代码)  

内存布局

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


堆管理

  • 堆是进程中主要用于动态分配变量和数据 的内存区域,堆的管理对应程序员不是直接可见的。因为它依赖标准库提供的各个辅助函数(其 中最重要的是malloc)来分配任意长度的内存区。 malloc和内核之间的经典接口是brk系统调用,负责扩展/收缩堆。 堆是一个连续的内存区域,在扩展时自下至上增长。其中mm_struct结构,包含堆在虚拟地 址空间中的起始和当前结束地址(start_brk和brk)。

sys_brk流程


  • brk机制基于匿名映射实现,以减少内部的开销。在检查过用于brk的值的新地址未超出堆的限制之后,sys_brk第一个重要的操作是将请求的地址按页长对齐。

  • brk()用于用户进程想内核申请空间,用于扩展用户堆栈空间,或者回收用户堆栈空间。

  • malloc()为小空间申请,brk()为大空间申请。do_brk()用于增长动态分配区。do_munmap()释放动态分配区。

do_brk()源码分析

  • 大内核锁BKL

  • 递归锁:嵌套上锁解锁。

  • 自动释放特性。

  • 本质上自旋锁,不同在于自旋锁不可以递归获取锁(会导致死锁),大内核锁可以递归获取锁,保护整个内核。保持锁的时间太长,严重影响系统性能和可伸缩性,因而被淘汰。

  • 【注意】

  • 原子操作对整数操作,自旋锁和信号量应用比较广泛。当临界区小应该选择自旋锁,反之应该信号量。

  • per-CPU计数器

  • 引入目的是加速SMP系统上计数器操作。

  • 基本原理:

  • 计数器的准确值存储在内存中的某一个地址,准确值所在内存位置之后是一个数组,每个数组想对应于系统中的一个CPU。

  • Linux系统尤其是针对SMP或者NUMA架构的多CPU系统的时候,主要描述每个CPU私有数据时,系统提供该机制per-cpu。

  • 三种CPU模式:x86 x64 ia64

  • X86表示基于X86指令安装模式;

  • x64表示64位系统程序;

  • ia64主要用于企业级服务器,inter安腾架构基于a64处理器架构的服务器,64位运算能力、寻址空间,数据处理能力方面突破性提高。

  • 总结

  • 本文介绍了内核的内存布局,分布情况,堆管理,malloc与brk区别,大内核锁,per-CPU计数器等。




一文带你解析Linux内核内存布局!(学习起来吧~)的评论 (共 条)

分享到微博请遵守国家法律