/***************************************************************************************************
linux 最简单的设备驱动
* hello.c
环 境:Fedora17 虚拟机
结 果:编译成功
实 验 者:张永辉 2012.07.XX
* 参考 Linux驱动开发庖丁解牛之二——模块编程 深入浅出LDD
***************************************************************************************************/
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for printk:KERN_ALERT */
#include <linux/init.h>
MODULE_LICENSE("Dual BSD/GPL"); //告知内核,该模块带有一个自由的许可证;若没有,在模块加载时内核会抱怨.
static int hello_init(void) //void 不能省略,否则报警
{
printk(KERN_ALERT "Hello world\n"); //见注解(1) 使用KERN_ALERT使信息出现在控制台
return 0; //A non 0 return means init_module failed; module can't be loaded.
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye world\n");
}
module_init(hello_init); //module_init 和 module_exit 是必须要有的,用于指出hello_init _exit的角色
module_exit(hello_exit);
MODULE_AUTHOR("zyhui65@163.com"); //可选配的信息
MODULE_DESCRIPTION("The first module program");
MODULE_VERSION("V1.0");
MODULE_ALIAS("Chinese: ren zhi chu");
/*************************************************************************************************************
(1)模块运行于内核空间,所以,不能引用标准库函数
(2) Linux 驱动程序的开发者无非处于两种情况:
1. 对一个全新的硬件编写驱动程序。
2. 移植一个驱动程序。
(3)操作步骤
#make
...
#insmod hello.ko 安装模块 会打印Hello world
#lsmod 查看有哪些模块
#rmmod hello 卸载模块 会打印Goodbye world
(4)犯错误总结
1: 没有Makfile文件
2: makefile 名字写成了 Makefile
3: MODULE_LICENSE 错写成 MODULE_LICENCE
4: MODULE_LICENSE ("Dual BSD/GPL"); 其引号 写成中文的了。
(5) printk() 函数中使用的日志级别,在编程过程中自定义地进行信息的输出, 便于调试
printk的日志级别定义如下(在linux26/includelinux/kernel.h中)
#defineKERN_EMERG"<0>" //紧急事件消息,系统崩溃之前提示,表示系统不可用
#defineKERN_ALERT"<1>" //报告消息,表示必须立即采取措施
#defineKERN_CRIT"<2>" //临界条件,通常涉及严重的硬件或软件操作失败
#defineKERN_ERR"<3>" //错误条件,驱动程序常用KERN_ERR来报告硬件的错误
#defineKERN_WARNING"<4>" //警告条件,对可能出现问题的情况进行警告
#defineKERN_NOTICE"<5>" //正常但又重要的条件,用于提醒。常用于与安全相关的消息
#defineKERN_INFO"<6>" //提示信息,如驱动程序启动时,打印硬件信息
#defineKERN_DEBUG"<7>" //调试级别的消息
没有指定日志级别的printk语句默认采用:DEFAULT_ MESSAGE_LOGLEVEL
级别也可以写为:
printk("<6> INFO\n"); 不使用逗号。
(6)insmod hello.ko 时若没有打印消息
原因:klogd 和 syslogd 都在系统中运行, 内核消息被追加到 /var/log/messages了
查看方法一: cat /var/log/messages
****************************************************************************************************/
/***************************************************************************************************
linux 驱动编程 入门
* Makefile
***************************************************************************************************/
obj-m := hello.o #模块编译的目标必须以obj-m 这样的形式指出
KERNELDIR ?= /lib/modules/$(shell uname -r)/build #模块的编译必须指定内核源代码的路径
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules #本行开头必须使用 Tab 键
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clearn:
rm -rf *.o *.ko *mod.o [mM]odule* .*.cmd .tmp_versions