写在前面:本篇主要以hello word驱动实例,来阐述驱动的基本结构从而打开驱动编程的大门。
正文:
1、两个命令: 加载模块进内核: insmod XX.ko 卸载内核中的模块 rmmod XX.ko
2、驱动模块化编程的好处:
(1)、内核中85%是驱动,15%才是调度、信号量等之类的,如果把所有驱动编译进内核,会导致内核非常庞大。
(2)、很多驱动都只在特定机器上使用。即内核的定制使用。
(3)、为实现热插拔提供基础。热插拔:例如在运行的linux设备上,插入一个外设,这时候linux设备检测到这个外设后会加载驱动,当将这个外设拔掉之后,linux设备会卸载调这个驱动。
3、Hello word实例:.c文件和Makefile,同样,代码中的注释尽可能完整了
hello.c:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
/* 非必需内容*/
MODULE_LICENSE("Dual BSD/GPL");//许可证、版权
MODULE_AUTHOR("kiran");//作者
MODULE_DESCRIPTION("hello demo");//模块描述
MODULE_VERSION("1.0");//
/* 入口函数 */
static int hello_init(void)
{
printk(KERN_ALERT "hello_init is called\n");
}
/* 退出函数 */
static void hello_exit(void)
{
printk(KERN_ALERT "hello_exit is called\n");
}
/* 注册 */
module_init(hello_init); //模块的入口 insmo命令时就会执行module_init 加载的函数
module_exit(hello_exit); //模块的出口 rmmod命令时就会执行module_exit 加载的函数
Makefile
KERN_DIR = /lib/modules/$(shell uname -r)/build
all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=$(shell pwd) modules clean
rm -rf modules.order
obj-m := hello.o
# uname -r :显示操作系统的发行编号
# make -C :指将当前工作目录转移到指定的位置,-C $(KERN_DIR) 指明跳转到内核源码目录下,读取那里的Makefile。
# M :M是内核根目录下的Makefile中使用的变量,“M=”的作用是在make命令中对变量M进行赋值。
# 当用户需要以某个内核为基础编译一个外部模块的话,需要在make modules 命令中加入“M=dir”,
# 表示包含dir下的Makefile文件,加入M选项后,程序会自动到你所指定的dir目录中查找模块源码,将其编译,生成KO文件
# modules:内核根目录下的Makefile的一个目标,表示编译成模块的意思
# obj-m := hello.o : obj-m表示把编译hello.c生成的文件hello.o编译成内核模块(不会编译到内核,但是会生成一个独立的 "hello.ko" 文件)。
# ko 文件是内核模块文件,是内核加载的某个模块,一般是驱动程序
在helloc.c目录下make之后:会生成.ko文件
在该目录下 执行 insmod hello.ko命令,然后dmesg,就会 看到hello_initi called 已经产生了调用,如下:
在该目录下 执行 rmmod hello.ko命令,然后dmesg,就会 看到hello_exit is called 已经产生了调用,如下: