linux驱动开发

利用Linux设备驱动程序的第一个例程:Hello World模块学习内核模块的结构。  

View Code

 

1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 
 4 static int __init hello_init(void)
 5 {
 6     printk(KERN_ALERT"Hello World\n");
 7     return 0;
 8 }
 9 
10 static void __exit hello_exit(void)
11 {
12     printk(KERN_ALERT"Goodbye, cruel world\n");
13 }
14 
15 module_init(hello_init);
16 module_exit(hello_exit);
17 
18 MODULE_LICENSE("GPL");

1、 所有模块都包含以下两个头文件:

View Code
#include <linux/init.h>
2 #include <linux/module.h>

module.h包含有可装载模块所需要的大量符号和函数定义。

包含init.h的目的是指定初始化和清除函数。

 

2、尽管不是严格要求,但模块应该指定代码所使用的许可证。

View Code

 

1 MODULE_LICENSE("GPL");

内核能够识别的许可证有:

View Code
1 “GPL”(任一版本的GNU通用公共许可证)
2 “GPL v2”(GPL版本2)
3 “GPL and additional rights”(GPL及附加权利)
4 “Dual BSD/GPL”(BSD/GPL双重许可证)
5 “Dual MPL/GPL”(MPL/GPL双重许可证)
6 “Proprietary”(专有)

如果一个模块没有显示地标记为上述内核可识别的许可证,则会被假定是专有的,而内核装载这种模块就会被“污染”。

 

另外,可在内核中包含其他描述性定义:

View Code

上述MODULE_声明可出现在源文件中源代码函数以外的任何地方,新近的内核编码习惯是将这些声明放在文件的最后

 

3、初始化和关闭

初始化函数的实际定义通常如下:

View Code

__init和__initdata表明该函数仅在初始化期间使用。

__devinit和__devinitdata,只有在内核未被配置为支持可热插拔设备的情况下,才会被翻译为__init和__initdata

 

清除函数的实际定义通常如下:

View Code

被标记为__exit的函数只能在模块被卸载或者系统关闭时被调用。

如果一个模块未定义清除函数,则内核不允许卸载该模块。

 

4、Makefile分析

View Code

obj-m := hello.o

代表了我们要构造的模块名称为hello.ko,make会在当前目录下找到hello.c文件进行编译。如果hello.o是由两个源文件生成(比如file1.c和file2.c),则正确的makefile可如下编写:

obj-m := hello.o

hello-objs := file1.o file2.o

make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-

-C $(KDIR)   指定了内核源代码的位置,其中保存有内核的顶层makefile文件。

M=$(PWD)  指定了模块源代码的位置

modules  目标指向obj-m变量中设定的模块。

 

insmod hello.ko

dmesg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值