linux内存概念理解

这篇具有很好参考价值的文章主要介绍了linux内存概念理解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

内核空间

内核空间的扩展功能

硬件层面

ARM64虚拟地址空间划分

进程的用户虚拟地址空间

内存布局

物理地址空间

内存映射


内核空间

1)内核空间的基本功能
 虚拟内存管理,负责从进程的虚拟地址空间分配虚拟页,
    sys_brk用来扩大或收缩堆,
    sys_mmap用来在内存映射区域分配虚拟页
    sys_munmap用来释放虚拟页;

2)内核延迟分配物理内存的策略:进程第一次访问虚拟内存的时候,触发页错误异常
页错误异常处理程序从页分配器申请物理页,在进程的页表中把虚拟页映射到物理页。

3)页分配器负责分配物理页,当前使用的页分配器是伙伴分配器

4)内核空间把页划分成小块内存,提供分配内存的接口kmalloc和释放内存的接口kfree
    支持slab slub slob

5)在内核初始化过程中,页分配器没有准备好,需要使用临时的引导内存分配器分配内存

内核空间的扩展功能


1)不连续页分配器提供了分配内存的接口vmalloc和释放内存的接口vfree.在内存碎片化的时候,申请连续物理页的成功率很低,可以申请不连续的物理页,映射到连续的虚拟页。即虚拟地址连续而物理地址不连续。

2)每处理器内存分配用来为每处理器变量分配内存

3)连续内存分配器(Coutiguous Memory allocator ,CMA)用来给驱动程序预留一段连续的内存,当驱动程序不用的时候,可以给进程使用;当驱动程序使用的时候,
把进程占用的内存通过页回收或迁移的方式让出来,给驱动程序使用。

4)内存控制组 用来控制今年初占用的内存资源

5)内存碎片化时,找不到连续的物理页,内存碎片整理通过迁移的方式得到连续的物理页。

6)内存不足的时候,页回收负责回收物理页,对于没有后备存储设备支持的匿名页,把数据换出到交换器,然后释放物理页;
    对于有后备存储支持的文件页,把数据写回存储设备,然后释放物理页。

7)如果页回收失败,内存耗尽杀手,选择进程杀掉。

硬件层面

MMU内存管理单元,负责把虚拟地址转化成物理地址
TLB页表缓存,保存最近使用的页表映射,避免每次把虚拟地址转换成物理地址都需要查询内存中的页表。
一级缓存 二级缓存,解决处理器与内存速度不匹配问题。
为了支持并行地取指令和取数据,一级缓存分为数据缓存和指令缓存。 

ARM64虚拟地址空间划分


1、虚拟地址的最大宽度是48位
2、内核虚拟地址[0XFFFF 0000 0000 0000 ,OXFFFF FFFF FFFF FFFF]
3、用户虚拟地址[0x0000 0000 0000 0000 ,0X0000 FFFF FFFF FFFF]
4、内核虚拟地址和用户虚拟地址的宽度相同
5、所有进程共享内核虚拟地址空间,每个进程有独立的用户虚拟地址空间
6、同一个线程组的用户线程共享用户用户虚拟地址空间,内核线程没有用户虚拟地址空间。

进程的用户虚拟地址空间


1,代码段数据段和未初始化数据段
2、动态库代码段,数据段和未初始化数据段
3、存放动态生成的数据 堆
4、存放局部变量和函数调用的栈
5、存放栈底部的环境变量和参数字符串
6、把文件区间映射到虚拟地址空间的内存映射区域。

为了使缓冲区溢出攻击更加困难,内核支持为内存映射区域、栈和堆随机的起始地址。进程是否使用虚拟地址空间随机化,由以下两个因素共同决定
1、进程描述符的成员personaliy是否设置ADDR_NO_RANDOMIZE
2、全局变量randomize_va_space:0表示关闭虚拟地址空间随机化;1表示使内存映射映射区域和栈的起始地址随机化;2表示内存映射区域、栈和堆起始地址随机化。

可以通过/proc/sys/kernel/randomize_va_space修改

内存布局

自顶向下增长,起始地址是STACK_TOP - 栈的最大长度 - 间隙。默认启用内存映射区域随机化,需要把起始地址减去一个随机值。

