装修网站怎么做的,网站关键词分布情况,做调查问卷网站,wordpress无法连接到ftp服务器1.模块化
1.1.模块化的基本概念#xff1a;
模块化是指将特定的功能或组件独立出来#xff0c;以便于开发、测试和维护。在Linux设备驱动中#xff0c;模块化允许将驱动程序作为内核模块动态加载到系统中#xff0c;从而提高了系统的灵活性和可扩展性。
1.2.Linux内核模…1.模块化
1.1.模块化的基本概念
模块化是指将特定的功能或组件独立出来以便于开发、测试和维护。在Linux设备驱动中模块化允许将驱动程序作为内核模块动态加载到系统中从而提高了系统的灵活性和可扩展性。
1.2.Linux内核模块的特点
动态加载和卸载内核模块可以在系统运行时被动态加载或卸载而无需重新编译整个内核。更好的扩展性系统可以根据需要加载或卸载模块从而避免资源的浪费。易于管理和维护模块化的设计使得驱动程序的开发、测试和部署更加便捷 1.3.模块化的好处
独立模块之间可以独立开发。隔离驱动模块与内核隔离不需要改内核源码不然来一个需求改一次内核源码风险增加而且编译内核换内核都是相对麻烦当然使用ftp导入内核没什么。 1.4.驱动模块主要由以下几个部分组成
模块加载函数必须当通过insmod命令加载内核模块时模块的加载函数会自动被内核执行完成本模块相关初始化工作模块卸载函数必须当通过rmmod命令卸载模块时模块的卸载函数会自动被内核执行完成与模块加载函数相反的功能模块许可证声明必须模块许可证LICENCE声明描述内核模块的许可权限如果不声明LICENCE,模块被加载时将收到内核被污染的警告。大多数 模块参数可选模块参数是模块被加载的时候可以被传递给他的值它本身对应模块内部的全局变量 模块导出符号可选内核模块可以导出符号(symbol,对应于函数或变量)这样其他模块可以使用本模块中的变量或函数 模块作者等信息声明可选。
2.驱动模块的相应接口 module_init(xxx_init); //注册模块加载函数 module_exit(xxx_exit); //注册模块卸载函数 MODULE_LICENSE( GPL ) //添加模块 LICENSE 信息 MODULE_AUTHOR( 你的名字 ) //添加模块作者信息 module_param(name,type,perm) //给模块传递参数 参数 name用来接收参数的变量名 type参数的数据类型 perm指定参数访问权限。 module_param_named(name_out,name_in,type,perm) //给模块传递参数 参数 name_out在加载模块时参数的名字 name_in模块内部变量的名字 type 参数类型 perm 访问权限 MODULE_PARM_DESC(name,describe); //给模块里面参数的变量指定一个描述信息通过modinfo可以查看到 参数 name 变量名 describe描述信息的字符串 EXPORT_SYMBOL(name); //导出符号 EXPORT_SYMBOL_GPL(name); 参数类型 MODULE_LICENSE(GPL); // GPL 是指明了 这是GNU General Public License的任意版本 // “GPL v2” 是指明 这仅声明为GPL的第二版本 // GPL and addtional // Dual BSD/GPL // Dual MPL/GPL // Proprietary 私有的 注意除非你的模块显式地声明一个开源版本否则内核会默认你这是一个私有的模块(Proprietary)。 其他接口 MODULE_DESCRIPTION描述 // 对这个模块作一个简单的描述modinfo可以查看 MODULE_VERSION // 这个模块的版本 MODULE_ALIAS // 这个模块的别名 MODULE_DEVICE_TABLE // 告诉用户空间这个模块支持什么样的设备当系统检测到匹配这些ID设备时就可以自动加载这个模块 3.测试以及测试解释
3.1.模块化接口测试 该测试用例没有加模块协议运行会报“模块许可证“未指定”污染内核”所以该加还是加上。 3.2.参数传递
#include linux/init.h
#include linux/module.h
static unsigned int var0;
module_param(var,uint,0664);static char *string;
module_param(string,charp,0444);
MODULE_PARM_DESC(var, int value);
MODULE_PARM_DESC(string, str value);static int hello_init(void)
{printk(hello my drivce \r\n);printk(int value %u \r\n, var);printk(str value %s \r\n, string);return 0;
}
static void hello_exit(void)
{printk(hello_exit \r\n);printk(int value %u \r\n, var);printk(str value %s \r\n, string);return;
}MODULE_AUTHOR(seven);
MODULE_LICENSE(GPL);
module_init(hello_init);
module_exit(hello_exit);
MODULE_DESCRIPTION(module test.);
测试
加载驱动可以传递参数如insmod 01_module_test.ko stringseven var10这里初始化的时候不设置参数通过修改 /sys/module/01_module_test/parameters/变量名 这个文件去修改对应的值然后卸载程序的时候打印出来看看。 3.3.符号导出
a驱动代码a驱动导出符号给b驱动使用
#include linux/init.h
#include linux/module.h
static int global_var 100;
static void show(void)
{printk(a module show(): global_var %d \n,global_var);
}
static int hello_init(void)
{printk(a module export :global_var%d\n,global_var);return 0;
}
static void hello_exit(void)
{printk(hello_exit \n);return;
}EXPORT_SYMBOL(global_var);
EXPORT_SYMBOL(show);
MODULE_AUTHOR(seven);
MODULE_LICENSE(GPL);
module_init(hello_init);
module_exit(hello_exit);b驱动代码
#include linux/module.hextern int global_var;
extern void show(void);
static int hello_init(void)
{printk(module b: global_var %d\n,global_var);global_var--;show();printk(module b: global_var %d\n,global_var);global_var--;show();return 0;
}
static void hello_exit(void)
{printk(hello_exit \n);return;
}
MODULE_AUTHOR(seven);
MODULE_LICENSE(GPL);
module_init(hello_init);
module_exit(hello_exit);运行时候 3.3.1.b驱动的注意事项
b驱动编译需要依赖 a驱动的符号表Module.symvers),解决这种问题目前知道两种办法 方法1将a驱动下面的Module.symvers拷贝到b驱动构建目录下面再进行编译 方法2makefile里面加上KBUILD_EXTMOD构建a驱动的绝对路径 模块编译时寻找使用的符号
a.在本模块中符号表中寻找符号函数或变量实现b.在内核全局符号表中寻找c.在模块目录下的Module.symvers文件中寻找 参考
手把手教Linux驱动1-模块化编程_要求:掌握linux模块编程技术,了解linux驱动编程与编译。 内容: 第一步(必做):在li-CSDN博客
手把手教Linux驱动2-之模块参数和符号导出_linux 引用其他模块导出来的符号-CSDN博客 内核Module.symvers文件揭秘 - Linux内核编程 | 宅学部落 (zhaixue.cc)
Linux设备驱动的模块化之路-CSDN博客
linux 内核模块声明 MODULE_LICENSE_module liciense-CSDN博客