首先写给自己,刚刚开始学习Linux驱动,并且是用迅为4412开发板跟着教学视频学习的。在这里写下一些记录方便自己回顾,若理解有不对的地方,希望有缘人能够指出。
一,Module是什么
在很久之前,写device driver 或者进行测试的时候,每次都需要编译生成一次内核,非常的麻烦,这种加载驱动的方式也叫静态加载。
而有了module,我们可以先写好module,然后使用insmod命令将module载入内核,不用的时候用rmmod命令卸载,测试效率得到了很大的提升,这种加载驱动方式叫动态加载。
二,加载流程
首先要先写好module,然后写好Makefile,在ubuntu中用make命令将module.c文件编译成.ko文件。再用insmod指令便可以加载module。
三,最基本的Module
1,要使用module,必须声明GPL协议
1.“include/linux/module.h”头文件里包含大量加载模块需要的函数和符号的定义,module添加GPL协议要加载这个头文件。
2.所有的Linux 代码必须遵循GPL 协议,如果不声明GPL 协议,模块是无法在Linux 中使用的,添加遵循GPL协议用MODULE_LICENSE(GPL)。
3.如果想声明代码作者(也就是你自己)的话,可以添加MODULE_AUTHOR(_author)。
2,出入口函数
有了出入口函数,便明白从哪里进入module,从哪里出去,这是module最基本要有的东西
1.包含出入口函数的头文件在include /linux/init.h中
2.入口函数module_init(x)
3.出口函数module_exit(x)
4.出入口函数里面的参数“x”,一般是一个函数,实现众多功能,如驱动的注册
3,最基本的module代码
#include <linux/init.h> //包含出入口函数
#include <linux/module.h> //添加GPL协议的MODULE_LICENSE指令
MODULE_LICENSE("Dual BSD/GPL"); //声明是开源的,没有内核版本限制
MODULE_AUTHOR("TOPEET");
static int hello_init(void)
{
printk(KERN_EMERG "HELLO WORLD enter!\n"); //打印信息,调试用
return 0;
}
static void hello_exit(void)
{
printk(KERN_EMERG "HELLO WORLD exit!\n"); //打印信息,调试用
}
module_init(hello_init); //入口函数
module_exit(hello_exit); //出口函数
四,对应的Makefile
因为没研究过makefile,所以写makefile时候,照猫画虎就可以了,只需要改xxxxxxx.o就可以
#!/bin/bash
#通知编译器我们要编译模块的哪些源码
#这里是编译xxxxxxx.c这个文件编译成中间文件xxxxxxx.o
obj-m +=xxxxxxx.o
#源码目录变量,这里用户需要根据实际情况选择路径
#作者是将Linux的源码拷贝到目录/home/topeet/android4.0下并解压的
KDIR := /home/topeet/Android/iTop4412_Kernel_3.0
#当前目录变量
PWD ?= $(shell pwd)
#make命名默认寻找第一个目标
#make -C就是指调用执行的路径
#$(KDIR)Linux源码目录,作者这里指的是/home/topeet/android4.0/iTop4412_Kernel_3.0
#$(PWD)当前目录变量
#modules要执行的操作
all:
make -C $(KDIR) M=$(PWD) modules
#make clean执行的操作是删除后缀为o的文件,可以添加其他的
clean:
rm -rf *.o
五,操作
将module.c文件和Makefile拷贝到ubuntu同一个文件夹中,使用make命令,然后生成了.“ko”文件,将.ko文件拷贝到开发板中,用insmod module.ko 命令加载模块(看你命名是什么,.c文件命名为hello.c 那生成的是hello.ko)
/THE END/