文章目录
1.模块参数
作用:根据不同应用场合给内核模块传递不同参数,提高内核的灵活性
- 定义一个常见变量
- 使用module_param宏将传参值赋值给变量
module_param(name, type, perm)
- name:参数名
- type:参数类型,如int,byte,bool,char
- perm:读写权限
- 不允许设置可执行权限
- 在“/sys/module/模块名/parameters”目录下,会生成该参数对应的文件名
1.1 代码示例
module_param.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
static int itype=0;
module_param(itype,int,0);
static bool btype=0;
module_param(btype,bool,0644);
static char ctype=0;
module_param(ctype,byte,0);
static char *stype=0;
module_param(stype,charp,0644);
static int __init param_init(void)
{
printk(KERN_ALERT "param init!\n");
printk(KERN_ALERT "itype=%d\n",itype);
printk(KERN_ALERT "btype=%d\n",btype);
printk(KERN_ALERT "ctype=%d\n",ctype);
printk(KERN_ALERT "stype=%s\n",stype);
return 0;
}
static void __exit param_exit(void)
{
printk(KERN_ALERT "module exit!\n");
}
module_init(param_init);
module_exit(param_exit);
MODULE_LICENSE("GPL2");
MODULE_AUTHOR("embedfire ");
MODULE_DESCRIPTION("module_param");
MODULE_ALIAS("module_param");
Makefile:
KERNELDIR := /home/klz/linux/linux-4.1.15
CURRENT_PATH := $(shell pwd)
obj-m := module_param.o
build: kernel_modules
kernel_modules:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
copy:
sudo cp *.ko /home/klz/linux/nfs/rootfs/lib/modules/4.1.15
clean:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
结果为:
1.2 查看生成的文件名
cd sys/module/模块名/parameters
2.符号共享
内核模块可以共享导出的符号表
- 变量共享
- 函数共享
EXPORT_SYMBOL(sym)
- sym:变量名或者函数名
2.1 查看符号表
cat /proc/kallsyms | grep xxx
2.2 代码示例
module_param.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
static int itype=0;
module_param(itype,int,0);
static bool btype=0;
module_param(btype,bool,0644);
static char ctype=0;
module_param(ctype,byte,0);
static char *stype=0;
module_param(stype,charp,0644);
static int __init param_init(void)
{
printk(KERN_ALERT "param init!\n");
printk(KERN_ALERT "itype=%d\n",itype);
printk(KERN_ALERT "btype=%d\n",btype);
printk(KERN_ALERT "ctype=%d\n",ctype);
printk(KERN_ALERT "stype=%s\n",stype);
return 0;
}
static void __exit param_exit(void)
{
printk(KERN_ALERT "module exit!\n");
}
EXPORT_SYMBOL(itype);
int my_add(int a, int b)
{
return a+b;
}
EXPORT_SYMBOL(my_add);
int my_sub(int a, int b)
{
return a-b;
}
EXPORT_SYMBOL(my_sub);
module_init(param_init);
module_exit(param_exit);
MODULE_LICENSE("GPL2");
MODULE_AUTHOR("embedfire ");
MODULE_DESCRIPTION("module_param");
MODULE_ALIAS("module_param");
calculation.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include "calculation.h"
static int __init calculation_init(void)
{
printk(KERN_ALERT "calculation init!\n");
printk(KERN_ALERT "itype+1 = %d, itype-1 = %d\n", my_add(itype,1), my_sub(itype,1));
return 0;
}
static void __exit calculation_exit(void)
{
printk(KERN_ALERT "calculation exit!\n");
}
module_init(calculation_init);
module_exit(calculation_exit);
MODULE_LICENSE("GPL2");
MODULE_AUTHOR("embedfire ");
MODULE_DESCRIPTION("calculation module");
MODULE_ALIAS("calculation_module");
calculation.h
#ifndef __CALCULATION_H__
#define __CALCULATION_H__
extern int itype;
int my_add(int a, int b);
int my_sub(int a, int b);
#endif
2.3 Makefile修改
- 有依赖关系的模块,放在一起进行编译
- clean伪目标增加清除共享文件夹指令
Makefile
KERNEL_DIR=/home/pi/build
ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH CROSS_COMPILE
obj-m := module_param.o calculation.o
all:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules
.PHONE:clean copy
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean
sudo rm /home/embedfire/workdir/*.ko
copy:
sudo cp *.ko /home/embedfire/workdir
2.4 模块手动加载卸载
- 加载时,必须先加载相关依赖模块
- 卸载时,顺序相反
2.4.1 模块加载
从代码可只calculation.ko依赖于module_params.ko,所以需要先加载module_params.ko,否则会出现下面的错误
2.4.2 模块卸载
先卸载本模块,再卸载依赖模块,不然会提示其他模块正在使用
卸载错误:
正确卸载:
2.5 模块自动加载卸载
条件:所有内核模块统一放到"/lib/modules/内核版本"目录下
2.5.1 模块加载
-
建立模块依赖关系:这里会分析各个模块的依赖关系
depmod -a 或者depmod
-
查看模块依赖关系
cat /lib/modules/内核版本/modules.dep | grep 模块名字
从图中可以知道calculation.ko
依赖于module_param.ko
-
加载模块及其依赖模块
modprobe xxx
2.5.1 模块卸载
-
卸载模块及其依赖模块
modprobe -r xxx