PCie驅(qū)動(dòng)綜述_第1頁(yè)
PCie驅(qū)動(dòng)綜述_第2頁(yè)
PCie驅(qū)動(dòng)綜述_第3頁(yè)
PCie驅(qū)動(dòng)綜述_第4頁(yè)
PCie驅(qū)動(dòng)綜述_第5頁(yè)
已閱讀5頁(yè),還剩2頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、 PCie 驅(qū)動(dòng)Pcie設(shè)備上有三種地址空間:PCI的I/O空間、PCI的存儲(chǔ)空間和PCI的配置空間。Pce的配置空間:PCI有三個(gè)相互獨(dú)立的物理地址空間:設(shè)備存儲(chǔ)器地址空間、I/O地址空間和配置空間。配置空間是PCI所特有的一個(gè)物理空間。由于PCI支持設(shè)備即插即用,所以PCI設(shè)備不占用固定的內(nèi)存地址空間或I/O地址空間,而是由操作系統(tǒng)決定其映射的基址。系統(tǒng)加電時(shí),BIOS檢測(cè)PCI總線,確定所有連接在PCI總線上的設(shè)備以及它們的配置要求,并進(jìn)行系統(tǒng)配置。所以,所有的PCI設(shè)備必須實(shí)現(xiàn)配置空間,從而能夠?qū)崿F(xiàn)參數(shù)的自動(dòng)配置,實(shí)現(xiàn)真正的即插即用。PCI總線規(guī)范定義的配置空間總長(zhǎng)度為256個(gè)字節(jié),配

2、置信息按一定的順序和大小依次存放。前64個(gè)字節(jié)的配置空間稱為配置頭,對(duì)于所有的設(shè)備都一樣,配置頭的主要功能是用來識(shí)別設(shè)備、定義主機(jī)訪問PCI卡的方式(I/O訪問或者存儲(chǔ)器訪問,還有中斷信息)。其余的192個(gè)字節(jié)稱為本地配置空間,主要定義卡上局部總線的特性、本地空間基地址及范圍等。·一般來說,基于pcie總線的驅(qū)動(dòng),需要涉及到pci_driver pci_dev pci_device_id .pci_device_id : 用于標(biāo)識(shí)pcie設(shè)備,通過上圖的廠商Id 設(shè)備Id 功能號(hào)等 唯一確定一個(gè)pcie設(shè)備,內(nèi)核通過這個(gè)結(jié)構(gòu)體確認(rèn)驅(qū)動(dòng)與設(shè)備是否匹配。pci_dev : 一般pcie

3、設(shè)備都具有熱拔插功能,當(dāng)內(nèi)核檢測(cè)到有pcie設(shè)備插入時(shí),會(huì)與相應(yīng)的Pci_driver : 當(dāng)有相應(yīng)的設(shè)備匹配會(huì)調(diào)用驅(qū)動(dòng)的相關(guān)方法,驅(qū)動(dòng)中通常要做的是讀出Base Adrress Register1-6 的值,這是pcies設(shè)備6個(gè)內(nèi)存空間的基地址,然后通過ioremap方法映射成虛擬地址,至于6個(gè)內(nèi)存空間的具體含義需要依賴于設(shè)備。在用模塊方式實(shí)現(xiàn)PCI設(shè)備驅(qū)動(dòng)程序時(shí),通常至少要實(shí)現(xiàn)以下幾個(gè)部分:初始化設(shè)備模塊、設(shè)備打開模塊、數(shù)據(jù)讀寫和控制模塊、中斷處理模塊、設(shè)備釋放模塊、設(shè)備卸載模塊。例如/* 指明該驅(qū)動(dòng)程序適用于哪一些PCI設(shè)備 */static struct pci_device_id

4、demo_ids = PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_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_DEVICE(PCI_VENDOR_ID_INTE

5、L, PCI_DEVICE_ID_INTEL_82845G_IG) , 0, ,;這個(gè) pci_device_id 結(jié)構(gòu)需要被輸出到用戶空間, 來允許熱插拔和模塊加載系統(tǒng)知道什么模塊使用什么硬件設(shè)備. 宏 MODULE_DEVICE_TABLE 完成這個(gè). 例如:MODULE_DEVICE_TABLE(pci, demo_ids);struct demo_card     unsigned int magic;    /* 使用鏈表保存所有同類的PCI設(shè)備 */    struct demo_card *

6、next;       /* . */* 中斷處理模塊 */static void demo_interrupt(int irq, void *dev_id, struct pt_regs *regs)    /* . */* 設(shè)備文件操作接口 */static struct file_operations demo_fops =     owner:      THIS_MODULE,   /* demo

7、_fops所屬的設(shè)備模塊 */    read:       demo_read,    /* 讀設(shè)備操作*/    write:      demo_write,    /* 寫設(shè)備操作*/    ioctl:      demo_ioctl,    /*

8、控制設(shè)備操作*/    mmap:       demo_mmap,    /* 內(nèi)存重映射操作*/    open:       demo_open,    /* 打開設(shè)備操作*/    release:    demo_release    /* 釋放設(shè)備操作*/&

9、#160;   /* . */;/* 設(shè)備模塊信息 */static struct pci_driver demo_pci_driver =     name:       demo_MODULE_NAME,    /* 設(shè)備模塊名稱 */    id_table:   demo_idsl,    /* 能夠驅(qū)動(dòng)的設(shè)備列表 */    probe:

