电竞比分网-中国电竞赛事及体育赛事平台

分享

Linux設(shè)備驅(qū)動(dòng)程序中的一些具體問(wèn)題

 lchjczw 2012-04-06

1。 I/O Port

和硬件打交道離不開(kāi)I/O Port,老的ISA設(shè)備經(jīng)常是占用實(shí)際的I/O端口,在linux下,操作系統(tǒng)沒(méi)有對(duì)I/O口屏蔽,也就是說(shuō),任何驅(qū)動(dòng)程序都可對(duì)任意的I/O口操作,這樣就很容易引起混亂。每個(gè)驅(qū)動(dòng)程序應(yīng)該自己避免誤用端口。

有兩個(gè)重要的kernel函數(shù)可以保證驅(qū)動(dòng)程序做到這一點(diǎn)。

1)check_region(int io_port, int off_set)

這個(gè)函數(shù)察看系統(tǒng)的I/O表,看是否有別的驅(qū)動(dòng)程序占用某一段I/O口。

參數(shù)1:io端口的基地址,

參數(shù)2:io端口占用的范圍。

返回值:0 沒(méi)有占用, 非0,已經(jīng)被占用。

2)request_region(int io_port, int off_set,char *devname)

如果這段I/O端口沒(méi)有被占用,在我們的驅(qū)動(dòng)程序中就可以使用它。在使用之前,必須向系統(tǒng)登記,以防止被其他程序占用。登記后,在/proc/ioports文件中可以看到你登記的io口。

參數(shù)1:io端口的基地址。

參數(shù)2:io端口占用的范圍。

參數(shù)3:使用這段io地址的設(shè)備名。

在對(duì)I/O口登記后,就可以放心地用inb(), outb()之類(lèi)的函來(lái)訪問(wèn)了。

在一些pci設(shè)備中,I/O端口被映射到一段內(nèi)存中去,要訪問(wèn)這些端口就相當(dāng)于訪問(wèn)一段內(nèi)存。經(jīng)常性的,我們要獲得一塊內(nèi)存的物理地址。

2。內(nèi)存操作

在設(shè)備驅(qū)動(dòng)程序中動(dòng)態(tài)開(kāi)辟內(nèi)存,不是用malloc,而是kmalloc,或者用get_free_pages直接申請(qǐng)頁(yè)。釋放內(nèi)存用的是kfree,或free_pages。 請(qǐng)注意,kmalloc等函數(shù)返回的是物理地址!

注意,kmalloc最大只能開(kāi)辟128k-16,16個(gè)字節(jié)是被頁(yè)描述符結(jié)構(gòu)占用了。

內(nèi)存映射的I/O口,寄存器或者是硬件設(shè)備的RAM(如顯存)一般占用F0000000以上的地址空間。在驅(qū)動(dòng)程序中不能直接訪問(wèn),要通過(guò)kernel函數(shù)vremap獲得重新映射以后的地址。

另外,很多硬件需要一塊比較大的連續(xù)內(nèi)存用作DMA傳送。這塊程序需要一直駐留在內(nèi)存,不能被交換到文件中去。但是kmalloc最多只能開(kāi)辟128k的內(nèi)存。

這可以通過(guò)犧牲一些系統(tǒng)內(nèi)存的方法來(lái)解決。

 3。中斷處理

同處理I/O端口一樣,要使用一個(gè)中斷,必須先向系統(tǒng)登記。

int request_irq(unsigned int irq ,void(*handle)(int,void *,struct pt_regs *),

unsigned int long flags, const char *device);

irq: 是要申請(qǐng)的中斷。

handle:中斷處理函數(shù)指針。

flags:SA_INTERRUPT 請(qǐng)求一個(gè)快速中斷,0 正常中斷。

device:設(shè)備名。

如果登記成功,返回0,這時(shí)在/proc/interrupts文件中可以看你請(qǐng)求的中斷。

4。一些常見(jiàn)的問(wèn)題。

