file、inode在應用層和驅動層之間的聯繫

應用層和驅動的銜接,一直是一個老大難問題,若弄不清楚,總覺得驅動寫起來似是而非的。下面就說說我對他們的理解,還有就是如何實現一個驅動支持多個上設備的問題。最主要涉及兩個機制:inode和file


在驅動中:

(1)、我們先找到一個設備號devno,可以動態申請,也可以靜態設定,假設靜態設定爲major,minor,通過宏MKDEV(major,minor)來生成devno

(2)、構建對設備的操作函數file_opreation結構體,裏面包含了的設備的操作:open、read、write、release、ioctl等

(3)、構建cdev結構體,裏面填充兩個主要成員dev(設備號)、file_operation(對設備的操作)

(4)、把cdev添加的cdev鏈表中:cdev_init、cdev_add


應用程序中:

fd=open("/dev/hello",O_RDWR)來打開設備文件,此設備節點對應有一個設備號,這是我們識別驅動和設備的橋樑。

打開 /dev/hello時,根據設備號,在cdev鏈表中找到cdev這個結構體,cdev裏面包含了file_operation結構體,有設備的各種操作,打開時就調用裏面的.open 函數。在這裏要完成幾件事:

(1)inode節點 每一個文件都對應有一個inode節點,inode結構體裏.i_fop由cdev的file_operation填充,i_dev由cdev的設備號填充

(2)file結構體中的file_operation也同樣由cdev中對應項填充,還有一項fd,對應於打開文件的文件描述符,fd和file一一對應,文件每打開一次,就有一個file結構it。所以file裏面的.private就很重要,下面會說到。


還有一個問題,那就是多個相同的設備,會公用同一個驅動,所以要把每一個設備的私有數據封裝起來,構成一個私有數據結構體。對設備的每一次讀寫,都通過操作設備的私有數據結構體中的資源來完成。也就是說,驅動在加載的時候,會申請多個設備私有資源結構體,每個結構體中包含了設備的所有私有資源,雖然公用一個驅動,可是通過設備號找到此設備號對應設備的私有資源,說的有點拗口。這可以通過file結構體的.private來指向。


例如封裝私有數據的結構體爲:

struct hello_device{

char buf[128]; //設備的私有資源,譬如buf

struct cdev cdev;//設備結構體,裏面有devno和file_operation

……

};

前面應經提到inode中的i_cdev會指向cdev結構,所以可以由container宏來得到hello_device的地址。

所以,在驅動的open函數中有兩個參數,inode和file

int open(structc inode *inode,struct file *file){

struct hello_device   *p =container(inode->i_cdev,hello_struct,cdev)

file->private=p;

}

這樣file中就包含了設備的私有數據。

驅動read函數中:

ssize_t read(fd,char __user *buf,count)

fd和file一一對應,每打開一次設備,雖然有不同的fd,但他們的file.private是一樣的。


前面主要說了一個驅動如何可以支持多個設備的問題,以及應用層和驅動之間的聯繫。還有一個問題就是,如何處理過個進程訪問同一個設備的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章