您的位置:首页 > 其它

内核中与驱动相关的内存操作之五(kmalloc)

2014-03-18 15:59 141 查看
在内核空间里面获取一段内存区域,最常用到的API就是kmalloc.

1.原型(lk2.6.22)如下:

static inline void *kmalloc(size_t size, gfp_t flags)


2.参数说明:

size:

要分配内存空间的大小,以字节为单位.

flags:

分配标志,用来控制kmalloc的行为.主要如下:

2-1.

GFP_KERNEL:

这是最常用的标志.以此标志控制的kmalloc行为的内存分配,会引起睡眠.因此,不能在进程上下文之外使用此标志来获取内存,否则会有很大的风险和隐患.如原子上下文、中断上下文、tasket、内核定时器这些场景,不应该使用此标志来获取内存;

GFP_ATOMIC:

针对上述GFP_KERNEL所带来的局限,GFP_ATOMIC分配内存期间不会引起睡眠.

__GFP_DMA:

在ZONE_DMA区间获取内存.例如X86,DMA区用在RAM的前16M,传统的ISA设备可以分配此DMA区域内存;

__GFP_HIGHMEM:

在ZONE_HIGHMEM区间获取内存.kmalloc是不能用来分配高端内存区间的内存的.

最常用的就是前面两个标志,后面的也往往接触到,其他的就比较"冷门".

3.返回值:

成功返回分配的目标内存空间的首地址;失败返回NULL.

4.应用场景:

4-1.kmalloc分配的内存绝大多数是位于ZONE_NORMAL的;

4-2.kmalloc分配的区域在物理内存中也是连续的;

4-3.它返回的是内核的逻辑地址.内核的逻辑地址是内核虚拟地址的子集,它与物理地址是线性关系,物理地址加上一个偏移量就是逻辑地址.比如CPU寄存器的值都被转换为逻辑地址以供内核访问的;

4-4.不能分配高端内存;

4-5.kmalloc分配的内存不应该大于128KB,如果只是分配几千个字节的内存,优先考虑非kmalloc之外的函数;

4-6.kmalloc分配的内存使用完之后,用kfree()释放掉.

5.实例:

kmalloc/kzmalloc在内核空间获取内存是最常见的,比比皆是.例如当一个USB插入到USB Port口的时候,因为是先有驱动后有设备,因此,会引发一个软件表征来表征此设备是一个"USB设备".因此,涉及到软件体的分配.如下:

static void hub_port_connect_change(struct usb_hub *hub, int port1,u16 portstatus, u16 portchange)
{
... ...;
udev = usb_alloc_dev(hdev, hdev->bus, port1);

... ...;
}

-->

struct usb_device *
usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
{
struct usb_device *dev;

dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return NULL;
... ...;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: