`
helloyesyes
  • 浏览: 1266090 次
  • 性别: Icon_minigender_2
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

linux内核与驱动基于TE2440II开发板(一)构造和运行模块

阅读更多

哈尔滨理工大学软件工程专业08-7李万鹏原创作品,转载请标明出处

http://blog.csdn.net/woshixingaaa/archive/2010/11/08/5995799.aspx

这个是《LINUX设备驱动程序》第二章的示例程序。编译这个程序之前要构建好内核源码树,

所谓源码树就是编译好内核后的/usr/src/$(shell uname -r) 目录

方法见我的博客http://blog.csdn.net/woshixingaaa/archive/2010/11/07/5993648.aspx

我的这个程序是在源码树之外编译内核模块。

module.h包含有可装载模块需要的大量符号和函数定义,包含init.h的目的是指定初始化和清除

函数。hello_init()和hello_exit()声明为静态是因为这两个函数只在本文件中使用。__init表明该函

数只在调用时被使用,__exit表示该函数只在模块被卸载或者系统关闭时被调用。printk是在内

核中运行向控制台输出显示的函数,LINUX内核首先在内核空间分配一个静态的缓冲区,作为

显示用的空间,然后调用sprintf,格式化显示字符串,然后调用tty_write向终端进行信息的显示。

module_init()和module_exit()是两个宏,前者用来注册模块,后者用来注销模块。使用insmod时

module_init()注册的函数被调用,使用rmmod时module_exit()注册的函数被调用。KERN_ALERT

用来定义这条消息的优先级,我们需要在模块中显示指定高优先级的原因在于:具有默认优先级

的消息可能不会输出在控制台上,这依赖于内核版本。


这个是Makefile文件,KERNELRELEASE是源码树顶层Makefile中定义的,ifneq用来判断参数是

否不相等,注意ifneq和后面的括号之间有一个空格,否则报错“Makefile:1: *** 遗漏分隔符 。 停止

。”将 KERNELRELEASE与空进行比较,如果不为空则指定目标obj-m:=hello.o, KERNELDIR 后

的?=是条件赋值运算符,如果KERNELDIR没有被赋值,则对它进行复制,后面这个/lib/modules/

$(shell uname -r)/build是一个符号链接,指向源码树。$(MAKE) -C $(KERNELDIR) M=$(PWD) mo

dules,我分析了好久,查了很多资料,是我感觉最难理解的一句。此命令首先改变当前工作目录到

-C指定的位置(即内核源码目录),其中保存有内核的顶层Makefile,执行此Makefile,需要编译模块,M

=$(PWD)指定了需要回到源码的目录,此时再次进入源码目录的Makefile,此时KERNELRELEASE

已被定义了,所以执行obj-m:=hello.o,指定了需要编译的模块,然后make modules进行编译。.PHON

Y: modules modules_install clear指定modules modules_install clear 都是伪指令,他们没有目标文件,

只相当于地址标号,如果有同名的目标不会发生错误。

可以安装模块了:


如果在文本控制台下可以直接输出


如果是在终端的仿真器中则许查看日志


此句不同发行版不同,有的是


然后卸载


再在日志中查看


模块参数传递

内核中使用module_param宏来声明参数,这个宏定义在moduleparam.h中,module_param需要3个参数:变量的名字,类型,以及用于sysfs入口项的访问许可掩码。

在程序中加入

修改hello_init


终端输入



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics