Linux内核的内存管理

本文探讨了内核中的内存分配策略,包括物理页的结构、页表的作用,以及如何通过structpage管理页面状态。讨论了内存区划分、DMA限制和Linux内核的内存分配函数如alloc_pages和kmalloc/vmalloc的区别。
摘要由CSDN通过智能技术生成

内核中的分配内存和进程中的很不同,内核不能睡眠。

页的物理结构:物理结构页,被虚拟页映射数据

MMU以页为单位来管理系统中的页表。
系统中的每一个物理页都需要分配一个这样的结构体,一个4GB的内存,每个页创建一个这个结构也仅仅需要20MB。
这个结构体用来记录物理页的状态。

使用示例:
考虑以下情况:
有一个物理页 A。
虚拟地址 V1 和 V2 映射到物理页 A。
此时,如果对 V1 所映射的虚拟页进行写操作,这将导致物理页 A 中的数据发生变化。由于虚拟地址 V2 也映射到相同的物理页 A,对 V1 的写操作也会反映在 V2 上,因为它们实际上指向同一块物理内存。
这种共享物理页的机制允许不同的虚拟地址空间之间共享相同的数据,提高了内存的利用效率。然而,这也意味着当一个虚拟页发生写操作时,共享同一物理页的其他虚拟页中的数据也会发生变化。
通过 struct page,内核可以追踪物理页的状态、引用计数以及其他信息,以便在多个虚拟页之间共享物理页时进行适当的管理和同步。

struct page{
	unsigned long  flags;//页的状态:是不是脏的,是不是被锁定在内存中
	atomic_t    		_count;//用于跟踪对此页面的引用计数
	atomic_t			_mapcount;//用于跟踪映射到此页面的用户数
	unsigned	long		private;
	struct  address_space 	*mapping;//指向虚拟地址空间
	pgoff_t		index;
	struct	list_head	lru;//用于在LRU(最近最少使用)列表中管理页面。
	void 	*virtual;//页的虚拟地址
}

内核用这个结构来描述物理内存本身的状态,而不是其中的数据,因为物理页中存放的数据会因为其被映射的虚拟页的改变而改变。
内核使用这一结构来管理系统中的所有页,因为内核需要知道一个页是否空闲(也就是页没有被分配)。如果页被分配,需要知道谁拥有这个页:用户空间进程,动态分配的内核数据,静态内核代码或页高速缓存等。

内核根据页的物理状况不同(有些页存在限制,不能永久映射啥的)把页分为不同的区。
Linux必须处理如下两种由于硬件存在缺陷而引起的内存寻址问题:

  1. 一些硬件的某些内存地址不能执行DMA(直接访问内存)
  2. 一些体系结构的内存的物理寻址范围比虚拟寻址范围大的多,这样,就有一些内存不能永久映射到内核空间上。

x86-32上的区

描述物理内存
ZONE_DMADMA使用的页<16MB
ZONE_NORMAL正常可寻址的页16-896MB
ZONE_HIGHMEM动态映射的页>896MB

x86-64上的区没有ZONE_HIGHMEM,所有的物理内存都处于ZONE_DMA和ZONE_NORMAL中。

Linux把系统的页划分为区,形成不同的内存池,这样就可以根据用途进行分配了。

获得页:我们就是通过获得页在内核中分配和释放内存的

内核提供了请求内存的底层机制的几个函数,都是以页为单位分配内存的。

核心函数

struct page * alloc_pages(gfp_t gfp_mask,unsigned int order);
该函数分配2的oreder次方个连续的物理地址,并且返回指向第一个页的page结构体。
void * page_address(struct page * page);
该函将物理页转换为其逻辑地址。

在内核中,这样的映射关系通常是通过 mapping 字段(在 struct page 中)表示的,该字段指向与页面关联的地址空间结构。

unsigned long _get_free_pages(gfp_t gfp_mask,unsigned int order);
该函数返回物理页的逻辑地址。
当你需要以页为单位的一族连续物理页时,尤其是只需要一两页时,这些低级页函数十分有用。

kmalloc():内核中以字节为单位的分配内存

void* kmalloc(size_t size,gfp_t flags);
这个函数返回一个指向内存块的指针,其内存块至少要有size大小,所分配的内存在物理上是连续的(虚拟地址也自然连续的)。

vmalloc()

分配的地址空间的物理地址不是连续的(和进程中的分配malloc相似,malloc在物理内存上也不是连续的)。
使用vamlloc()把物理上不连续的也转换为虚拟地址,需要专门建立页表,并且使用时,必须通过页表一一映射。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值