内核地址空间布局
1、线性映射区域的范围是[PAGE_OFFSET,2^64-1],起始位置是内核虚拟地址空间一半。

PAGE_OFFSET = 0xFFFFFFFFFFFFFFFF<<(VA_BIT-1) 

虚拟地址=((物理地址 - PHYS_OFFSET)+ PAGE_OFFSET),其中PHYS_OFFSET是内存的物理地址

2、vmemmap区域范围[VMEMMAP_START,PAGE_OFFSET),长度是VMEMMAP_SIZE=(线性映射区域长度/页长度 * page结构体的长度上限)
3、PCI/IO区域范围是[PIC_IO_START,PCI_IO_END) 长度是16M,结束地址是PCI_IO_END=(VMEMMAP_START-2MB)
4、固定映射区域的范围[FIXADDR_START,FIXADDR_TOP),长度是FIXADDR_SIZE,结束地址是FIXADDR_TOP = (PCI_IO_START-2MB)
5、vmalloc区域范围是[VMALLOC_START,VMALLOC_END),内核镜像在此区域
6、内核模块区域范围[MODULES_VADDR,MODULES_END],长度128M
7、KASAN (动态的内存错误检查工具)影子区域的起始地址是内核虚拟地址空间的起始地址,长度是内核虚拟地址的1/8

物理地址空间


物理地址是处理器在系统总线上看到,使用精简指令集的处理器通常只实现一个物理地址空间


外围设备和物理内存使用统一的物理地址空间,有些处理器架构把分配给外围设备的物理地址区域称为设备内存。


处理器通过外围控制器的寄存器访问外围设备,分为控制寄存器、状态寄存器和数据寄存器三大类。
处理器对外围设备寄存器的编制方式有两种:
1、I/O映射方式
2、内存映射方式


程序只能通过虚拟地址访问外设寄存器, 
ioremap 把外设寄存器的物理地址映射到内核虚拟地址空间
io_remap_pfn_range()把外设寄存器的物理地址映射到进程的用户虚拟地址空间

ARM64结构定义了两种内存类型
正常内存:物理内存和只读寄存器(ROM)
    共享属性
        不可共享:只能被处理器的一个核使用
        内部共享:一个处理器的所有共享或者多个处理器共享
        外部共享:处理器和其他观察者(如DMA)共享
    缓存属性:用来定义访问时是否通过缓存处理器
设备内存:分配给外围设备寄存器的物理地址区域
    共享属性总是外部共享
    缓存属性总是不可缓存

内存映射


在进程的虚拟地址空间中创建一个映射
1)文件映射,把文件的一个区间映射到进程的虚拟地址空间,数据源是存储设备上的文件;通常把文件映射的物理页称为文件页。
2)匿名映射,没有文件支持,把物理内存映射到进程的虚拟地址空间,没有数据源。把匿名映射的物理页称为匿名页。

根据修改是否对其他进程可见和是否传递到底层文件,内存映射分为共享映射和私有映射
共享映射:修改数据时,映射相同区域的其他进程可以看见,如果是文件支持的映射,修改会传递到底层文件。
私有映射:第一次修改数据时会从数据源复制一个副本,然后修改副本,其他进程看不见,不影响数据源。

两个进程可以使用共享的文件映射实现共享内存,匿名映射通常是私有映射,共享的匿名映射只可能出现在父进程和子进程之间。
在进程的虚拟地址空间中,代码段数据段是私有的文件映射,未初始化数据段、堆和栈是私有的匿名映射。

学习链接:

kernel学习链接

 参考

https://course.0voice.com/v1/course/intro?courseId=2&agentId=0文章来源地址https://www.toymoban.com/news/detail-708375.html

