linux 内核学习之内存管理-未完待续

1 相关概念

MMU:MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址以及提供硬件机制的内存访问授权。

页:内存管理(物理页)的基本单位,MMU通常以页为单位进行处理,通常32位体系结构支持4KB的页,64位体系结构一般支持8KB的页。内核中以struct page 表示系统中的每个物理页。page结构体的virtual域是页的虚拟地址(就是页在虚拟内存中的地址)。

区:内核使用区对功能相似的页进行分组。linux主要使用了四种区:

ZONE_DMA:这个区包含的页用来执行DMA操作。

ZONE_DMA32:用来执行DMA操作,与上面不同之处在于,此区的页面只能被32位设备访问。

ZONE_NORMAL:这个区包含的都是能正常映射的页。

ZONE_HIGHEM:这个区包含“高端内存”,其中的页并不能永久地映射到内核地址空间。

用户空间:进程空间中0~3G部分,对应进程,当进程切换改变时,用户空间会随之发生变化。用户进程只能访问用户虚拟空间而无法访问内核空间。

内核空间:4G的用户空间中3G~4G的部分,内核负责映射,是固定的,不随进程切换而改变。

TLB(translation lookaside buffer):一种硬缓冲区,用来缓存虚拟地址到物理地址的映射关系,大大提供了系统的性能。

2.内存分配接口

以页为单位的内存分配接口:alloc_pages 和page_address,其中获得填充为0的页是:get_zeroed_page

以字节为单位的内存分配接口:

malloc:用户空间申请动态内存,使用free释放内存。malloc 分配的内存在虚拟地址空间是连续的,但是其在物理地址(即在物理RAM中)并不一定是连续的。linux内核,C库的malloc函数通过brk()和mmap()两个系统调用来实现。

kmalloc :与用户空间的malloc类似,用于获得以字节为单位的一块内核内存,所分配的区域不仅虚拟地址是连续的,物理地址上是连续的。性能较后面介绍的vmalloc 高。

kmalloc函数使用较多,返回的是一个指向内存块的指针,其内存块至少要有size大小。kfree函数释放由kmalloc分配出来的内存块。kmalloc 分配的区域位于物理内存映射区(3G~3G+64M的区域)。出错时,返回的是null(除非没有足够的内存可用,否则内核总能分配成功)。在调用kmalloc调用之后,必须检查返回的是不是null,如下:

struct dog *p;

p = kmalloc(sizeof(stuct dog),GFP_KERNEL);//第二个参数GFP_FERNEL是分配器的标志,下文中有介绍

if(!p)

/*处理错误*/

vmalloc:与kmalloc不同的是,vmalloc所分配的区域在物理不是连续的,需要建立页表项以把物理上不连续的页转换为虚拟地址空间上连续的页,因此与kmalloc相比,效率较低。同vfree对应。vmalloc 分配的区域(位于内核空间:3G+64M+8M(大概)~接近4G)与kmalloc 分配的区域不在同一个区域。

3. 虚拟地址到物理地址的转换

应用程序操作的对象是映射到物理内存之上的虚拟内存,但是处理器直接操作的却是物理内存。所以当用程序访问一个虚拟地址时,首先必须将虚拟地址转化成物理地址,然后处理器才能解析地址访问请求。地址的转换工作需要通过查询页表才能完成,概括的讲,地址转换需要将虚拟地址分段,使每段虚地址都作为一个索引指向页表,而页表项则指向下一级别的页表或者指向最终的物理页面。每个进程都有自己的页表。进程描述符号的pgd域指向的就是进程的页全局目录。注意,虚拟地址映射到页之前必须先分配物理页---即必须先从内核获取空闲页,并建立页表。因此需要了解内核管理物理内存(页管理)的机制。

4 进程地址空间的管理

5 分配器标志

   分为三类:行为修饰符、区修饰符及类型标志。作为kmalloc函数的一个参数使用。

行为修饰符:表示内核应当如何分配所需的内存,例如分配内存的过程中不能睡眠。

区修饰符:表示内存区应该从何处分配,内核优先从ZONE_NORMAL开始。通常不需要指定。

类型标志:指定所需的行为和区描述符以完成特殊类型的处理(内核使用类型标志的做法既简单又不容易出错误,而不是直接使用用到的多个描述符)。通常使用的是GFP_KERNEL或者GFP_ATOMIC。

例如最常用的标志GFP_KERNEL,实际上是_GFP_WAIT|_GFP_IO|_GFP_FS)的组合,调用可能祖塞,表示能睡眠的内存分配(表示内核运行调用者睡眠)。

GFP_ATOMIC:表示不能睡眠的内存分配(内核不能让调用这休眠),因此它分配成功的机会较小(与GFP_GERNEL)相比。但是,在当前代码(例如中断处理程序、软中断和tasklet)不能睡眠时,只能选择GFP_ATOMIC.


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值