Linux内核模块开发

xiaoxiao2021-02-28  5

一、内核模块基础 1.1 什么是内核模块 Linux内核的整体结构非常庞大,其包含的组件也非常 多,如何使用这些组件呢, 方法1:把所有的组件都编 方法1:把所有的组件都编 译进内核文件,即:zImage或bzImage,但这样会导 致一个问题:占用内存过多. 有没有一种机制能让内核文件本身并不包含某组件,而 是在该组件需要被使用的时候,动态地添加到正在运行 的内核中呢? 1.2 内核模块特点 模块本身并 不被编译进内核文件 (zImage或者bzImage) ②可以更具需求, 在内核运行期间动态的安装或卸载 1.3 内核安装与卸载 安装 insmod  例:insmod /hoem/dnw_usb.ko 卸载rmmod  例:rmmod dnw_usb 查看 lsmod 例:lsmod 二、内核模块设计 2.1 内核的 三要素: 头文件:linux/init.h linux/module.h insmod,运行模块入口:module_init(); rmmod,运行模块退出:module_exit(); 2.2 内核的思维导图 2.3 内核的helloworld编写 #include <linux/init.h> #include <linux/module.h> static int hello_init(void) {     printk(KERN_WARNING"Hello, world !\n");     return 0; } static void hello_exit(void) {     printk(KERN_INFO "Goodbye, world\n"); }  module_init(hello_init); module_exit(hello_exit); printk 日志级别一共有8个级别,printk的日志级别定义如下(在 include/linux/kernel.h 中): #define KERN_EMERG 0/*紧急事件消息,系统崩溃之前提示,表示系统不可用*/ #define KERN_ALERT 1/*报告消息,表示必须立即采取措施*/ #define KERN_CRIT 2/*临界条件,通常涉及严重的硬件或软件操作失败*/ #define KERN_ERR 3/*错误条件,驱动程序常用KERN_ERR来报告硬件的错误*/ #define KERN_WARNING 4/*警告条件,对可能出现问题的情况进行警告*/ #define KERN_NOTICE 5/*正常但又重要的条件,用于提醒*/ #define KERN_INFO 6/*提示信息,如驱动程序启动时,打印硬件信息*/ #define KERN_DEBUG 7/*调试级别的消息*/ 2.4 内核Makefile编写 Makefile obj-m := helloworld.o                              //默认使用obj-m的形式 #hello-objs := file1.o file2.o file3.o             //这个可以分模块的方式 KDIR := /home/doctmp/part4/linux-tq2440            //设置tq2440的内核目录 all:     make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm    //-C 表明使用的内核目录  M表示需要编译的目录(PWD大写!) modules:make modules (编译内核)后面用交叉工具链 clean:     rm -f *.o *.ko *.order *.symvers *.mod.c            //设置清除指令 三、内核模块可选信息 3.1 模块申明 1、 MODULE_LICENSE (”遵守的协议”) 申明该模块遵守的许可证协议,如:“GPL“、”GPL v2“等 2、 MODULE_AUTHOR (“作者”) 申明模块的作者 3、 MODULE_DESCRIPTION (“模块的功能描述") 申明模块的功能 4、 MODULE_VERSION ("V1.0") 申明模块的版本 3.2 模块参数 在应用程序中 int main(int argc, char** argv), argc表示命令行输入的参数个数,argv中保存输入的参数。 同理: 同理: 通过宏 module_param 指定保存模块参数的变量。模块参数 用于在加载模块时传递参数给模块。 module_param(name,type,perm); name:变量的名称 type:变量类型,bool:布尔型 int:整型 charp:字符串型 perm是访问权限。 S_IRUGO:读权限 S_IWUSR:写权限 例: nt a = 3; char *st; module_param(a,int, S_IRUGO); module_param(st,charp, S_IRUGO); 3.3 符号输出 内核符号的导出使用宏 EXPORT_SYMBOL (符号名) EXPORT_SYMBOL_GPL (符号名) 说明: 其中EXPORT_SYMBOL_GPL只能用于包含GPL许可证的模块。 再写一个add.c,修改helloworld调用add()函数。 #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("GPL"); int add(int a, int b) {     return a+b; } static int add_init(void) {     return 0; } static void add_exit(void) {     printk(KERN_WARNING"add_exit"); } EXPORT_SYMBOL(add); module_init(add_init); module_exit(add_exit); 如果不加EXPORT_SYMBOL的话,会出现以下错误: # insmod add.ko # insmod helloworld.ko helloworld: Unknown symbol add insmod: cannot insert 'helloworld.ko': unknown symbol in module or invalid parameter 尽管加上extern表示外部引用,最后依然不能完成加载,哪怕顺序一致。加上export_symbol后就能让helloworld使用了。 <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script> 阅读(64) | 评论(0) | 转发(0) | 0

上一篇:根文件系统制作

下一篇:Linux内核子系统

相关热门文章 SHTML是什么_SSI有什么用...查看linux中某个端口(port)...卡尔曼滤波的原理说明...shell中字符串操作关于java中的“错误:找不到或... 给主人留下些什么吧!~~ 评论热议
转载请注明原文地址: https://www.6miu.com/read-450202.html

最新回复(0)