到了这里,关于linux内存概念理解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [linux kernel]slub内存管理分析(5) kfree

    省流 如果对代码细节不感兴趣,可以直接跳转底部内存释放逻辑总结。 前情回顾 关于slab几个结构体的关系和初始化和内存分配的逻辑请见: [linux kernel]slub内存管理分析(0) 导读 [linux kernel]slub内存管理分析(1) 结构体 [linux kernel]slub内存管理分析(2) 初始化 [linux kernel]slub内存管

    2023年04月09日
    浏览(62)
  • 深入理解Linux内核——内存管理(4)——伙伴系统(1)

    提要:本系列文章主要参考 MIT 6.828课程 以及两本书籍 《深入理解Linux内核》 《深入Linux内核架构》 对Linux内核内容进行总结。 内存管理的实现覆盖了多个领域: 内存中的物理内存页的管理 分配大块内存的伙伴系统 分配较小内存的slab、slub、slob分配器 分配非连续内存块的

    2024年02月10日
    浏览(53)
  • [linux kernel]slub内存管理分析(4) 细节操作以及安全加固

    前情回顾 关于slab几个结构体的关系和初始化和内存分配的逻辑请见: [linux kernel]slub内存管理分析(0) 导读 [linux kernel]slub内存管理分析(1) 结构体 [linux kernel]slub内存管理分析(2) 初始化 [linux kernel]slub内存管理分析(2.5) slab重用 [linux kernel]slub内存管理分析(3) kmalloc 描述方法约定

    2023年04月09日
    浏览(56)
  • linux内存概念理解

    目录 内核空间 内核空间的扩展功能 硬件层面 ARM64虚拟地址空间划分 进程的用户虚拟地址空间 内存布局 物理地址空间 内存映射 1)内核空间的基本功能  虚拟内存管理,负责从进程的虚拟地址空间分配虚拟页,     sys_brk用来扩大或收缩堆,     sys_mmap用来在内存映射区域

    2024年02月09日
    浏览(31)
  • 【Linux 内核源码分析】物理内存组织结构

    多处理器系统两种体系结构: 非一致内存访问(Non-Uniform Memory Access,NUMA):这种体系结构下,内存被划分成多个内存节点,每个节点由不同的处理器访问。访问一个内存节点所需的时间取决于处理器和内存节点之间的距离,因此处理器与内存节点之间的距离会影响内存访问

    2024年02月22日
    浏览(57)
  • 【Linux 内核源码分析】内存管理——Slab 分配器

    在Linux内核中,伙伴分配器是一种内存管理方式,以页为单位进行内存的管理和分配。但是在内核中,经常会面临结构体内存分配问题,而这些结构体的大小通常是小于一页的。如果使用伙伴分配器来分配这些小内存,将造成很大的内存浪费。因此,为了解决这个问题,Sun公

    2024年02月22日
    浏览(61)
  • Linux内核源码分析 (6)RCU机制及内存优化屏障

    问题: RCU 英文全称为 Read-Copy-Update ,顾名思义就是 读-拷贝-更新 ,是 Linux 内核中重要的同步机制。 Linux 内核已有原子操作、读写信号量等锁机制,为什么要单独设计一个比较复杂的新机制? RCU的原理 RCU记录所有指向共享数据的指针的使用者,当要修改该共享数据时,首先

    2024年02月10日
    浏览(58)
  • 深入分析linux内核的内存分配函数devm_kzalloc

    在分析驱动代码的时候,经常会遇到使用devm_kzalloc()为一个设备分配一片内存的情况。devm_kzalloc()是内核用来分配内存的函数,同样可以分配内存的内核函数还有devm_kmalloc, kzalloc, kmalloc。它们之间的区别在于devm_XXX分配的内存可以跟设备进行绑定,当设备跟驱动分离时,跟设备

    2024年02月02日
    浏览(43)
  • 【Linux Kernel】Linux内核裁剪

    目录 1. 内核简介 1.1 内核版本及特点 1.2 获取内核源码 1.3 内核启动过程简述 1.3.1 内核引导阶段 1.3.2 内核初始化阶段 2. 内核源码结构及Makefile分析 2.1 Linux内核Makefile分析 2.1.1决定编译那些文件 2.1.2 怎样编译这些文件 2.1.3 怎样链接这些文件 3. Kconfig分析 3.1 Kconfig文件的基本要

    2024年02月04日
    浏览(49)
  • ubuntu linux kernel内核操作

    1.内核编译前的准备工作 2.下载内核 4. 编译新内核 5. 内核安装 6. 安装模块 7. 生成initrd.img文件 8. 切换到/boot/grub/目录下,自动查找新内核,并添加至grub引导 9. 重启Ubantu,在previous version中选择启动新编译的内核 VMware虚拟机Ubantu20.04,Linux5.8.1内核源代码包 1.内核编译前的准备

    2024年02月19日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包