第二章--Linux内核与内核模块-Linux设备驱动程序-教学课件.ppt

上传人:可****阿 文档编号:73601432 上传时间:2023-02-20 格式:PPT 页数:51 大小:2.13MB
返回 下载 相关 举报
第二章--Linux内核与内核模块-Linux设备驱动程序-教学课件.ppt_第1页
第1页 / 共51页
第二章--Linux内核与内核模块-Linux设备驱动程序-教学课件.ppt_第2页
第2页 / 共51页
点击查看更多>>
资源描述

《第二章--Linux内核与内核模块-Linux设备驱动程序-教学课件.ppt》由会员分享,可在线阅读,更多相关《第二章--Linux内核与内核模块-Linux设备驱动程序-教学课件.ppt(51页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、设备驱动程序第二章 Linux内核与内核模块目录lLinux内核的组成l内核的编译及加载l内核模块的程序结构l模块加载和卸载函数l模块参数l导出符号l模块声明与描述l模块的使用计数l模块的编译l模块与GPL目录lLinux内核的组成l内核的编译及加载l内核模块的程序结构l模块加载和卸载函数l模块参数l导出符号l模块声明与描述l模块的使用计数l模块的编译l模块与GPLLinux内核源代码结构进程调度内存管理虚拟文件系统目录lLinux内核的组成l内核的编译及加载l内核模块的程序结构l模块加载和卸载函数l模块参数l导出符号l模块声明与描述l模块的使用计数l模块的编译l模块与GPL内核模块简介l什么

2、是模块?l从代码特征上来看,模块就是可完成一项独立功能的一组函数的集合。l从使用特征上来看,它在被需要时可以随时安装,而在不需要时又可以随时被卸载。l总之,模块是一个为内核或其他内核模块提供使用功能的代码块。l准确地说,模块就是一个已编译但未连接的可执行文件。lLinux是一个一体化内核,内核中各部件联系紧密,当因为某种原因需要增加、扩充时,用户必须对内核全部重新编译一次,所以,为了弥补这个缺点,Linux建立了模块机制。内核模块简介l从内核的角度看,模块所包含的代码段一旦被连接到内核,它就可以是内核的一部分,所以它也被叫做内核模块。l从用户角度看,模块是内核的一个外挂的配件,需要时可以将其连

3、接到内核上,以完成用户所要求的任务;不需要时可以将其删除。它给用户提供了扩充内核功能的手段。代码说明l Printk()是内核使用的函数。因为在内核中不能调用C库函数,所以在内核模块中必须使用由内核提供的相关函数。l这个最简单的内核模块只包含内核模块加载函数、卸载函数和对Dual BSD/GPL许可权限的声明以及一些描述信息。l编译它会产生hello.ko目标文件,通过insmod./hello.ko命令可以加载它,输出hello world enter。l通过rmmod hello命令可以卸载它,输出hello world exit。内核模块程序结构l一个Linux内核模块主要由以下几部分组

4、成:l模块加载函数(必须)l模块卸载函数(必须)l模块许可证声明(必须)l模块参数(可选)l模块导出符号(可选)l模块作者等信息声明(可选)模块加载函数lLinux内核模块加载函数一般以_ _init标识声明,典型的模块加载函数的形式:l模块加载函数必须以module_init(函数名)的形式被指定。它返回整型值,若初始化成功,应返回0;失败则返回错误编码。l在Linux内核中,所有标识为_ _init的函数在连接的时候都放在.init.text这个区段内,此外,所有的_ _init函数在.initcall.init区段中还保存了一份函数指针,在初始化时内核会通过这些函数指针调用这些_ _in

5、it函数,并在初始化完成后释放init区段。模块卸载函数lLinux内核模块加载函数一般以_ _exit标识声明,典型的模块卸载函数的形式:l模块卸载函数在模块卸载的时候运行,不返回任何值,必须以module_ _exit(函数名)的形式来指定。l和_ _init一样,_ _exit也可以使对应函数在运行完成后自动回收内存。模块加载和卸载函数l若模块加载函数注册了XXX,则模块卸载函数应该注销XXX。l若模块加载函数动态申请了内存,则模块卸载函数应释放内存。l若模块加载函数申请了硬件资源的占用,则模块卸载函数应释放这些硬件资源。l若模块加载函数开启了硬件,则卸载函数中一般要关闭硬件。目录lLi

6、nux内核的组成l内核的编译及加载l内核模块的程序结构l模块加载和卸载函数l模块参数l导出符号l模块声明与描述l模块的使用计数l模块的编译l模块与GPL模块参数l我们可以用module_param(参数名,参数类型,参数读/写权限)为模块定义一个参数。l在装载内核模块时,用户可以向模块传递参数,形式为insmode(或modprobe)模块名 参数名=参数值,如果不传递,参数将使用模块内定义的默认值。l模块也可以拥有参数数组,形式为module_param_array(数组名,数组类型,数组长,参数读/写权限)。运行insomd或modprobe命令时,应使用逗号分隔输入的数组元素。导出符号l

7、Linux2.6的/proc/kallsyms文件对应着内核符号表,它记录了符号以及符号所在的内存地址。l模块可以使用如下宏导出符号到内核符号表:l导出的符号将可以被其他模块使用,使用前声明下即可。目录lLinux内核的组成l内核的编译及加载l内核模块的程序结构l模块加载和卸载函数l模块参数l导出符号l模块声明与描述l模块的使用计数l模块的编译l模块与GPL模块声明与描述l在Linux内核模块中,我们可以使用MODULE_AUTHOR,MODULE_DESCRIPTION,MODULE_VERSION,MODULE_DEVICE_TABLE,MODULE_ALIAS分别声明模块的作者、描述、版

8、本、设备表和别名。模块的使用计数lLinux2.4内核中,模块自身通过MOD_INC_USE_COUNT,MOD_DEC_COUNT宏来管理自己被使用的计数。lLinux2.6内核提供了模块计数管理接口lInt try_module_get(struct module*module)函数用于增加模块使用计数。若返回0,表示调用失败,希望使用的模块没有被加载或正在被加载。lmodule_put(struct module*module)函数用于减少模块的使用计数。目录lLinux内核的组成l内核的编译及加载l内核模块的程序结构l模块加载和卸载函数l模块参数l导出符号l模块声明与描述l模块的使用计

9、数l模块的编译l模块与GPL目录lLinux内核的组成l内核的编译及加载l内核模块的程序结构l模块加载和卸载函数l模块参数l导出符号l模块声明与描述l模块的使用计数l模块的编译l模块与GPL模块与GPLl对于自己编写的驱动等内核代码,如果不编译为模块则无法绕开GPL,编译为模块后企业在产品中使用模块,则公司对外不再需要提供对应的源代码。l为了使公司产品所使用的Linux操作系统支持模块,需要完成如下工作:l在内核编译时应该选上“Enable loadable omdule support”,嵌入式产品一般不需要动态卸载模块,所以“可以卸载模块”不选,当然选了也没关系l将我们编译的内核模块.ko

10、文件放置在目标文件系统的相关目录中l产品的文件系统中应该包含了支持新内核的insmod、lsmod、rmmod等工具l在使用中用户可使用insmod命令手动加载模块,如insmod xxx.ko(如:insmod hello.ko)l但是一般而言,产品在启动过程中应该加载模块,在嵌入式Linux的启动过程中,加载企业自己的模块的最简单的方法是修改启动过程的rc脚本,增加insomd/xxx.ko这样的命令。模块与GPL目录lLinux内核的组成l内核的编译及加载l内核模块的程序结构l模块加载和卸载函数l模块参数l导出符号l模块声明与描述l模块的使用计数l模块的编译l模块与GPLLinux内核的

11、配置lLinux内核的配置系统由以下三部分组成:lMakefile:分布在Linux内核源代码中的makefile,定义Linux内核的编译规则。l配置文件Kconfig:给用户提供配置选择的功能。l配置工具:包括配置命令(make menuconfig)解释器和配置用户界面。Linux内核的配置lLinux内核的配置界面:Kconfigl菜单入口l大多数的内核配置选项都对应kconfig中的一个菜单入口,如:lConfig关键字定义新的配置选项,之后的几行定义了该配置选项的属性。配置选项的属性包括类型、数据范围、输入提示、依赖关系、帮助信息和默认值等。Kconfigl菜单结构l菜单入口在菜单

12、树结构中的位置可由两种方法决定。l所有处于menu和endmenu之间的菜单入口都会成为“network device support”的子菜单。而且,所有子菜单选项都会继承父菜单的依赖关系。l 通过分析依赖关系生成菜单结构。如果菜单选项在一定程度上依赖于前面的选项,它就能成为该选项的子菜单。如果父选项为N,则子选项不可见;如果为Y或M,则子选项可见。KconfigKconfigl使用make config/make menuconfig命令后,会生成一个.config配置文件(隐含在顶层makefile中),记录哪些部分被编译入内核,哪些部分被编译为内核模块。l运行make menuconf

13、ig命令时,配置工具首先分析与体系结构对应的/arc/xxx(arm)/kconfig文件(最顶层的kconfig目录)。Kconfig文件中除了本身包含一些与体系结构相关的配置项和配置菜单外,还通过source语句引入了一系列kconfig文件,而这些kconfig文件又可能再次通过source引入下一层的kconfig,配置工具依据这些kconfig包含的菜单和项目即可描绘出一个如图的分层结构。举例:source drivers/test/kconfigKconfigMakefilel目标定义l目标定义用来定义哪些内容要作为模块编译,哪些要编译并连接进内核。obj-y+=foo.o 表示要

14、由foo.c或foo.s文件编译得到foo.o并连接进内核,而obj-m则表示该文件要作为模块编译。除了y,m以外的obj-x形式的目标都不会被编译。l更常见的做法是根据.config文件的CONFIG_变量来决定文件的编译方式,如下:Makefilel多文件模块的定义l如果一个模块由多个文件组成,这时应采用模块名加-objs后缀或者-y后缀的形式来定义模块的组成文件。Makefilel目录层次的迭代:l当CONFIG_EXT2_FS的值为y或m时,将kbuild会把ext2目录列入向下迭代的目录中,具体ext2目录下的文件是要作为模块编译还是链入内核由ext2目录下的makefile文件的内

15、容决定。在Linux内核中新增程序的方法l在LINUX下加载程序(驱动程序也如此)可以采用动态和静态两种方式。l静态加载就是把程序直接编译到内核里,系统启动后可以直接调用。静态加载的缺点是调试起来比较麻烦,每次修改一个地方都要重新编译下载内核,效率较低。l动态加载利用了LINUX的module特性,可以在系统启动后用insmod命令把程序(.ko文件)添加上去,在不需要的时候用rmmod命令来卸载。l在台式机上一般采用动态加载的方式。在嵌入式产品里可以先用动态加载的方式来调试,调试完毕后再编译到内核里。静态加载l在Linux内核中增加程序需要完成以下三项工作:l将编写的源代码复制到Linux内

16、核源代码的相应目录。l在目录的Kconfig文件中增加新源代码对应项目的编译配置选项。l在目录的Makefile文件中增加对新源代码的编译条目。静态加载实例RTCl在linuxdriverschar目录中包含S3C2410处理器的RTC设备驱动程序源代码s3c2410-rtc.c。l在该目录的Kconfig配置文件中增加S3C2410_RTC的配置项目:config S3C2410_RTC bool “S3C2410 RTC Driver”depend on ARCH_s3c2410 help l上述Kconfig文件的这段脚本意味着只有在ARCH_s3c2410项目被配置的情况下,运行mak

17、e menuconfig时才会出现S3C2410_RTC配置项目,这个项目配置项目为布尔型(要么编译入内核,要么不编译,选项为“Y”或“N”),菜单上显示的字符串为“S3C2410 RTC Driver”,“help”后面的内容为帮助信息。静态加载实例RTC静态加载实例RTCl在目录的Makefile中建立一个关于S3C2410_RTC的编译脚本:obj-$(CONFIG_ S3C2410_RTC)+=s3c2410-rtc.ol如果S3C2410_RTC配置选项被选择为“Y”,即obj-$(CONFIG_ S3C2410_RTC)等同于obj-y,则编译s3c2410-rtc.c,直接会将生成的目标代码直接连接到内核。相反,选“N”时,则不编译s3c2410-rtc.c。Linux内核的引导lX86PC机上的Linux内核引导流程:Linux内核的引导lX86PC机上的Linux内核初始化:

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 生活常识

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