1、Linux内核模块编写模块:1、module_init(XXX_init);static int __init XXX_init(){...};2、module_exit(XXX_exit);static int __exit XXX_exit(){...};3、MODULE_lICENSE("GPL"); //模块许可声明4、static int booknum=100;module_param(bookNumber,int,S_IRUGO);编写编译文件Makefile:1、mymodule_objs :=book.oobj-m :=book.oKDIR := /usr/src/linux-headers-2.6.38-8-generic2、all:$(MAKE) -C $(KDIR) M=$(PWD)clean:rm -rf *.mod.c *.mod.o *.ko *.o *.tmp_versions *.order *symvers2、在内核中申请内存在内核中申请内存和在用户空间中申请内存不同,有以下因素引起了复杂性,包括:1、内核的虚拟地址和物理地址被限制到1G大小2、linux内核中没有分页内存3、内核通常需要连续的物理内存4、通常内核申请内存过程不能睡眠5、内核中的错误比其他地方错误代价更大在内核中申请内存最常用的方法:#include <linux/slab.h>void *kmalloc(size_t size, int flags);flags:flags控制了申请内存的行为。flags分为三类:action modifiers,zone modifiers,types。Action modifiers告诉内如以怎么的行为去申请内存。比如kernel能否睡眠。Zone modifiers告诉内核从什么地方去申请内存,比如一些请求可能需要申请的内存能够让硬件以DMA的方式方式。type指定了申请的类型。把这写flags可以合成一个变量,传给kmalloc。3、内核中申请内存需遵循的一些简单规则1、判断申请内存的时候可否睡眠,也就是调用kmalloc的时候能否被阻塞。如果在一个中断处理,在中断处理的下半部分,或者有一个锁的时候,就不能被阻塞。如果在一个进程上下文,也没有锁,则一般可以睡眠。2、如果可以睡眠,指定GFP_KERNEL。3、如果不能睡眠,就指定GFP_ATOMIC。4、如果需要DMA可以访问的内存,比如ISA或者有些PCI设备,就需要指定GFP_DMA。5、需要对kmalloc返回的值检查NULL。6、为了没有内存泄漏,需要用kfree()来释放内存。kmalloc并不直接从分页机制中获得空闲页面,而是从slab页面分配器那获得需要的页面,slab的实现代码限制了最大分配的大小为128k.4、几种内存分配函数比较:1、 __get_free_pages直接对页框进行操作,最大分配内存为4M,适用于分配较大量的连续物理内存。2、 kmem_cache_alloc基于slab机制实现,最大分配内存为128kb, 适合需要频繁申请释放相同大小内存块时使用.3、kmalloc基于kmem_cache_alloc实现,最大分配内存为128kb, 最常见的分配方式,需要小于页框大小的内存时可以使用。4、vmalloc建立非连续物理内存到虚拟地址的映射,物理不连续,适合需要大内存,但是对地址连续性没有要求的场合5、dma_alloc_coherent基于__alloc_pages实现,最大分配内存为4MB,适用于DMA操作。6、ioremap实现已知物理地址到虚拟地址的映射,适用于物理地址已知的场合,如设备驱动7、alloc_bootmem在启动kernel时,预留一段内存,内核看不见,小于物理内存大小,内存管理要求较高
Linux内核中编写一个模块,实现申请一块内存,需要考虑哪些方面?
最新推荐文章于 2024-06-21 19:13:30 发布