10、      demo_probe,    /* 設(shè)備與驅(qū)動(dòng)匹配時(shí)調(diào)用    remove:     demo_remove    /* 卸載設(shè)備模塊 */    /* . */; 3. 初始化設(shè)備模塊在Linux系統(tǒng)下,想要完成對(duì)一個(gè)PCI設(shè)備的初始化,需要完成以下工作:檢查PCI總線是否被Linux內(nèi)核支持;檢查設(shè)備是否插在總線插槽上,如果在的話則保存它所占用的插槽

11、的位置等信息。讀出配置頭中的信息提供給驅(qū)動(dòng)程序使用。當(dāng)Linux內(nèi)核啟動(dòng)并完成對(duì)所有PCI設(shè)備進(jìn)行掃描、登錄和分配資源等初始化操作的同時(shí),會(huì)建立起系統(tǒng)中所有PCI設(shè)備的拓?fù)浣Y(jié)構(gòu),此后當(dāng)PCI驅(qū)動(dòng)程序需要對(duì)設(shè)備進(jìn)行初始化時(shí),一般都會(huì)調(diào)用如下的代碼:static int _init demo_init_module (void)    /* 檢查系統(tǒng)是否支持PCI總線 */    if (!pci_present()        return -ENODEV;

12、0;   /* 注冊(cè)硬件驅(qū)動(dòng)程序 */    if (!pci_register_driver(&demo_pci_driver)         pci_unregister_driver(&demo_pci_driver);                return -ENODEV;  

13、      /* . */      return 0; 驅(qū)動(dòng)程序首先調(diào)用函數(shù)pci_present( )檢查PCI總線是否已經(jīng)被Linux內(nèi)核支持,如果系統(tǒng)支持PCI總線結(jié)構(gòu),這個(gè)函數(shù)的返回值為0,如果驅(qū)動(dòng)程序在調(diào)用這個(gè)函數(shù)時(shí)得到了一個(gè)非0的返回值,那么驅(qū)動(dòng)程序就必須得中止自己的任務(wù)了。調(diào)用pci_register_driver( )函數(shù)來注冊(cè)PCI設(shè)備的驅(qū)動(dòng)程序,此時(shí)需要提供一個(gè)pci_driver結(jié)構(gòu),在該結(jié)構(gòu)中給出的probe探測(cè)例程將負(fù)責(zé)完成對(duì)硬件的檢測(cè)工作。 static

14、int _init demo_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)    struct demo_card *card;    /* 啟動(dòng)PCI設(shè)備 */    if (pci_enable_device(pci_dev)        return -EIO;    /* 設(shè)備DMA標(biāo)識(shí) */ 

15、60;  if (pci_set_dma_mask(pci_dev, DEMO_DMA_MASK)         return -ENODEV;        /* 在內(nèi)核空間中動(dòng)態(tài)申請(qǐng)內(nèi)存 */    if (card = kmalloc(sizeof(struct demo_card), GFP_KERNEL) = NULL)         prin

16、tk(KERN_ERR "pci_demo: out of memoryn");        return -ENOMEM;        memset(card, 0, sizeof(*card);    /* 讀取PCI配置信息 */    card->iobase = pci_resource_start (pci_dev, 1);    ca

17、rd->pci_dev = pci_dev;    card->pci_id = pci_id->device;    card->irq = pci_dev->irq;    card->next = devs;    card->magic = DEMO_CARD_MAGIC;    /* 設(shè)置成總線主DMA模式 */       pci_s

18、et_master(pci_dev);    /* 申請(qǐng)I/O資源 */    request_region(card->iobase, 64, card_namespci_id->driver_data);    return 0; 4. 打開設(shè)備模塊在這個(gè)模塊里主要實(shí)現(xiàn)申請(qǐng)中斷、檢查讀寫模式以及申請(qǐng)對(duì)設(shè)備的控制權(quán)等。在申請(qǐng)控制權(quán)的時(shí)候,非阻塞方式遇忙返回,否則進(jìn)程主動(dòng)接受調(diào)度,進(jìn)入睡眠狀態(tài),等待其它進(jìn)程釋放對(duì)設(shè)備的控制權(quán)。static int demo_open(str

19、uct inode *inode, struct file *file)    /* 申請(qǐng)中斷,注冊(cè)中斷處理程序 */    request_irq(card->irq, &demo_interrupt, SA_SHIRQ,        card_namespci_id->driver_data, card)     /* 檢查讀寫模式 */    if(file->f_mode

20、 & FMODE_READ)         /* . */        if(file->f_mode & FMODE_WRITE)        /* . */           /* 申請(qǐng)對(duì)設(shè)備的控制權(quán) */    down(&card->op

21、en_sem);    while(card->open_mode & file->f_mode)         if (file->f_flags & O_NONBLOCK)             /* NONBLOCK模式,返回-EBUSY */        

22、60;   up(&card->open_sem);            return -EBUSY;        else             /* 等待調(diào)度,獲得控制權(quán) */       

23、60;    card->open_mode |= f_mode & (FMODE_READ | FMODE_WRITE);            up(&card->open_sem);            /* 設(shè)備打開計(jì)數(shù)增1 */       

24、;     MOD_INC_USE_COUNT;            /* . */            在對(duì)資源的訪問方式上,除了有I/O指令以外,還有對(duì)外設(shè)I/O內(nèi)存的訪問。對(duì)這些內(nèi)存的操作一方面可以通過把I/O內(nèi)存重新映射后作為普通內(nèi)存進(jìn)行操作,另一方面也可以通過總線主DMA(Bus Master DMA)的方式讓設(shè)備把數(shù)據(jù)通過DMA傳送到系統(tǒng)內(nèi)存中。 釋放設(shè)備模塊主要負(fù)責(zé)釋放對(duì)設(shè)備的控制權(quán),釋放占用的內(nèi)存和中斷等,所做的事情正好與打開設(shè)備模塊

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論