第一个模块的编写与编译
编写与编译
1、在ubuntu目录下新建文件夹modules,在文件夹下新建文件hello.c文件
$mkdir modules
$cd modules
$touch hello.c
$vi hello.c
hello.c代码如下:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
/*类似声明如下
MODULE_AUTHOR // 声明作者
MODULE_DESCRIPTION // 对这个模块作一个简单的描述,这个描述是"human-readable"的
MODULE_VERSION // 这个模块的版本
MODULE_ALIAS // 这个模块的别名
MODULE_DEVICE_TABLE // 告诉用户空间这个模块支持什么样的设备
*/
// 模块初始化函数声明与实现
static int hello_init(void)
{
printk(KERN_INFO "Hello World!\n");
return 0;
}
// 模块移除函数声明与实现
static void hello_exit(void)
{
printk(KERN_INFO "Hello exit!\n");
}
/* 注意函数没有void参数声明的话在ubunt14.10中报警告:
warning: function declaration isn’t a prototype
*/
module_init(hello_init);
module_exit(hello_exit);
2、在hello.c文件目录下,新建Makefile文件
$touch Makefile
$vi Makefile
Makefile文件内容如下:
KERNEL_DIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
mymodule-objs:=hello.o
obj-m:=mymodule.o
#( 切记不要使用module作为对象名,否则加载模块出错 )
default:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers
3、执行编译,生成mymodule.ko文件
$make
编译输出结果如下:
make -C /lib/modules/3.16.0-59-generic/build M=/home/harry/harry/kernel_test/Mymodule modules
make[1]: Entering directory `/usr/src/linux-headers-3.16.0-59-generic'
CC [M] /home/harry/harry/kernel_test/Mymodule/hello.o
LD [M] /home/harry/harry/kernel_test/Mymodule/module.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/harry/harry/kernel_test/Mymodule/module.mod.o
LD [M] /home/harry/harry/kernel_test/Mymodule/module.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.16.0-59-generic'
hello.c文件分析
包含头文件:
#include<linux/init.h>
#include<linux/module.h>
函数声明:
static int mymodele_init(void);
static void mymodule_exit(void);
提示: function without void declaration will display error:
warning: function declaration isn’t a prototype
内核调用
module_init(mymodule_init);
module_exit(mymodule_exit);
模块安装与卸载
通过
$sudo insmod mymodule.ko
为linux添加模块
除此之外,
$sudo rmmod myodule
用于卸载模块
$dmesg
用来显示内核环缓冲区(kernel-ring buffer)内容,内核将各种消息存放在这里。