您的位置:首页 > 移动开发 > Android开发

android底层驱动学习之内存初步

2016-12-21 16:01 387 查看
android底层驱动学习之内存初步
 
1.       首先先认识下几个分配内存的接口函数:
l  rbuff = kmalloc(len + 4,
GFP_KERNEL)
GFP_KERNEL是flag,可以通过该flag来设定分配内存的方式,目前这个GFP_KERNEL就是可以睡眠的,优先级普通;如果是GFP_ATOMIC则优先级高,是原子的,不能睡眠. 通过kfree(rbuff)来释放
l  rbuff = vmalloc(len)
类似于kmalloc,只不过kmalloc分配的内存不管是虚拟地址还是物理地址都是连续的;而vmalloc分配的只是在虚拟地址是连续的,在物理地址上不一定是连续的,所以在需要一张表来建立虚拟地址和分散物理地址的关系,这样就会使效率降低很多,所以一般这个接口用于要分配大内存时。
l  data = devm_kzalloc(&dev,sizeof(struct fts_ts_data),
GFP_KERNEL)
这个接口是具有资源管理的kzalloc()。使用资源管理(resource-managed)函数分配的内存,是会与所属设备相关联。当设备从系统中分离或者设备驱动被卸载,该内存会被自动释放。也可以通过devm_kfree()来释放内存。Struct device dev;
 
2.       slab分配器
l  当频繁申请小内存,要频繁进出内存,那这样就会造成系统消耗较大,所以就设计了slab相当于高速缓存,slab分成三种状态:满的slab、部分满的slab、空的slab;当下一次需要分配内存时会先去看slab里面是否有满足条件的,如果没有就创建一个新的slab。当调用kmalloc时就会先去看slab是否有满足条件的(在kmalloc ->__kmalloc—>__do_kmalloc有这么一句__find_general_cachep(size,
flags)就是找是否有满足条件的?----是对的-12.20);
l  上面的最后讲的不知道对不对,另外,如果需要频繁创建很多相同类型的对象,那么就应该考虑使用高速缓存,步骤如下:
a.      内核函数 kmem_cache_create
用来创建一个新缓存。这通常是在内核初始化时执行的,或者在首次加载内核模块时执行。
b.      要从一个命名的缓存中分配一个对象,可以使用 kmem_cache_alloc 函数。调用者提供了从中分配对象的缓存以及一组标志:
voidkmem_cache_alloc( struct kmem_cache *cachep, gfp_t flags= GFP_KERNEL );
c.      最后不用了一定要记得释放掉- kmem_cache_free
通过a、b两步就可以创建一个具体对象structftp的高速缓存,如果后面要经常创建和释放struct fts分配的空间,用这个就不用频繁的申请释放内存,大大的提高效率
3.       用户空间和内核空间
l  首先这两个空间是通过权限来划分,这样可以更好的保护数据,应用程序处在用户空间,与硬件直接打交道的内核核心程序处在内核空间,这样就可以避免应用程序非法访问内核、硬件,必须按照内核的规定来。
l  二者总共4G,0-3G是用户空间,3-4G是内核空间,那为什么只有4G?为什么内核空间在高地址?这里的4G指的是虚拟内存?
答:
问题一:因为我们平时用的机器一般是32位的,32位地址线能索引的最大内存量是4G=2^10×2^10×2^10×2^2(2^10=1k);
           问题二:内核是为应用服务的, 将内核放到 较高的线性空间,是为了方便 应用 程序 从0开始使用线性地址空间。
           问题三:4G指的是虚拟内存,在实际的物理空间,内核空间还是从地址0开始,只不过在物理内存映射到虚拟内存时采用了偏移量,二者大小比例的划分是可以更改的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: