PCie驱动综述分析_第1页
PCie驱动综述分析_第2页
PCie驱动综述分析_第3页
PCie驱动综述分析_第4页
PCie驱动综述分析_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

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

文档简介

1、PCie驱动Pcie设备上有三种地址空间:PCI的I/O空间、PCI的存储空间和 PCI的配置空间。Pce的配置空间:PCI有三个相互独立的物理地址空间:设备存储器地址空间、I/O地址空间和配置空间。配置空间是PCI所特有的一个物理空间。由于PCI支持设备即插即用,所以PCI设备不占用固定的内存地址空间或I/O地址空间,而是由操作系统决定其映射的基址。系统加电时,BIOS检测PCI总线,确定所有连接在 PCI总线上的设备以及它们的配置要求,并进行系统配置。所以,所有的PCI设备必须实现配置空间,从而能够实现参数的自动配置,实现真正的即插即用。PCI总线规范定义的配置空间总长度为256个字节,配

2、置信息按一定的顺序和大小依次存放。前64个字节的配置空间称为配置头,对于所有的设备都一样,配置头的主要功能是用来识别设备、定义主机访问 PCI卡的方式(I/O访问或者存储器访问,还有中断信息)。其余的 192个字 节称为本地配置空间,主要定义卡上局部总线的特性、本地空间基地址及范围等。311:QDevice IDVendor IDQOh|ScirutCcnEnand0411f加Cod?Revision IDOSh5IST Header TypeQOj1Base Address Rezistef 1lOh3asr Addrf 5-4 Rczisier 214!iBase Add re »

3、; R亡黑址 i 3mReels41CI120hBaseRtgiiter 624hCIS Pointer2SbIDSubvscfm Vendor ID2ChWxRMiz口穿 ROX* Bas* AddffisiObCapitij:T5 Fctntcr3Sli口X 工不IJJzi GncInttfrup: PuiIn :!*Trupi LineSCIi一般来说,基于pcie总线的驱动,需要涉及到pci_driver pci_dev pci_device_id .pci_device_id :用于标识pcie设备,通过上图的厂商Id设备Id功能号等唯一确定一个pcie设备,内核通过这个结构体确认驱

4、动与设备是否匹配。pci_dev : 一般pcie设备都具有热拔插功能,当内核检测到有pcie设备插入时,会与相应的Pci_driver :当有相应的设备匹配会调用驱动的相关方法,驱动中通常要做的是读出BaseAdrress Register1-6的值,这是pcies设备6个内存空间的基地址,然后通过ioremap方法映射成虚拟地址,至于6个内存空间的具体含义需要依赖于设备。在用模块方式实现 PCI设备驱动程序时,通常至少要实现以下几个部分:初始化设备模块、 设备打开模块、数据读写和控制模块、中断处理模块、设备释放模块、设备卸载模块。例如/*指明该驱动程序适用于哪一些PCI设备*/static

5、 struct pci_device_id demo_ids = PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_IDNTEL_82810_IG1) , PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3) , PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) , PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) , PCI_DEVIC

6、E(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) , 0, ,;这个pci_device_id结构需要被输出到用户空间,来允许热插拔和模块加载系统知道什么模块使用什么硬件设备 宏MODULE_DEVICE_TABL完成这个.例如:MODULE_DEVICE_TABLE(pci, demo_ids);struct demo_card un sig ned int magic;/*使用链表保存所有同类的PCI设备*/ struct demo_card *n ext;/* . */*中断处理模块*/static void demo_ in t

7、errupt(i nt irq, void *dev_id, struct pt_regs *regs)/* . */owner:THIS_MODULE,/* demo_fops所属的设备模块read:demo_read, /*读设备操作*/write:demo_write, /*写设备操作*/ioctl:demo_ioctl, /*控制设备操作*/mmap:demo_mmap,/*内存重映射操作*/ope n:demo_ope n, /*打开设备操作*/release:demo release/*释放设备操作*/static struct file_operations demo_fops

8、= */*设备文件操作接口*/* . */;/*设备模块信息*/static struct pci_driver demo_pci_driver = name:demo_MODULE_NAME, /* 设备模块名称 */id_table: demo_idsl, /*能够驱动的设备列表 */ probe:demo_probe, /*设备与驱动匹配时调用remove:demo_remove /* 卸载设备模块 */* . */;3.初始化设备模块在Linux系统下,想要完成对一个PCI设备的初始化,需要完成以下工作:检查PCI总线是否被Linux内核支持;检查设备是否插在总线插槽上,如果在的话则保

9、存它所占用的插槽的位置等信息。读出配置头中的信息提供给驱动程序使用。当Linux内核启动并完成对所有PCI设备进行扫描、登录和分配资源等初始化操作的同时,会建立起系统中所有PCI设备的拓扑结构,此后当PCI驱动程序需要对设备进行初始化时,一般都会调用如下的代码:static int _init dem on it_module (void)/*检查系统是否支持 PCI总线*/if (!pci_prese nt()return -ENODEV;/*注册硬件驱动程序*/if (!pci_register_driver( &demo_pci_driver) pci_ un register_

10、driver(&demo_pci_driver);return -ENODEV;/* . */ return 0;驱动程序首先调用函数pci_present()检查PCI总线是否已经被Linux内核支持,如果系统支持PCI总线结构,这个函数的返回值为0,如果驱动程序在调用这个函数时得到了一个非0的返回值,那么驱动程序就必须得中止自己的任务了。调用pci_register_driver()函数来注册PCI设备的驱动程序,此时需要提供一个pci_driver结构,在该结构中给出的probe探测例程将负责完成对硬件的检测工作。static int _init demo_probe(struc

11、t pci_dev *pci_dev, const struct pci_device_id *pci_id)struct demo_card *card;/*启动PCI设备*/if (pci_e nable_device(pci_dev)return -EIO;/*设备DMA标识*/if (pci_set_dma_mask(pci_dev, DEMO_DMA_MASK) return -ENODEV;/*在内核空间中动态申请内存*/if (card = kmalloc(sizeof(struct demo_card), GFP_KERNEL) = NULL) prin tk(KERN_ERR

12、 "pci_demo: out of memory' n");return -ENOMEM;memset(card, 0, sizeof(*card);/*读取PCI配置信息*/card->iobase = pci_resource_start (pci_dev, 1);card->pci_dev = pci_dev;card->pci_id = pci_id ->device;card->irq = pci_dev->irq;card->n ext = devs;card->magic = DEMO_CARD_MAG

13、IC;/*设置成总线主DMA模式*/pci_set_master(pci_dev);/*申请I/O资源*/request_region(card ->iobase, 64, card_namespci_id ->driver_data);return 0;4.打开设备模块在这个模块里主要实现申请中断、检查读写模式以及申请对设备的控制权等。在申请控制 权的时候,非阻塞方式遇忙返回,否则进程主动接受调度,进入睡眠状态,等待其它进程释放 对设备的控制权。static int demo_open(struct inode *inode, struct file *file)/*申请中断,注

14、册中断处理程序*/request_irq(card ->irq, &demo_interrupt, SA_SHIRQ,card_namespci_id ->driver_data, card) /*检查读写模式*/if(file ->f_mode & FMODE_READ) /* . */if(file ->f_mode & FMODE_WRITE) /* . */*申请对设备的控制权*/down(&card ->open_sem);while(card ->open_mode & file ->f_mode)

15、if (file ->f_flags & O_NONBLOCK) /* NONBLOCK模式,返回-EBUSY */up(&card ->ope n_sem);return -EBUSY; else /*等待调度,获得控制权*/card->open_mode |= f_mode & (FMODE_READ | FMODE_WRITE); up(&card ->ope n_sem);/*设备打开计数增1 */MOD_INC_USE_COUNT;/* . */在对资源的访问方式上,除了有I/O指令以外,还有对外设I/O内存的访问。对这些内存的

16、操作一方面可以通过把I/O内存重新映射后作为普通内存进行操作,另一方面也可以通过总线主DMA(Bus Master DMA)的方式让设备把数据通过DMA传送到系统内存中。释放设备模块主要负责释放对设备的控制权,释放占用的内存和中断等,所做的事情正好 与打开设备模块相反:static int demo_release(struct inode *inode, struct file *file)/* . */*释放对设备的控制权 */card->open_mode &= (FMODE_READ | FMODE_WRITE);/*唤醒其它等待获取控制权的进程*/wake_up(&card ->ope n_wait);up(&card ->ope

温馨提示

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

评论

0/150

提交评论