编写linux模块(由浅入深)

开启内核对模块的支持

在编译内核时确保开启加载模块支持。
Loadable module support --->
         [*] Enable loadable module support
         [*] Module unloading
         [ ] Module versioning support (EXPERIMENTAL)
         [*] Automatic kernel module loading
勾选如上选项,重新编译安装内核。

Hello module

首先确保运行的内核和源代码版本一致。
进入linux源码目录drivers/misc/,创建文件mymodule.c, 代码如下
#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
static int __init mymodule_init(void)
{
printk ("Hello module!\n");
return 0;
}
static void __exit mymodule_exit(void)
{
printk ("Unloading my module.\n");
return;
}
module_init(mymodule_init);
module_exit(mymodule_exit);
MODULE_LICENSE("GPL");
然后在同一个目录下的Makefile文件追加一行
obj-m += mymodule.o

编译
make -C <top directory of your kernel source> SUBDIRS=$PWD modules

加载
insmod ./mymodule.ko
成功会打印出 Hello module!

移除
rmmod mymodule


模块和内核

现在来用模块做一些有意思的事。
有一个关键是模块只能访问内核导出的函数和变量。示例如下:

在内核kernel/prink/printk.c中添加全局变量
int my_variable = 0;
重新编译并重启内核

在mymodule_init中添加如下代码:
extern int my_variable;
printk ("my_variable is %d\n", my_variable);
my_variable++;
重现编译并加载模块

<span style="font-family: Arial, Helvetica, sans-serif;">这次出现了错误信息      insmod: error inserting './mymodule.ko': -1 Unknown symbol in module</span>
它的意思是内核不允许模块访问变量, 当模块加载的时,它查找函数和变量的外部引用,my_variable变量一定是在内核中,只是没有找到。
在prinkf.c my_variable下添加导出符号代码
EXPORT_SYMBOL(my_variable);
问题解决。

加载模块
my_variable is 0
Hello module!

再次重新加载
# rmmod mymodule && insmod ./mymodule.ko
打印:
Unloading my module.
my_variable is 1
Hello module!

模块可以访问内核中导出的函数和方法,权限很高。建议在虚拟机里测试编写代码,因为一不小心系统就崩了。

模块可以传参(不详细介绍)

# insmod module.ko [param1=value param2=value ...]

让模块支持中断

未完成













發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章