第11单元 驱动程序原理与开发.ppt

  1. 1、本文档共47页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第11单元 驱动程序原理与开发

Lsmod 即list modules,对每行而言,第一列是模块名称;第二列是模块大小;第三列是用量计数。lsmod命令用来列出当前系统加载的模块,同时也可以当作察看硬 件浏览器。从以上列表我们可以看到那些设备的驱动程序已经加载。 如果后面为unused,则表示该模块当前没在使用。 如果后面有autoclean,则该 模块可以被rmmod -a命令自动清洗。rmmod -a命令会将目前有autoclean的模块卸载,如果这时候某个模块未被使用,则将该模块标记为autoclean。 以上是lsmod命令显示的当前内核已经加载的模块和驱动。以下面行为例: scsi_mod 130637 6 qla2xxx,scsi _transport_fc,mptspi, mptscsih, scsi_transport_spi,sd_mod 第1列:表示模块的名称,如scsi_mod表示scsi模块。 第2列:表示模块的大小,如130637表示scsi_mod模块的大小为130637字节。 第3列:表示依赖模块的个数,如6表示有6个模块依赖scsi_mod模块。 第4列:表示依赖模块的内容,如qla2xxx表示Qlogic FC HBA光纤HBA卡模块。 通常在使用lsmod命令时,都会采用类似lsmod|grep -i ext3这样的命令来查询当前系统是否加载了某些模块。 Eg:DA实验: insmod da.o ; CAN实验: insmod can.o * 在设备完成注册并创建文件系统节点后,用户写的应用程序就可以调用read/write函数对该设备进行一定的操作,而驱动程序就是实现读写这些操作的。 * init_module是默认的模块的入口,如果你想指定其他的函数作为模块的入口就需要 module_init函数来指定,比如 module_init (your_func); 其中your_func是你编写的一个函数的名称. __init : linux中把一些启动及初始化时候用的数据用__init标识,然后在适当的时候把它们释放,回收内存。 说到这个__init,就不能不说module_init,subsys_initcall。 就像你写C程序需要包含C库的头文件那样,Linux内核编程也需要包含Kernel头文件,大多的Linux驱动程序需要包含下面三个头文件: #include linux/init.h #include linux/module.h #include linux/kernel.h 其中,init.h 定义了驱动的初始化和退出相关的函数,kernel.h 定义了经常用到的函数原型及宏定义,module.h 定义了内核模块相关的函数、变量及宏。 几乎每个linux驱动都有个module_init(与module_exit的定义在Init.h (/include/linux) 中)。没错,驱动的加载就靠它。为什么需要这样一个宏?原因是按照一般的编程想法,各部分的初始化函数会在一个固定的函数里调用比如: void init(void) { init_a(); init_b(); } 如果再加入一个初始化函数呢,那么在init_b()后面再加一行:init_c();这样确实能完成我们的功能,但这样有一定的问题,就是不能独立的添加初始化函数,每次添加一个新的函数都要修改init函数。可以采用另一种方式来处理这个问题,只要用一个宏来修饰一下: void init_a(void) { } __initlist(init_a, 1); 它是怎么样通过这个宏来实现初始化函数列表的呢?先来看__initlist的定义: #define __init __attribute__((unused, __section__(.initlist))) #define __initlist(fn, lvl) / static initlist_t __init_##fn __init = { / magic: INIT_MAGIC, / callback: fn, / level: lvl } 请注意:__section__(.initlist),这个属性起什么作用呢?它告诉连接器这个变量存放在.initlist区段,如果所有的初始化函数都是用这个宏,那么每个函数会有对应的一个initlist_t结构体变量存放在.initlist区段,也就是说我们可以在.initlist区段找到所有初始化函数的指针。怎么找到.initlist区段的地址呢? extern u32 __initlist_start; extern u32 __initlist_end; 这两个变量起作用了,__initlist_start是.ini

文档评论(0)

dajuhyy + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档