基础知识
1.物理地址分配(Node、Zone、页(由虚拟地址映射(MMU)决定)),页为内存分配的最小单元,因为是mmu操作的最小单元
2.物理地址划分(ZONE_HIGHMEM、ZONE_NORMAL、ZONE_DMA)其中前一个为高地址区,后两个为低地址区
3.1G部分虚拟内核区的划分(线性映射区、Vmalloc区、特殊映射区)
4.获取当前系统页大小的命令:getconf PAGE_SIZE
1.页面分配器分配页内存
页面分配器struct 中有个gfp_mask,用它可以指定分配物理内存的哪个区(三个都可以分配),内核提供了利用页面分配器分配内存的接口,一般用于分配高端地址,得到page struct后再用kmap永久映射得到逻辑地址。
关于永久映射:
由于高端内存区不可能永久的映射在内核,所以要用kmap来永久分配一块,永久映射数量有限记得用完之后kumap
2.页分配太大,采用slab分配器分配小块内存,其实slab也可以用来分配多页内存
对应函数:
kmalloc、kzmalloc、其中参数flag完全继承了页面分配器的mask、(kmalloc与kzmalloc都是分配在物理的低地址区(线性映射区)),
kzmalloc与kmalloc唯一不同是flag多了__GFP_ZERO
slab作用:
-
用于分配小块内存(相对于页面分配器而言)其实也可以分配多页如kmalloc
-
用于高速缓存,如果在内核中要创建多个大的数据结构那么可以考虑用slab分配器
3.内核虚拟内存与物理高地址区映射
对应函数:
vmalloc,ioremap(vmalloc与kmalloc的不同在于v
malloc映射的物理地址可能是不连续的,因为vmalloc还要创建管理页表所以效率也比kmalloc低)
映射图像:
vmalloc与ioremap的区别与联系:
相同:都是修改在vmalloc区页表
不同:vmalloc是映射的物理内存可以是高端也可以是低端区,而iormap映射的是IO设备的内存不需要伙伴系统
注意一点:有的架构的体系不支持直接操作IO区映射过来的地址,必须用readb/writeb、readw/writew宏来读写(宏会展开与架构相应的代码)
4.per-CPU变量(在每个cpu都
对应一个变量,但是操作互不影响,这样就不需要任何锁了,但是任然需要关内核抢占)
使用:
静态分配:
动态分配:
其中get_cpu_var有关cpu抢占操作,put_cpu_var有开cpu抢占操作