Linux 简单字符设备驱动
1、hello_drv.c
(1) 初始化和卸载函数的格式是固定的,函数名自定义
(2) printk是内核的打印函数,用法与printf一致
(3) MODULE_LICENSE:模块代码支持开源协议(必须包含此项)
MODULE_AUTHOR:模块作者
MODULE_DESCRIPTION:模块简单描述
MODULE_VERSION:模块代码版本
MODULE_ALIAS:模块的别名
MODULE_DEVICE_TABLE:模块支持什么设备
// 模块化程序必须包含的两个头文件 #include <linux/module.h> #include <linux/init.h> // __init 标记为初始化代码,仅在初始化时使用 static int __init hello_init(void) { printk("-----%s-----\n", __FUNCTION__); return 0; } // __exit 标记为卸载函数,仅在卸载时使用 static void __exit hello_exit(void) { printk("-----%s-----\n", __FUNCTION__); } // 模块入口函数,insmod会调用hello_init module_init(hello_init); // 模块出口函数,rmmod会调用hello_exit module_exit(hello_exit); // 模块遵循开源协议 MODULE_LICENSE("GPL"); // 模块的开发者 MODULE_AUTHOR("Aaron Lee");
2、Makefile
在模块源码目录下使用make指令会自动调用当前目录下的Makefile文件来编译生成hello_drv.ko
# KERNEL_DIR为内核源码路径变量,根据实际情况选择编译过的源码路径 KERNEL_DIR = /home/lialong/iTop4412_Kernel_3.0 # CUR_DIR为需要编译的文件路径,$表示取变量值 CUR_DIR = $(shell pwd) # 驱动代码文件名 DRV_NAME = hello_drv # 应用代码文件名 #USR_NAME = hello_app # -C 指定内核Makefile文件的路径 # M 指定要编译代码的路径 # modules 将程序编译成.ko文件 # arm-none-linux-gnueabi-gcc使用交叉编译工具编译应用层代码 all: make -C $(KERNEL_DIR) M=$(CUR_DIR) modules # arm-none-linux-gnueabi-gcc $(USR_NAME).c -o $(USR_NAME) # make clean # 调用内核中make clean方法在本目录下使用 # 删除编译产生的后缀为.o的文件 clean: make -C $(KERNEL_DIR) M=$(CUR_DIR) clean rm -rf *.o # 需要编译的的文件 obj-m += $(DRV_NAME).o
3、加载模块 insmod hello_drv.ko
打印 -----hello_init-----
4、卸载模块 rmmod hello_drv (卸载不加.ko后缀)
打印 -----hello_exit-----