核心模块与应用程序的对比
(1)大多数应用程序是从头到尾执行单个任务,而模块程序却只是预先注册自己以便服务于将来的某个请求,然后它的初始化函数就立即结束。
(2)应用程序在退出时,可以不管资源的释放或者其他的清楚工作,但模块的退出函数却必须撤销初始化函数所做的一切,否则,在系统重新引导之前某些东西就会残留在系统中。
(3)应用程序可以调用它并未定义的函数(函数库),而模块仅仅被链接到内核,能调用的函数仅仅是由内核导出的那些函数,而不存在任何可链接的函数库。
(4)处理错误的方式不同:应用程序开发过程中的段错误是无害的,并可使用调试器跟踪到源代码中的问题所在,而一个内核错误即使不影响整个系统,也至少会杀死当前进程。
(5)并发的处理
用户空间和内核空间
模块运行在所谓的内核空间,应用程序运行在所谓的用户空间。
通常来讲,一个驱动程序包括2类任务:模块中的某些函数作为系统调用的一部分而执行,而其他函数则负责中断处理。
编译和装载
准备工作:
(1)具备合适的编译器和工具
(2)内核树
make命令举例
ARCH=arm
CROSS_COMPILE=arm-none-linux-gnueabi-
obj-m := hello.o
KERNELDIR ?= /home/omap/linux-2.6.28-omap
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
-C:改变目录到指定的位置
M:让该makefile在构造modules目标之前返回到模块源代码目录
然后modules目标指向obj-m变量中设定的模块。
那么insmod是如何工作的呢?
实际上它依赖于定义在kernel/module.c中的一个系统调用。函数sys_init_module给模块分配内核内存以便装载模块,然后该系统调用将模块正文复制到内存区域,并通过内核符号表解析模块中的内核引用,最后调用模块的初始化函数。
小提示:
/proc/devices与/dev区别
/proc/devices/中的设备是通过insmod加载到内核的,它可产生一个major供mknod作为参数。
/dev/*.* 是通过mknod加上去的,格式:mknod device1 c/b major minor 如:mknod dr1 c 254 0,用户通过此设备名来访问你的驱动。
阅读(1165) | 评论(0) | 转发(0) |