第2部分第4次课linux26内核模块设计_第1页
第2部分第4次课linux26内核模块设计_第2页
第2部分第4次课linux26内核模块设计_第3页
第2部分第4次课linux26内核模块设计_第4页
第2部分第4次课linux26内核模块设计_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

嵌入式Linux

内核体系架构李超lichao-runing@163.coARTONE模块机制1.构建和运行驱动模块模块概念

Linux内核是一个整体结构,因此向内核添加任何东西,或者删除某些功能,都十分困难。为了解决这个问题引入了模块机制。从而可以动态的想内核中添加或者删除模块。

模块和应用程序的区别 一个应用程序从头到尾完成一个任务;而模块是为以后处理某些请求注册自己应用程序在用户空间;而模块加载后位于内核空间构建和运行驱动模块l构建和运行驱动模块structmodule{ unsignedlongsize_of_struct;/*==sizeof(module)*/ structmodule*next; constchar*name;int(*init)(void); void(*cleanup)(void);……}构建和运行驱动模块intinit_module():这个函数在模块插入内核时启动,在内核中注册一定的功能函数,或者用它的代码代替内核中某些函数的内容(估计这些函数是空的)。intcleanup_module():当内核模块卸载时调用,它能将模块从内核中清除。构建和运行驱动模块编写模块实例#include"linux/kernel.h"#include“linux/module.h"/*hello.c--amoduleprogramm*/intinit_module(){printk("helloworld!\n');printk("Ihaveruninginakernermod@!!\n");return0;}/*thedistoryfunction*/intcleanup_module(){printk("Iwillshutdownmyselfinkernerlmod/n)";retutn0;}

编译gcc-Wall-DMODULE-D__KERNEL__-DLinux–I/usr/src/linux-2.4.20-8/include–c–ohello.ohello.c`加载$insmodhello.ohelloworld!Iwillshutdownmyselfinkernerlmod$lsmodhello(unused)….$rmmodIwillshutdownmyselfinkernerlmod模块编译参数__KERNEL__——这个标志告诉头文件此代码将在内核模块中运行,而不是作为用户进程。_MODULE——这个标志告诉头文件要给出适当的内核模块的定义。 LINUX——从技术上讲,这个标志不是必要的。但是,如果你希望写一个比较正规的内核模块,在多个操作系统上编译,这个标志将会使你感到方便。它可以允许你在独立于操作系统的部分进行常规的编译。

内核模块处理相关命令insmod:它依赖于kernel/modulec.c中定义的几个系统调用。sys_create_module为装载模块分配内存(这些内存是由vmalloc分配的)系统调用get_kernel_syms返回内核符号表sys_init_module将可重定位目标码复制到内核空间并调用模块的初始化函数。内核模块处理相关命令lsmodlsmod就是通过/proc/modules文件获取系统中所有的模块,然后列出来内核模块处理相关命令rmmod的使用将已经插入的模块从内核中移出,rmmod程序自动运行在cleanup_module()函数中定义的过程modprobe的使用modprobe能够挂载、列出、卸载模块常用的功能就是挂载模块,在挂载模块时,会将该模块依赖的模块同时被加载。modprobe模块名kerneld守护进程目的:为了方便用户加载和卸载模块,并且避免把不再使用的驱动程序继续保留在内核中,Linux提供了对模块的自动加载和卸载支持Kerneld进程通过sysVIPC和内核通信,内核向kerneld发送需要装载的模块信息,然后kerneld调用modprobe查找这个模块,并且将该模块加载版本相关性要时刻牢记,对于想连编的每一个不同版本的内核,模块都要相应地编译一次。每个模块都定义了一个称为kernel_version的符号,insmod检查这个符号是否与当前内核版本号匹配。较新的内核已在<linux/module.h>中替你定义了这个符号

如果模块是由多个源文件组成的,只能有一个源文件包含了<linux/module.h>内核符号表这张表包含了实现模块化设备驱动程序所需的全局内核项――函数和变量。可以从文件/proc/ksyms中以文本的方式读取这个公开符号表当你的模块被加载时,你声明的任何全局符号都成为内核符号表的一部分,你可以从文件/proc/ksyms或命令ksyms的结果了解这一点。内核导出符号表在Linux中当一个模块被装载后,会被动态的连接到内核中,按照规定,只有导出的内核函数和数据才可以被其它模块调用。而没有导出的函数和数据是不可以被其它模块使用所有模块导出的函数及变量都会存放在公共内核符号表中,该表包含了所有全局内核项的地址通常情况下,模块只需实现自己的功能,而不需导出任何符号导出宏EXPORT_SYMBOL(name)EXPORT_SYMBOL_GPL(name)init_module中的错误处理

如果你注册时发生什么错误,你必须取消失败前所有已完成的注册。

建议用goto语句处理错误恢复

在Linux内核里,错误编码是一个负值,在<linux/errno.h>中定义。如果你不使用其他函数返回的错误编码而要生成自己的,你应该包含<linux/errno.h>,这样就可以使用诸如-ENODEV,-ENOMEM之类的符号值。总是返回相应的错误编码是种非常好的习惯,因为这样一来用户程序就利用perror或相似的方法把它们转换成有意义的字符串了。模块计数通过3个宏来维护使用计数:MOD_INC_USE_COUNT 当前模块计数加1。MOD_DEC_USE_COUNT 计数减1。MOD_IN_USE 计数非0时返回真。这些宏都定义在<linux/module.h>中,它们都操作不该有程序员直接访问的内部数据结构。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论