Linux设备驱动的第一个例子。
Linux设备驱动的第⼀个例⼦。
Linux 设备驱动的第⼀个例⼦
⼀.源程序( hello.c
1. #include <linux/init.h>
2. #include <linux/module.h>
清明小长假第1天3. MODULE_LICENSE("Dual BSD/GPL");
4. static int hello_init(void)
5. {
6.        printk(KERN_ALERT "Hello, world/n");
7.        return 0;
8. }
9. static void hello_exit(void)
10. {
11.        printk(KERN_ALERT "Goodbye, cruel world/n");
12. }
13. module_init(hello_init);
14. module_exit(hello_exit);
(1) moudle.h 包含了⼤量加载模块需要的函数和符号的定义.
(2) init.h 来指定你的初始化和清理函数
(3) MODULE_LICENSE("GPL");指定代码使⽤哪个许可
内核认识的特定许可有,
"GPL"( 适⽤ GNU 通⽤公共许可的任何版本 ),关闭uac
"GPL v2"( 只适⽤ GPL 版本 2 ),
"GPL and additional rights",
"Dual BSD/GPL",
"Dual MPL/GPL",
"Proprietary".
(4)除此之外还可以包含模块的其他描述性定义
MODULE_AUTHOR ( 声明谁编写了模块 ),
MODULE_DESCRIPION( ⼀个⼈可读的关于模块做什么的声明 ), MODULE_VERSION ( ⼀个代码修订版本号),
MODULE_ALIAS ( 模块为⼈所知的另⼀个名⼦ ),
MODULE_DEVICE_TABLE ( 来告知⽤户空间, 模块⽀持那些设备).
(5) static int hello_init(void)
初始化函数应当声明成静态的,
static void hello_exit(void)
清理函数, 它注销接⼝, 在模块被去除之前返回所有资源给系统
(6) module_init(hello_init);
这个宏定义增加了特别的段到模块⽬标代码中, 表明在哪⾥到模块的初始化函数. 没有这个定义, 你的初始化函数不会被调⽤.          module_exit(hello_exit);
(7)printk
在 Linux 内核中定义并且对模块可⽤; 它与标准 C 库函数 printf 的⾏为相似. 内核需要它⾃⼰的打印函数, 因为它靠⾃⼰运⾏(8)字串 KERN_ALERT 是消息的优先级,因为使⽤缺省优先级的消息可能不
会在任何有⽤的地⽅显⽰
⼆.Makefile⽂件
运动步数怎么打开1. obj-m := hello.o
2. KERNELDR := /usr/src/linux-2.6.26
3. PWD := $(shell pwd)
4. modules:
5.    $(MAKE) -C $(KERNELDR) M=$(PWD) modules
6. moduels_install:
7.    $(MAKE) -C $(KERNELDR) M=$(PWD) modules_install
8. clean:
9.    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
(1)obj-m := hello.o制作母亲节贺卡
表明有⼀个模块要从⽬标⽂件 hello.o 建⽴. 在从⽬标⽂件建⽴后结果模块命名为 hello.ko。
(2)KERNELDR := /usr/src/linux-2.6.26
⽤来定位内核源码⽬录
(3)PWD := $(shell pwd)
获得当前⽬录路径
(4)M=$(PWD) M= 选项
使 makefile 在试图建⽴模块⽬标前, 回到你的模块源码⽬录
(5)$(MAKE) -C $(KERNELDR) M=$(PWD) modules
这个命令开始是改变它的⽬录到⽤ -C 选项提供的⽬录下( 就是说, 你的内核源码⽬录 ). 它在那⾥会发
现内核的顶层 makefile. 这个M= 选项使 makefile 在试图建⽴模块⽬标前, 回到你的模块源码⽬录. 这个⽬标, 依次地, 是指在 obj-m 变量中发现的模块列表, 在我们的例⼦⾥设成了
(6)$(MAKE) -C $(KERNELDR) M=$(PWD) modules_install
⽤于模块的安装
(7)rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
⽤于make clean清除上次编译⽣成的⽂件
三.
注意:只有超级⽤户可以加载和卸载模块 .
1. % make
2. make[1]: Entering directory `/usr/src/linux-2.6.26'
3.  CC [M] /home/ldd3/src/misc-modules/hello.o
4.  Building modules, stage 2.
5.  MODPOST
6.  CC /home/ldd3/src/d.o
7.  LD [M] /home/ldd3/src/misc-modules/hello.ko
8. make[1]: Leaving directory `/usr/src/linux-2.6.26'
9. % su
10. root# insmod ./hello.ko
11. Hello, world
12. root# rmmod hello
13. Goodbye cruel world
14. root#
1. insmod
加载模块的代码段和数据段到内核,并且调⽤模块的初始化函数来启动所有东西.
2. rmmod
如果内核认为模块还在⽤( 就是说, ⼀个程序仍然有⼀个打开⽂件对应模块输出的设备 ), 或者内核被配置成不允许模块去除, 模块去除会失败.
3. lsmod
⽣成⼀个内核中当前加载的模块的列表. lsmod 通过读取 /proc/modules 虚拟⽂件⼯作. 当前加载的模块的信息也可在位于 /sys/module 的 sysfs 虚拟⽂件系统到.
4. 前⾯的屏幕输出是来⾃⼀个字符控制台; 如果你从⼀个终端模拟器或者在窗⼝系统中运⾏ insmod 和 rmmod, 你不会在你的屏幕上看到任何东西. 消息进⼊了其中⼀个系统⽇志⽂件中, 例如 /var/log/messages (实际⽂件名⼦随 Linux 发布⽽变化).
白羊金牛
5. vermagic.o⽬标⽂件:
当加载⼀个模块时,内核为模块检查特定处理器的配置选项,确定它们匹配运⾏的内核。如果模块⽤不同选项编译,则不会加载。出现下⾯内容:
菊花爆满山 马博1. # insmod hello.ko
2. Error inserting './hello.ko':-1 Invlid module forma
查看系统⽇志⽂件(var/log/message)将发现导致模块⽆法加载的原因
现在应该可以跑完程序,并了解了⼀些Linux设备驱动最基础的知识了吧!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。