Linux 内核开发之内存管理

本文详细介绍了Linux内核的内存管理,包括地址类型(如用户虚拟地址、物理地址、内核逻辑地址、内核虚拟地址)、内存管理单元MMU、区的划分、页的获取与释放、gfp_mask的使用、kmalloc和vmalloc的异同、slab缓存机制以及高端内存的映射等核心概念和操作。通过对这些内容的探讨,读者可以深入理解Linux内核如何高效管理内存。
摘要由CSDN通过智能技术生成

一. 地址类型

    1. 用户虚拟地址(Virtual Memory Address)

    用户空间程序所能看到的常规地址,32位或者64位。每个进程都有自己的虚拟地址空间,空间分为若干区域/段,/proc/pid/maps 可查看,通过 VMA 管理。

    进程的内存映射至少包含如下区域:

    a. text 段,即程序的可执行代码段;

    b. data 段,包含初始化数据、非初始化数据和堆栈

    c. 与每个活动的内存映射对应的区域,即 mmap 的区域

    2. 物理地址

    在处理器和系统内存之间使用,也是 32 位或者 64 位的,以页为单位进行管理。

    3. 内核逻辑地址

    内核逻辑地址组成了内核的常规地址空间,内核使用逻辑地址来引用物理内存中的页。该地址映射了部分或者全部的内存,并经常被视为物理地址。在大多数体系结构上,逻辑地址和与其关联的物理地址的区别,仅仅是它们之间存在一个固定的偏移量。逻辑地址使用硬件内建的指针大小,因此在安装了大量内存的 32 位系统中,它无法寻址全部的物理内存。逻辑地址通常保存在 unsigned long 或者 void * 这样类型的变量中。kmalloc 返回的内存就是内核逻辑地址。

    我的理解,就像用户空间无法直接访问物理内存,内核也一样,需经过一层映射,换成官方说法:内核无法直接操作没有映射到内核地址空间的内存。不同的是,用户空间的映射是非线性的,而内核空间的逻辑地址则是线性的。所以,kmalloc 返回的不是直接的物理地址,而是内核逻辑地址。

    内核逻辑地址与物理地址的相互转换:

    __pa():返回某个逻辑地址对应的物理地址    physics address

    __va():将物理地址逆向映射到逻辑地址,但只对低端内存有效    virtual address,其实应该是 logic address

        #define __pa(x) ((unsigned long)(x) & 0x7fffffff)

        #define __va(x) ((void *)((unsigned long)(x) | 0x80000000))

    从这个定义来看,内核逻辑地址在物理地址的基础上增加了一个偏移,所以,内核逻辑地址的低位变成了保留位,难道是给 DMA 使用的?

    4. 内核虚拟地址

    与前者的相同之处在于,都将内核空间的地址映射到物理地址上。区别是,内核虚拟地址与物理地址的映射不必是线性的和一对一的,而是类似于用户虚拟地址的映射方式。所有的逻辑地址都是内核虚拟地址,但是许多内核虚拟地址不是逻辑地址。例如 vmalloc 分配的内存都是虚拟地址,kmap 也返回一个虚拟地址。虚拟地址通常保存在指针变量中。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值