/***********************************************************************************
*
* alloc_pages,kmalloc,vmalloc,kmem_cache,class
*
* 声明:
* 1. 本系列文档是在vim下编辑,请尽量是用vim来阅读,在其它编辑器下可能会
* 不对齐,从而影响阅读.
* 2. 本文中有些源代码没有全部帖出来,主要是因为篇幅太大的原因;
* 3. 基于2中的原因,本文借鉴了python中的缩进代码风格进行代码的体现:
* 1. 有些代码中的'...'代表省略了不影响阅读的代码;
* 2. 如下代码缩进代表在一个函数内部的代码,至于在什么函数里,不影响阅读:
* ... //省略代码
* struct test_s {
* };
* ... //省略代码
*
* //进入临界区之前加锁 }
* spin_lock(&p->lock); |
* | |
* /* 有效代码 */ |-->|采用缩进,代表在一个函数内
* | |的代码
* //出临界区之后解锁 |
* spin_unlock(&p->lock); }
*
* ... //省略代码
* int __init test_init(void)
* {
* ... //省略代码
* }
* ... //省略代码
*
*
* 2015-3-14 阴 深圳 尚观 Var 曾剑锋
**********************************************************************************/
\\\\\--*目录*--///////////
| 一. alloc_pages接口:
| 二. kmalloc接口:
| 三. vmalloc接口:
| 四. kmem_cache接口:
| 五. dma_alloc_coherent接口:
| 六. 三星pwm中间层驱动:
| 七. class接口:
\\\\\\\\////////////////
一. alloc_pages接口:
1. 常见内存分配标志:
1. GFP_KERNEL: 内存分配会睡眠阻塞,当没有足够内存分配时,直到有内存分配;
2. GFP_ATOMIC: 内存分配不会阻塞,没有足够内存分配时返回错误;
2. 把需要分配的字节数换算成对应的页页框: get_order(1234);
3. 分配页框(page frame),如果分配多个页,分配的多个页在物理地址上是连续的;
4. 两种分配2的get_order(1234)次方个页框,分配失败返回NULL:
1. struct page *p = alloc_pages(GFP_KERNEL, get_order(1234));
2. unsigned long p = __get_free_pages(GFP_KERNEL, get_order(1234));
5. 获取虚拟地址: void *addr = page_address(page);
6. 两种释放连续的页框方法:
1. __free_pages(page, get_order(1234));
2. free_pages(p, get_order(1234));
7. alloc_pages接口实例Demo:
...
struct page *p;
/*void *virt = NULL;*/
unsigned long virt;
int __init test_init(void)
{
/**
* printk('order = %dn', get_order(1234));
* printk('order = %dn', get_order(5000));
*/
/**
* p = alloc_pages(GFP_KERNEL, get_order(1234));
* if(!p)
* return -ENOMEM;
*
* virt = page_address(p);
* printk('virt = %p.n', virt);
*/
virt = __get_free_pages(GFP_KERNEL, get_order(1234));
if(!virt)
return -ENOMEM;
printk('virt = %p.n', (void *)virt);
return 0;
}
void __exit test_exit(void)
{
/*__free_pages(p, get_order(1234));*/
free_pages(virt, get_order(1234));
}
...
二. kmalloc接口:
1. 一般来说,kmalloc通常用于分配少量内存,保证可移植一般不超过128k,
在虚拟地址上连续, 在物理地址上也连续
2. 分配内存: void *p = kmalloc(1234, GFP_KERNEL);
3. 分配内存,并初始化为0: kzalloc();
4. 释放由kmalloc分配的内存空间: kfree(p);
5. kmalloc接口实例:
...
void *virt = NULL;
int __init test_init(void)
{
/*virt = kmalloc(1234, GFP_KERNEL);*/
/*virt = kmalloc(0x400000, GFP_KERNEL);*/
virt = kzalloc(0x400000, GFP_KERNEL);
if(!virt)
return -ENOMEM;
printk('virt = %p.n', virt);
return 0;
}
void __exit test_exit(void)
{
kfree(virt);
}
...
三. vmalloc接口:
1. 一般来说,vmalloc通常用于分配大量内存,在虚拟地址上连续,在物理地址上不一定连续;
2. 分配内存: void *p = vmalloc(0x900000);
3. 释放vmalloc释放的空间: vfree(p);
4. vmalloc接口实例Demo:
...
void *virt = NULL;
int __init test_init(void)
{
virt = vmalloc(0x800000);
if(!virt)
return -ENOMEM;
printk('virt = %p.n', virt);
return 0;
}
void __exit test_exit(void)
{
vfree(virt);
}
...
四. kmem_cache接口:
1. 使用高速内存池对象:
struct kmem_cache *kc = kmem_cache_create('kc', 16, 0,
SLAB_HWCACHE_ALIGN, NULL);
2. 分配内存块:
void *p = kmem_cache_alloc(kc, GFP_KERNEL);
3. 释放内存块: kmem_cache_free(kc, p);
4. 销毁对象: kmem_cache_destroy(kc);
5. kmem_cache接口实例Demo:
...
struct kmem_cache *kc;
void *p[5];
int __init test_init(void)
{
int i;
kc = kmem_cache_create('kc', 16, 0, SLAB_HWCACHE_ALIGN, NULL);
上一篇:Samsung_tiny4412(驱动笔记10)----mdev,bus,device,driver,platform
下一篇:Samsung_tiny4412(驱动笔记08)----jiffies,timer,kthread,workqueue,tasklet
- 热门资源推荐
- 热门放大器推荐
- EVAL-AD7687CBZ,用于 AD7687、16 位、250 Ksps PulSAR 模数转换器的评估板
- 使用 Infineon Technologies AG 的 OMR7815SR 的参考设计
- AD8052AR-EBZ,AD8052ARZ 双通道高速运算放大器评估板,采用 8 引脚 SOIC 封装
- LT1072CS8 升压型升压转换器的典型应用
- 用于微处理器复位电路的 NCP301LSN31T1 3.1V 电压检测器的典型应用
- LT1934IDCB 独立式 350mA 锂离子电池充电器的典型应用电路
- 使用 NXP Semiconductors 的 TDA8559 的参考设计
- OP462GSZ-REEL耳机输出运算放大器典型应用电路
- TLP7820隔离放大器的应用电路(电流检测)
- 3.3 kW APM OBC演示板测试报告



非常经典的关于LLC的杨波博士论文
ICL7621BCPA

XC6406PP60DL






京公网安备 11010802033920号