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开始,只不过在物理内存映射到虚拟内存时采用了偏移量,二者大小比例的划分是可以更改的。
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开始,只不过在物理内存映射到虚拟内存时采用了偏移量,二者大小比例的划分是可以更改的。
相关文章推荐
- android底层驱动学习之调试驱动DEVICE_ATTR的原理及用法
- android底层驱动学习之I2C概述及工作原理(一)
- android底层驱动学习之如何通过debugfs创建文件的方式来调试内核信息
- android底层驱动学习之java基本语法的学习(二)
- 【2】android底层驱动开发学习及Ubuntu使用问题
- android底层驱动学习之DebugFS的用法,以及对file_operations的进一步理解
- android底层驱动学习之debug方法(proc、sysfs、debugfs)
- android底层驱动学习之log的输出
- android底层驱动学习之设备树驱动及设备匹配过程
- android底层驱动学习之日志信息、printk的个人理解
- android底层驱动学习之focaltech触屏实例理解
- android底层驱动学习之工作队列work_queue相关参数
- 【1】android底层驱动开发学习及Ubuntu使用问题
- android底层驱动学习之内核信息的输出以及控制方式
- android底层驱动学习之I2C(二)---以C语言理解IIC
- android底层驱动学习之从应用程序如何到底层driver的调用
- android底层驱动学习之linux输入子系统的理解
- 【4】android底层驱动开发学习
- android底层驱动学习之 module_init的内核调用顺序
- android底层驱动学习之java基本语法的学习(一)