- 1、本文档共20页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
嵌入式Linux内核体系架构 李超 lichao-runing@163.comPART ONE 模块机制 1.构建和运行驱动模块 模块概念 Linux内核是一个整体结构,因此向内核添加任何东西,或者删除某些功能,都十分困难。为了解决这个问题引入了模块机制。从而可以动态的想内核中添加或者删除模块。 模块和应用程序的区别 一个应用程序从头到尾完成一个任务;而模块是为以后处理某些请求注册自己 应用程序在用户空间;而模块加载后位于内核空间 构建和运行驱动模块 l 构建和运行驱动模块 struct module { unsigned long size_of_struct; /* == sizeof(module) */ struct module *next; const char *name; int (*init)(void); void (*cleanup)(void); …… } 构建和运行驱动模块 int init_module(): 这个函数在模块插入内核时启动,在内核中注册一定的功能函数,或者用它的代码代替内核中某些函数的内容(估计这些函数是空的)。 int cleanup_module():当内核模块卸载时调用,它能将模块从内核中清除。 构建和运行驱动模块 编写模块实例 模块编译参数 __KERNEL__ ——这个标志告诉头文件此代码将在内核模块中运行,而不是作为用户进程。 _MODULE ——这个标志告诉头文件要给出适当的内核模块的定义。 LINUX——从技术上讲,这个标志不是必要的。但是,如果你希望写一个比较正规的内核模块,在多个操作系统上编译,这个标志将会使你感到方便。它可以允许你在独立于操作系统的部分进行常规的编译。 内核模块处理相关命令 insmod: 它依赖于kernel/modulec.c中定义的几个系统调用。 sys_create_module为装载模块分配内存(这些内存是由vmalloc分配的) 系统调用get_kernel_syms返回内核符号表 sys_init_module将可重定位目标码复制到内核空间并调用模块的初始化函数。 内核模块处理相关命令 lsmod lsmod就是通过/proc/modules文件获取系统中所有的模块,然后列出来 内核模块处理相关命令 rmmod的使用 将已经插入的模块从内核中移出,rmmod程序自动运行在cleanup_module()函数中定义的过程 modprobe的使用 modprobe能够挂载、列出、卸载模块 常用的功能就是挂载模块,在挂载模块时,会将该模块依赖的模块同时被加载。 modprobe 模块名 kerneld守护进程 目的:为了方便用户加载和卸载模块,并且避免 把不再使用的驱动程序继续保留在内核中,Linux提供了对模块的自动加载和卸载支持 Kerneld进程通过sysV IPC和内核通信,内核向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中定义。如果你不使用其他函数返回的错误编码而要生成自己的,你应该包含
文档评论(0)