欢迎来到冰点文库! | 帮助中心 分享价值,成长自我!
冰点文库
全部分类
  • 临时分类>
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • ImageVerifierCode 换一换
    首页 冰点文库 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    论Linux Kernel Module之设备驱动程序Word格式文档下载.docx

    • 资源ID:5822509       资源大小:33.10KB        全文页数:28页
    • 资源格式: DOCX        下载积分:1金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要1金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    论Linux Kernel Module之设备驱动程序Word格式文档下载.docx

    1、3.5设备的中断和轮询处理4设备驱动程序接口第4章Linux设备驱动程序的实现301PCI驱动程序实现的关键数据结构1. 1pci_driver结构1. 2pci_dev结构2. 写驱动程序的fuctoin问题2.1function的encode问题2.2function的export问题2.3两个常用function3设备驱动程序中的一些具体问题3. 1I/O Port3.2内存操作3.3中断处理4Realtek Fast Ethernet Driver rtl8139网卡驱动3个模块的改写4. 1设备指明模块4.2数据读写和控制信息模块4.3中断处理模块参考文献.25附录.26致谢28【摘

    2、 要】驱动程序编写方法。由Linux设备驱动程序编写方式着手,转而研究设备驱动程序的Kernel Module程序。在了解了Linux下的驱动设备类型之后,从Linux下设备驱动程序的功能,组成部分,结构,接口4个方面分析了设备驱动程的框架。在参看了许多的书籍和网络论坛的文章,资料,具体讨论了Linux下设备驱动程序的实现,具体研究了驱动程序的数据结构,function问题和编写程序时各个部分可能出现的难点,疑点问题。并根据Donald Becker 1999-2000年编写的Realtek Fast Ethernet Driver rtl8139网卡驱动Linux版(内核版本2.0.24)改

    3、写了其中的3个模块:设备指明模块,数据读写和控制信息模块与中断处理模块。【关键词】Kernel Linux内核Kernel Module Linux的内核模块Character Devices字符设备Block Devices块设备Funtion函数前言 Linux是最受欢迎的自由电脑操作系统内核。它是一个用C语言写成,符合POSIX标准的类Unix操作系统。Linux最早是由芬兰黑客 Linus Torvalds为尝试在英特尔x86架构上提供自由免费的类Unix操作系统而开发的。该计划开始于1991年, 从Linus Torvalds当时在Usenet新闻组comp.os.minix所登载了

    4、一分著名的贴子,标志了Linux计划的正式开始。在计划的早期有一些Minix 黑客提供了协助,而今天全球无数程序员正在为该计划无偿提供帮助。技术上说Linux是一个内核。“内核”指的是一个提供硬件抽象层、磁盘及文件系统控制、多任务等功能的系统软件。一个内核不是一套完整的操作系统。一套基于Linux内核的完整操作系统叫作Linux操作系统,或是GNU/Linux。今天Linux是一个一体化内核系统。设备驱动程序可以完全访问硬件。Linux内的设备驱动程序可以方便地以模块的形式设置,并在系统运行期间可直接装载或卸载。第1章 Linux设备驱动程序编写方式Linux下的设备驱动程序可以按照两种方式进

    5、行编译,一种是直接静态编译成内核的一部分,另一种则是编译成可以动态加载的模块。如果编译进内核的话,会增加内核的大小,还要改动内核的源文件,而且不能动态地卸载,不利于调试,所有推荐使用模块方式。 从本质上来讲,模块也是内核的一部分,它不同于普通的应用程序,不能调用位于用户态下的C或者C+库函数,而只能调用Linux内核提供的函数,在/proc/ksyms中可以查看到内核提供的所有函数。 module的出现是 Linux 的一大革新。有了 module 之后,写 device driver 不需要每次要测试 driver 就重新 compile kernel 一次。避免了很多的麻烦。Module

    6、允许我们动态的改变 kernel,加载 device driver,而且它也能缩短我们 driver development 的时间。 module就是模块。module 其实是一般的程序。但是它可以被动态载到 kernel 里成为 kernel的一部分。载到 kernel 里的 module 它具有跟 kernel 一样的权力。可以 access 任何 kernel 的 data structure。第2章 Linux下的驱动设备类型正文格式字符设备, Linux 最简单的设备,象文件一样访问。应用程序使用标准系统调用打开、读取、写和关闭,完全好像这个设备是一个普通文件一样。甚至连接一个 L

    7、inux 系统上网的 PPP 守护进程使用的 modem ,也是这样的。当字符设备初始化的时候,它的设备驱动程序向 Linux 核心登记,在 chrdevs 向量表增加一个 device_struct 数据结构条目。这个设备的主设备标识符(例如对于 tty 设备是 4 ),用作这个向量表的索引。一个设备的主设备标识符是固定的。 Chrdevs 向量表中的每一个条目,一个 device_struct 数据结构,包括两个元素:一个登记的设备驱动程序的名称的指针和一个指向一组文件操作的指针。这块文件操作本身位于这个设备的字符设备驱动程序中,每一个都处理特定的文件操作比如打开、读、写和关闭。 /pro

    8、c/devices 中字符设备的内容来自 chrdevs 向量表当代表一个字符设备(例如 /dev/cua0 )的字符特殊文件打开,核心必须做一些事情,从而去掉用正确的字符设备驱动程序的文件操作例程。和普通文件或目录一样,每一个设备特殊文件都用 VFS I 节点表达。这个字符特殊文件的 VFS inode (实际上所有的设备特殊文件)都包括设备的 major 和 minor 标识符。这个 VFS I 节点由底层的文件系统(例如 EXT2 ),在查找这个设备特殊文件的时候根据实际的文件系统创建。 每一个 VFS I 节点都联系着一组文件操作,依赖于 I 节点所代表的文件系统对象不同而不同。不管代

    9、表一个字符特殊文件的 VFS I 节点什么时候创建,它的文件操作被设置成字符设备的缺省操作。这只有一种文件操作: open 操作。当一个应用程序打开这个字符特殊文件的时候,通用的 open 文件操作使用设备的主设备标识符作为 chrdevs 向量表中的索引,取出这种特殊设备的文件操作块。它也建立描述这个字符特殊文件的 file 数据结构,让它的文件操作指向设备驱动程序中的操作。然后应用程序所有的文件系统操作都被映射到字符设备的文件操作。 块设备也支持象文件一样被访问。这种为打开的块特殊文件提供正确的文件操作组的机制和字符设备的十分相似。 Linux 用 blkdevs 向量表维护已经登记的块设

    10、备文件。它象 chrdevs 向量表一样,使用设备的主设备号作为索引。它的条目也是 device_struct 数据结构。和字符设备不同,块设备进行分类。 SCSI 是其中一类,而 IDE 是另一类。类向 Linux 核心登记并向核心提供文件操作。一种块设备类的设备驱动程序向这种类提供和类相关的接口。例如, SCSI 设备驱动程序必须向 SCSI 子系统提供接口,让 SCSI 子系统用来对核心提供这种设备的文件操作。 每一个块设备驱动程序必须提供普通的文件操作接口和对于 buffer cache 的接口。每一个块设备驱动程序填充 blk_dev 向量表中它的 blk_dev_struct 数据

    11、结构。这个向量表的索引还是设备的主设备号。这个 blk_dev_struct 数据结构包括一个请求例程的地址和一个指针,指向一个 request 数据结构的列表,每一个都表达 buffer cache 向设备读写一块数据的一个请求。 每一次 buffer cache 希望读写一块数据到或从一个登记的设备的时候它就在它的 blk_dev_struc 中增加一个 request 数据结构。图 8.2 显示了每一个 request 都有一个指针指向一个或多个 buffer_head 数据结构,每一个都是一个读写一块数据的请求。这个 buffer_head 数据结构被锁定( buffer cache

    12、),可能会有一个进程在等待这个缓冲区的阻塞进程完成。每一个 request 结构都是从一个静态表, all_request 表中分配的。如果这个 request 增加到一个空的 request 列表,就调用驱动程序的 request 函数处理这个 request 队列。否则,驱动程序只是简单地处理 request 队列中的每一个请求。 一旦设备驱动程序完成了一个请求,它必须把每一个 buffer_head 结构从 request 结构中删除,标记它们为最新的,然后解锁。对于 buffer_head 的解锁会唤醒任何正在等待这个阻塞操作完成的进程。这样的例子包括文件解析的时候:必须等待 EXT2

    13、 文件系统从包括这个文件系统的块设备上读取包括下一个 EXT2 目录条目的数据块,这个进程将会在将要包括目录条目的 buff_head 队列中睡眠,直到设备驱动程序唤醒它。这个 request 数据结构会被标记为空闲,可以被另一个块请求使用。 字符设备是以字节为单位逐个进行I/O操作的设备,在对字符设备发出读写请求时,实际的硬件I/O紧接着就发生了,一般来说字符设备中的缓存是可有可无的,而且也不支持随机访问。块设备则是利用一块系统内存作为缓冲区,当用户进程对设备进行读写请求时,驱动程序先查看缓冲区中的内容,如果缓冲区中的数据能满足用户的要求就返回相应的数据,否则就调用相应的请求函数来进行实际的

    14、I/O操作。块设备主要是针对磁盘等慢速设备设计的,其目的是避免耗费过多的CPU时间来等待操作的完成。一般说来,PCI卡通常都属于字符设备。第2章 Linux设备驱动程序的框架1.1 对设备初始化和释放1. 2把数据从内核传送到硬件和从硬件读取数据1. 3读取应用程序传送给设备文件的数据和回送应用程序请求的数据1.4检测和处理设备出现的错误.2设备驱动程序的组成部分2.1 自动配置和初始化子程序自动配置和初始化子程序,负责检测所要驱动的硬件设备是否存在和是否 能正常工作。如果该设备正常,则对这个设备及其相关的、设备驱动程序 需要的软件状态进行初始化。这部分驱动程序仅在初始化的时候被调用一 次。2

    15、.2 服务于I/O请求的子程序服务于I/O请求的子程序,又称为驱动程序的上半部分。调用这部分是由 于系统调用的结果。这部分程序在执行的时候,系统仍认为是和进行调用 的进程属于同一个进程,只是由用户态变成了核心态,具有进行此系统调 用的用户程序的运行环境,因此可以在其中调用sleep()等与进程运行环 境有关的函数。2.3 中断服务子程序中断服务子程序,又称为驱动程序的下半部分。在UNIX系统中,并不是 直接从中断向量表中调用设备驱动程序的中断服务子程序,而是由UNIX 系统来接收硬件中断,再由系统调用中断服务子程序。中断可以产生在任 何一个进程运行的时候,因此在中断服务程序被调用的时候,不能依

    16、赖于 任何进程的状态,也就不能调用任何与进程运行环境有关的函数。因为设 备驱动程序一般支持同一类型的若干设备,所以一般在系统调用中断服务 子程序的时候,都带有一个或多个参数,以唯一标识请求服务的设备。在系统内部,I/O设备的存取通过一组固定的入口点来进行,这组入口点是 由每个设备的设备驱动程序提供的。3.1 驱动程序注册与注销向系统增加一个驱动程序意味着要赋予它一个主设备号,这可以通过在驱动程序的初始化过程中调用register_chrdev( )或者register_blkdev( )来完成。而在关闭字符设备或者块设备时,则需要通过调用unregister_chrdev( )或unregis

    17、ter_blkdev( )从内核中注销设备,同时释放占用的主设备号。3.2 设备的打开与释放打开设备是通过调用file_operations结构中的函数open( )来完成的,它是驱动程序用来为今后的操作完成初始化准备工作的。在大部分驱动程序中,open( )通常需要完成下列工作:检查设备相关错误,如设备尚未准备好等。如果是第一次打开,则初始化硬件设备。识别次设备号,如果有必要则更新读写操作的当前位置指针f_ops。分配和填写要放在file-private_data里的数据结构。使用计数增1。释放设备是通过调用file_operations结构中的函数release( )来完成的,这个设备方法

    18、有时也被称为close( ),它的作用正好与open( )相反,通常要完成下列工作:使用计数减1。释放在file-private_data中分配的内存。如果使用计算为0,则关闭设备。3.3 设备的读写操作字符设备的读写操作相对比较简单,直接使用函数read( )和write( )就可以了。但如果是块设备的话,则需要调用函数block_read( )和block_write( )来进行数据读写,这两个函数将向设备请求表中增加读写请求,以便Linux内核可以对请求顺序进行优化。由于是对内存缓冲区而不是直接对设备进行操作的,因此能很大程度上加快读写速度。如果内存缓冲区中没有所要读入的数据,或者需要执

    19、行写操作将数据写入设备,那么就要执行真正的数据传输,这是通过调用数据结构blk_dev_struct中的函数request_fn( )来完成的。3.4 设备的控制操作除了读写操作外,应用程序有时还需要对设备进行控制,这可以通过设备驱动程序中的函数ioctl( )来完成。ioctl( )的用法与具体设备密切关联,因此需要根据设备的实际情况进行具体分析。3.5 设备的中断和轮询处理对于不支持中断的硬件设备,读写时需要轮流查询设备状态,以便决定是否继续进行数据传输。如果设备支持中断,则可以按中断方式进行操作。Linux中的I/O子系统向内核中的其他部分提供了一个统一的标准设备接口,这是通过inclu

    20、de/linux/fs.h中的数据结构file_operations来完成的:struct file_operations struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*write) (struct file *, const char *, size_t, loff_t *); int (*readdir) (struct file *, void *, filld

    21、ir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct

    22、inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); ssize_t (*writev) (struct file *, cons

    23、t struct iovec *, unsigned long, loff_t *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);当应用程序对设备文件进行诸如open、close、read、write等操作时,Linux内核将通过file_operations结

    24、构访问驱动程序提供的函数。例如,当应用程序对设备文件执行读操作时,内核将调用file_operations结构中的read函数。第4章 Linux设备驱动程序的实现1 PCI驱动程序实现的关键数据结构 PCI设备上有三种地址空间:PCI的I/O空间、PCI的存储空间和PCI的配置空间。CPU可以访问PCI设备上的所有地址空间,其中I/O空间和存储空间提供给设备驱动程序使用,而配置空间则由Linux内核中的PCI初始化代码使用。内核在启动时负责对所有PCI设备进行初始化,配置好所有的PCI设备,包括中断号以及I/O基址,并在文件/proc/pci中列出所有找到的PCI设备,以及这些设备的参数和属

    25、性。 Linux驱动程序通常使用结构(struct)来表示一种设备,而结构体中的变量则代表某一具体设备,该变量存放了与该设备相关的所有信息。好的驱动程序都应该能驱动多个同种设备,每个设备之间用次设备号进行区分,如果采用结构数据来代表所有能由该驱动程序驱动的设备,那么就可以简单地使用数组下标来表示次设备号。1.1pci_driver结构这个数据结构在文件include/linux/pci.h里,这是Linux内核版本2.4之后为新型的PCI设备驱动程序所添加的,其中最主要的是用于识别设备的d_table结构,以及用于检测设备的函数probe( )和卸载设备的函数remove( ):struct

    26、pci_driver struct list_head node; char *name; const struct pci_device_id *id_table; int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); void (*remove) (struct pci_dev *dev); int (*save_state) (struct pci_dev *dev, u32 state); int (*suspend)(struct pci_dev *dev, u32 state); int (*resu

    27、me) (struct pci_dev *dev); int (*enable_wake) (struct pci_dev *dev, u32 state, int enable); 这个数据结构也在文件include/linux/pci.h里,它详细描述了一个PCI设备几乎所有的硬件信息,包括厂商ID、设备ID、各种资源等:struct pci_dev struct list_head global_list; struct list_head bus_list; struct pci_bus *bus; struct pci_bus *subordinate; void *sysdata;

    28、 struct proc_dir_entry *procent; unsigned int devfn; unsigned short vendor; unsigned short device; unsigned short subsystem_vendor; unsigned short subsystem_device; unsigned int class; u8 hdr_type; u8 rom_base_reg; struct pci_driver *driver; void *driver_data; u64 dma_mask; u32 current_state; unsign

    29、ed short vendor_compatibleDEVICE_COUNT_COMPATIBLE; unsigned short device_compatibleDEVICE_COUNT_COMPATIBLE; unsigned int irq; struct resource resourceDEVICE_COUNT_RESOURCE; struct resource dma_resourceDEVICE_COUNT_DMA; struct resource irq_resourceDEVICE_COUNT_IRQ; char name80; char slot_name8; int active; int ro; unsigned short regs; int (*prepare)(struct pci_dev *dev); int (*activate)(struct pci_dev *dev); int (*deactivate)(struct pci_dev *dev);2写驱动程序的fuctoin问题2.1 function的encode问题在写 C 程序的时候,一


    注意事项

    本文(论Linux Kernel Module之设备驱动程序Word格式文档下载.docx)为本站会员主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2023 冰点文库 网站版权所有

    经营许可证编号:鄂ICP备19020893号-2


    收起
    展开