linux内存与I/O访问

来源:互联网 发布:简单orcle sql语句 编辑:程序博客网 时间:2024/04/29 06:45

1、用户空间内存动态申请

在用户空间动态申请内存的函数为malloc(), 这个函数在各种操作系统上的使用是一致的,malloc() 申请的内存的释放函数为 free()。

malloc() 的内存一定要被 free() ,否则会造成内存泄露。


2、内核空间内存动态申请

1.  kmalloc()

void *kmalloc(size_t size, int flags);

给kmalloc()的第一个参数是要分配的块的大小,第二个参数为分配标志,用于控制 kmalloc() 的行为。

最常用的分配标志是GFP_KERNEL,其含义是在内核空间的进程中申请内存。kmalloc() 的底层依赖  

_ _get_free_pages()实现,分配标志的前缀GFP正好是这个底层函数的缩写。使用GFP_KERNEL标志申请内存时,若暂时不能满足,则进程会睡眠等待也,即会引起堵塞,因此不能在中断上下文或持有自旋锁的时候使用GFP_KERNEL申请内存。

2. _ _get_free_pages()

_ _get_free_pages()系类函数/宏是Linux内核本质上最底层的用于获取空闲内存的方法,因为底层的伙伴算法以page的2的n次幂为单位管理空闲内存,所以最底层的内存申请总是以页为单位的。

_ _get_zeroed_page(unsigned int flags); //该函数返回一个指向新页的指针并且将该页清零。

_ _get_free_page(unsigned int flags); //该宏返回一个指向新页的指针但是该页不清零,它实际上为:

#define _ _get_free_page(gfp_mask)    \

     _ _get_free_pages( (gfp_mask), 0)

就是调用了下面的_ _get_free_pages() 申请1页。

_ _get_free_pages(unsigned int flags, unsigned int order); //该函数可分配多个页并返回分配内存的首地址,分配的页数为2的order次幂,分配的页也不清零。order允许的最大值是10(即1024页)或者11(2048页),依赖与具体的硬件平台。

struct page * alloc_page_page(int gfp_mask, unsigned long order); //既可以在内核空间分配,也可以在用户空间分配。

使用_ _get_free_pages()系列函数/宏申请的内存应使用下列函数释放。

void free_page(unsigned long addr);

void free_pages(unsigned long addr, unsigned long order);

3. vmalloc()

vmalloc() 一般用在为只存在软件中(没有对应的硬件意义)的较大的顺序缓冲区分配内存,vmalloc()远大于_ _get_free_pages()的开销,为了完成vmalloc(),新的页表需要被建立。因此,只是调用vmalloc()来分配少量的内存(如1页)是不妥的。

void *vmalloc(unsigned long size);

void vfree(void * addr);


3、申请与释放设备I/O端口和I/O内存

1. I/O端口申请

struct resource *request_region(unsigned long first, unsigned long n, const char *name); //申请n个端口,从first开始,name参数为设备的名称。

void release_region(unsigned long start, unsigned long n); //将request_region()申请的I/O端口归还给系统。

2.I/O内存申请

struct resource *request_mem_region(unsigned long start, unsigned long len, char *name);

void release_mem_region(unsigned long start, unsigned long len);


4、DMA

DMA是一种无需CPU的参与就可以让外设与系统内存之间进行双向数据传输的硬件机制。使用DMA可以使系统CPU从实际的I/O数据传输过程中摆脱出来,从而大大提高系统的吞吐率。DMA通常与硬件体系结构特别是外设的总线技术密切相关。

DMA方式的数据传输由DMA控制器(DMAC)控制,在传输期间,CPU可以并发地执行其他任务。当DMA结束后,DMAC通过中断通知CPU数据传输已经结束,然后由CPU执行相应的中断服务程序进行后处理。

和中断一样,在使用DMA之前,设备驱动程序需首先向系统申请DMA通道,申请DMA通道的函数如下:

int request_dma(unsigned int dmanr, const char * device_id);

void free_dma(unsigned int dmanr); //释放该通道

原创粉丝点击