Linux内核设备驱动之内存管理笔记整理

2019-01-16 20:42:48王冬梅

虚拟内存必须解决的一个主要问题是内存碎片,因为通常内核使用连续的物理内存,所以碎片过多可能导致请求失败。

/********************** * 在内核中获取内存 **********************/

和在用户空间中一样,在内核中也可以动态分配和释放内存,但受到的限制要比用户空间多一些。

(1)内核中的内存管理

内核把物理页作为内存管理的基本单位。这主要是因为内存管理单元(MMU)是以页为单位进行虚拟地址和物理地址转换的,从虚拟内存的角度来看,页就是最小单位。大多数32位体系结构支持4KB的页。

a.页

内核用struct page表示系统中的每个物理页。

包括<linux/mm.h>就可以使用page,其实际定义在<linux/mm_types.h>

struct page{ page_flags_t flags; atomic_t _count; atomic_t _mapcount; unsigned long private; struct address_space *mapping; pgoff_t index; struct list_head lru; void *virtual; };

flags用于存放页的状态,定义在<linux/page-flags.h>,状态包括页是不是脏的,是不是被锁定在内存中等等。_count存放页的引用计数。

page结构与物理页相关,并非与虚拟页相关。结构的目的再于描述物理内存本身,而不是其中的数据。

内核根据page结构来管理系统中所有的页,内核通过page可以知道一个页是否空闲(也就是页有没有被分配)。

如果页已经被分配,内核还需要知道谁拥有这个页。

拥有者可能是用户空间进程,动态分配的内核数据,静态内核代码,或页高速缓存等。

系统中的每个物理页都要分配这样一个结构。如果结构体40字节大小,则128MB物理内存(4K的页)需要分配1MB多用于page结构。

b.区

由于硬件的限制,内核不能对所有的页一视同仁。内核使用区(zone)对具有相似特性的页进行分组。这些特性包括:

*一些硬件只能用某些特定的内存地址来执行DMA *一些体系结构其内存的物理寻址范围远大于虚拟寻址范围,这样,就有一些内存不能永久地映射到内核空间

针对这些限制,linux采用了三种区(<linux/mmzone.h>):

ZONE_DMA:这个区包含的页能执行DMA操作 ZONE_NORMAL:这个区包含的都是能正常映射的页 ZONE_HIGHMEM:这个区包含高端内存(大于896M),其中的页不能永久地映射到内核的地址空间

对于x86,这3个区对于的物理内存分别是:

ZONE_DMA: <16MB ZONE_NORMAL: 16~896MB ZONE_HIGHMEM: >896MB

见<linux/mmzone.h>中的struct zone。

系统中只有3个这样的区结构。

(2)页分配

内核是使用页进行内存管理的,因此,我们在内核中也可以要求系统以页为单位给我们分配内存。当然,以页为单位分配可能造成内存浪费,因此,只有在我们确定需要整页内存时才调用他们。