linux内核模块编写方法
来源:互联网 发布:网络文学评论停刊 编辑:程序博客网 时间:2024/06/05 11:30
目录
- 一 内核模块结构
- 二 模块编译测试
- 1 编译
- 11 Makefile 文件的书写
- 12编译方法
- 2 加载模块
- 3 卸载模块
- 1 编译
- 三 模块参数
- 1 c语言主函数的参数形式
- 2 linux内核模块参数形式
- 四 多模块同时编译
- 1 程序
- 2 编译结果
- 3 加载卸载
- 五 多文件编译成一个模块
- 1 程序
- 2 编译
- 3 挂载卸载
一 内核模块结构
例子:
#include <linux/kernel.h> //需要包含的内核头文件#include <linux/module.h> //模块头文件//模块的入口函数 __init 是linux定义的关键字,表示这是一个入口函数static int __init hello_module_init(void){ printk("Hello,module is installed !\n"); return 0;}//模块出口函数 __exit linux定的关键字,表示出口static void __exit hello_module_cleanup(void){ printk("Good-bye, module was removed!\n");}//这两个函数分别是模块加载函数和模块卸载函数module_init(hello_module_init);module_exit(hello_module_cleanup);//表示模块许可声明,这个声明是必须的,如果没有这个声明,在加载模块是会出现内核污染警告MODULE_LICENSE("GPL");
二 模块编译测试
2.1 编译
2.1.1 Makefile 文件的书写
编译使用 makefile 文件编译,具体书写方法:
obj-m += module_001.o//内核所在目录KDIR:=/root/workdir/linux-3.5/all: make -C $(KDIR) M=$(PWD) modules//调用内核编译时的makefile文件,便宜当前文件夹下的文件clean: rm -f *.o *.mod.o *.mod.c *.symvers *.markers *.order
2.1.2编译方法
[root@localhost 001]# makemake -C /root/workdir/linux-3.5/ M=/rootfs/root/driver/001 modulesmake[1]: Entering directory `/root/workdir/linux-3.5' CC [M] /rootfs/root/driver/001/module_001.o Building modules, stage 2. MODPOST 1 modules CC /rootfs/root/driver/001/module_001.mod.o LD [M] /rootfs/root/driver/001/module_001.komake[1]: Leaving directory `/root/workdir/linux-3.5'
2.2 加载模块
[root@TXM 001]#insmod /root/driver/001/module_001.ko[ 113.885000] this is a init of my first module !
2.3 卸载模块
[root@TXM /]#rmmod /root/driver/001/module_001.ko[ 126.075000] this is a exit of my first module !
三 模块参数
与c语言函数一样,模块也可以有函数
3.1 c语言主函数的参数形式
int main(int argc,char *argv[],char **envarg)
3.2 linux内核模块参数形式
//使用特定的函数向模块接口函数加载参数module_param(num, int, 0644); //num传入参数,int参数类型,0644 参数权限(与文件权限一样)
参数类型有:
int
char
uint
charp
long
short
bool
//向模块接口函数传入数组module_param_array(a, int,&num, 0644);//a数组,int类型,num 个数(系统自动生成,一定加 & ),0644权限
例:
#include <linux/kernel.h>#include <linux/module.h>int num;int a[10];module_param(num,int,0644);module_param_array(a, int,&num, 0644);static int __init module_002_init(void){ int i; printk("this is a init of my second module !\n"); printk("num = %d\n",num); for(i=0;i<num;i++) printk("%d\n",a[i]); return 0;}static void __exit module_002_exit(void){ printk("this is a exit of my second module !\n");}module_init(module_002_init );module_exit(module_002_exit);MODULE_LICENSE("GPL");
有参数时加载内核模块的方法:
[root@TXM 002]# insmod module_002.ko a=1,2,3[ 4504.475000] this is a init of my second module ![ 4504.475000] num = 3[ 4504.475000] 1[ 4504.475000] 2[ 4504.475000] 3
四 多模块同时编译
4.1 程序
模块1:
#include <linux/kernel.h>#include <linux/module.h>#include "print.h"int num;int a[10];module_param(num,int,0644);module_param_array(a, int,&num, 0644);static int __init module_001_init(void){ printk("this is a init of my first module !\n"); printk("num = %d\n",num); print_me(num,a); return 0;}void print_me(int num,int *a){ int i; for(i=0;i<num;i++) printk("%d\n",a[i]);}EXPORT_SYMBOL(print_me);static void __exit module_001_exit(void){ printk("this is a exit of my first module !\n");}module_init(module_001_init );module_exit(module_001_exit);MODULE_LICENSE("GPL");
模块2:
#include <linux/kernel.h>#include <linux/module.h>#include "print.h"int num;int a[10];module_param_array(a, int,&num,0644);static int __init tiny4412_hello_module_init(void){ printk("Hello, Tiny4412 module is installed !\n"); print_me(num,a); return 0;}static void __exit tiny4412_hello_module_cleanup(void){ printk("Good-bye, Tiny4412 module was removed!\n");}module_init(tiny4412_hello_module_init);module_exit(tiny4412_hello_module_cleanup);DULE_LICENSE("GPL");
Makefile文件:
obj-m += module_002.o module_003.oKDIR:=/root/workdir/linux-3.5/all: make -C $(KDIR) M=$(PWD) modules rm -f *.o *.mod.o *.mod.c *.symvers *.markers *.orderclean: rm -f *.o *.mod.o *.mod.c *.symvers *.markers *.order
4.2 编译结果
[root@localhost 002]# makemake -C /root/workdir/linux-3.5/ M=/rootfs/root/driver/002 modulesmake[1]: Entering directory `/root/workdir/linux-3.5' CC [M] /rootfs/root/driver/002/module_002.o CC [M] /rootfs/root/driver/002/module_003.o Building modules, stage 2. MODPOST 2 modules CC /rootfs/root/driver/002/module_002.mod.o LD [M] /rootfs/root/driver/002/module_002.ko CC /rootfs/root/driver/002/module_003.mod.o LD [M] /rootfs/root/driver/002/module_003.komake[1]: Leaving directory `/root/workdir/linux-3.5'rm -f *.o *.mod.o *.mod.c *.symvers *.markers *.order
4.3 加载卸载
[root@TXM 002]# insmod module_003.ko a=1,2,3[ 4485.560000] module_003: Unknown symbol print_me (err 0)insmod: can't insert 'module_003.ko': unknown symbol in module, or unknown parameter[root@TXM 002]# insmod module_003.ko[ 4495.560000] module_003: Unknown symbol print_me (err 0)insmod: can't insert 'module_003.ko': unknown symbol in module, or unknown parameter
可见先加载 module_003 会出错,因为没有函数 print_me
[root@TXM 002]# insmod module_002.ko a=1,2,3[ 6160.900000] this is a init of my first module ![ 6160.900000] num = 3[ 6160.900000] 1[ 6160.900000] 2[ 6160.900000] 3[root@TXM 002]# insmod module_003.ko a=1,2,3[ 6166.995000] Hello, Tiny4412 module is installed ![ 6166.995000] 1[ 6166.995000] 2[ 6166.995000] 3
[root@TXM 002]# rmmod module_002.kormmod: can't unload 'module_002': Resource temporarily unavailable[root@TXM 002]# rmmod module_003.ko[ 6189.220000] Good-bye, Tiny4412 module was removed![root@TXM 002]# rmmod module_002.ko[ 6196.330000] this is a exit of my first module !
由上面运行结果可以看出,如果先卸载 module_002.ko 会出错,无法卸载,因为 module_003.ko 正在使用。
五 多文件编译成一个模块
5.1 程序
主函数
#include <linux/kernel.h>#include <linux/module.h>#include "print.h"int num;int a[10];module_param_array(a, int,&num, 0644);static int __init module_001_init(void){ printk("this is a init of my first module !\n"); printk("num = %d\n",num); print_me(num,a); return 0;}static void __exit module_001_exit(void){ printk("this is a exit of my first module !\n");}module_init(module_001_init );module_exit(module_001_exit);MOD`LE_LICENSE("GPL");
子函数
#include "print.h"void print_me(int num,int *a){ int i; for(i=0;i<num;i++) printk("%d\n",a[i]);}
Makefile文件
obj-m += module_004_1.o/* module_004_1.o相当于打包生成的文件 module_004.o & print.o 是依赖的文件*/module_004_1-objs:=module_004.o print.o#KDIR:=/lib/modules/$(shell uname -r)/buildKDIR:=/root/workdir/linux-3.5/all: make -C $(KDIR) M=$(PWD) modules rm -f *.o *.mod.o *.mod.c *.symvers *.markers *.orderclean: rm -f *.o *.mod.o *.mod.c *.symvers *.markers *.order
5.2 编译
[root@localhost 003]# makemake -C /root/workdir/linux-3.5/ M=/rootfs/root/driver/003 modulesmake[1]: Entering directory `/root/workdir/linux-3.5' CC [M] /rootfs/root/driver/003/module_004.o CC [M] /rootfs/root/driver/003/print.o LD [M] /rootfs/root/driver/003/module_004_1.o Building modules, stage 2. MODPOST 1 modules CC /rootfs/root/driver/003/module_004_1.mod.o LD [M] /rootfs/root/driver/003/module_004_1.komake[1]: Leaving directory `/root/workdir/linux-3.5'rm -f *.o *.mod.o *.mod.c *.symver *.markers *.order
5.3 挂载卸载
[root@TXM 003]# insmod module_004_1.ko a=1,2,3[ 9760.095000] this is a init of my first module ![ 9760.095000] num = 3[ 9760.095000] 1[ 9760.095000] 2[ 9760.095000] 3[root@TXM 003]# rmmod module_004_1.ko [10228.120000] this is a exit of my first module ![root@TXM 003]#
阅读全文
0 0
- linux内核模块编写方法
- 编写Linux内核模块
- linux内核模块编写
- 编写Linux内核模块
- linux 内核模块编写
- Linux内核模块的编写方法和技巧
- 编写自定义Linux内核模块
- 初学编写linux内核模块
- 编写自定义Linux内核模块
- 初学编写linux内核模块
- linux内核模块的编写
- Linux内核模块和驱动的编写
- linux内核模块和驱动程序的编写
- Linux内核驱动模块编写(Hello,World)
- 学习Linux内核模块编写总结
- Linux内核驱动模块编写(Hello,World)
- 编写一个简单的linux内核模块
- Linux最简单内核模块编写
- short s1 = 1; s1 = s1 + 1; short s1 = 1; s1 += 1;
- Java 读取Excel表格数据日期类型转换
- 通过分析CircleImageView掌握自定义View流程
- JS动态创建form表单提交参数
- DVP interface CAM500B DEBIAN MJPG-STREAMER
- linux内核模块编写方法
- spring配置datasource数据源的三种方式
- Golang GBK转UTF-8
- meta标签及其含义大全
- 花了 4 个月整理了 50 篇 Android 干货文章
- Struts2日期转换器
- 文章标题
- Framework制作流程简介
- 【数据结构与算法】基数排序