下面我们聊聊接口,接口就像一个沟通的交互点。接口在内核层/驱动层与应用层扮演的角色,就像寄存器在硬件与软件扮演的角色类似。大的来讲,就像通信中的协议规范。工作中,内核/驱动的工程师与应用开发工程师对接时,也是通过接口进行沟通的。
内存这块的接口在开发过程中,还是很重要的;就像应用层开发,对于字符串族处理的相关函数接口一样,重要且常用。
这里简单总结如下接口及应用场景:
内核层:kmalloc与kfree、vmalloc与vfree、kzalloc、kcalloc、alloc_pages、devm_kzalloc
kmalloc是内核中内存分配的常用方案,适用场景:连续物理页
常用参数:GFP_KERNEL和GFP_ATOMIC。
GFP_ATOMIC:进行不睡眠的高优先级的分配,适用于中断处理程序以及其他不能睡眠的代码段;
GFP_KERNEL:对于可睡眠的代码段,比如没有自旋锁的进程上下文代码。
vmalloc:内存虚拟地址连续但不能保证物理地址连续。把物理内存映射到连续的逻辑地址空间上(有性能上的损失)。
alloc_page:分配高端内存,page大小进行分配。注意函数返回值是一个执行struct page结构的指针。
kzalloc:相比kmalloc添加了一个标志,对申请的内容清零。__GFP_ZERO
kcalloc: 为数组分配内存。
应用层:mallloc、calloc、realloc和mmap(函数库)
区别:适用场景、性能和功能上的差别
场景上:malloc+memset = calloc
性能上:calloc只有malloc一半的汇编指令
功能上:realloc能够调整malloc分配内存的大小,将内存增加到size大小
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *str;
/* 最初的内存分配 */
str = (char *) malloc(5*sizeof(int));
strcpy(str, "aaaaaaaaaaaaaaaaaaaabbbb");
printf("String = %s, Address = %u\n", str, str);
/* 重新分配内存 */
str = (char *) realloc(str,7*sizeof(int));
strcat(str, ".com");
printf("String = %s, Address = %u\n", str, str);
free(str);
return(0);
}
malloc的底层实现一部分是mmap。也就是malloc的实现在大于128k内存时,调用sys_mmap分配;小于128k是sys_brk。
mmap接口的实现原理和使用方法,后面会单独讲一下。