對(duì)硬件操作,有時(shí)時(shí)序很重要。但是如果用C語(yǔ)言寫(xiě)一些低級(jí)的硬件操作的話(huà),gcc往往會(huì)對(duì)你的程序進(jìn)行優(yōu)化,這樣時(shí)序會(huì)發(fā)生錯(cuò)誤。如果用匯編寫(xiě)呢,gcc同樣會(huì)對(duì)匯編代碼進(jìn)行優(yōu)化,除非用volatile關(guān)鍵字修飾。最保險(xiǎn)的辦法是禁止優(yōu)化。這當(dāng)然只能對(duì)一部分你自己編寫(xiě)的代碼。如果對(duì)所有的代碼都不優(yōu)化,你會(huì)發(fā)現(xiàn)驅(qū)動(dòng)程序根本無(wú)法裝載。這是因?yàn)樵诰幾g驅(qū)動(dòng)程序時(shí)要用到gcc的一些擴(kuò)展特性,而這些擴(kuò)展特性必須在加了優(yōu)化選項(xiàng)之后才能體現(xiàn)出來(lái)。

 

由于設(shè)備種類(lèi)繁多,相應(yīng)的設(shè)備驅(qū)動(dòng)程序也非常之多。盡管設(shè)備驅(qū)動(dòng)程序是內(nèi)核的一部分,但設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)往往由很多人來(lái)完成,如業(yè)余編程高手、設(shè)備廠商等。為了讓設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)建立在規(guī)范的基礎(chǔ)上,就必須在驅(qū)動(dòng)程序和內(nèi)核之間有一個(gè)嚴(yán)格定義和管理的接口,例如SVR4提出了DDI/DDK規(guī)范,其含義就是設(shè)備與驅(qū)動(dòng)程序接口/設(shè)備驅(qū)動(dòng)程序與內(nèi)核接口(Device-Driver Interface/Driver-Kernel Interface)。通過(guò)這個(gè)規(guī)范,可以規(guī)范設(shè)備驅(qū)動(dòng)程序與內(nèi)核之間的接口。

 

Linux的設(shè)備驅(qū)動(dòng)程序與外接的接口與DDI/DKI規(guī)范相似,可以分為三部分:

(1)   驅(qū)動(dòng)程序與內(nèi)核的接口,這是通過(guò)數(shù)據(jù)結(jié)構(gòu)file_operations來(lái)完成的。

(2)   驅(qū)動(dòng)程序與系統(tǒng)引導(dǎo)的接口,這部分利用驅(qū)動(dòng)程序?qū)υO(shè)備進(jìn)行初始化。

(3)   驅(qū)動(dòng)程序與設(shè)備的接口,這部分描述了驅(qū)動(dòng)程序如何與設(shè)備進(jìn)行交互,這與具體設(shè)備密切相關(guān)。

 

根據(jù)功能,驅(qū)動(dòng)程序的代碼可以分為如下幾個(gè)部分:

(1)驅(qū)動(dòng)程序的注冊(cè)和注銷(xiāo)

(2)設(shè)備的打開(kāi)與釋放

(3)設(shè)備的讀和寫(xiě)操作

(4)設(shè)備的控制操作

(5)設(shè)備的中斷和查詢(xún)處理

前三點(diǎn)我們已經(jīng)給予簡(jiǎn)單說(shuō)明,后面我們還會(huì)結(jié)合具體程序給出進(jìn)一步的說(shuō)明。關(guān)于設(shè)備的控制操作可以通過(guò)驅(qū)動(dòng)程序中的ioctl()來(lái)完成,例如,對(duì)光驅(qū)的控制可以使用cdrom_ ioctl()。

與讀寫(xiě)操作不同,ioctl()的用法與具體設(shè)備密切相關(guān),例如,對(duì)于軟驅(qū)的控制可以使用floppy_ioctl(),其調(diào)用形式為:

static int floppy_ioctl(struct inode *inode, struct file *filp,

unsigned int cmd, unsigned long param)

其中cmd的取值及含義與軟驅(qū)有關(guān),例如,F(xiàn)DEJECT表示彈出軟盤(pán)。

除了ioctl(),設(shè)備驅(qū)動(dòng)程序還可能有其他控制函數(shù),如lseek()等。

對(duì)于不支持中斷的設(shè)備,讀寫(xiě)時(shí)需要輪流查詢(xún)?cè)O(shè)備的狀態(tài),以便決定是否繼續(xù)進(jìn)行數(shù)據(jù)傳輸,例如,打印機(jī)驅(qū)動(dòng)程序在缺省時(shí)輪流查詢(xún)打印機(jī)的狀態(tài)。如果設(shè)備支持中斷,則可按中斷方式進(jìn)行

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多