第一:struct inode結(jié)構(gòu)體
struct inode { ······ struct hlist_node i_hash; struct list_head i_list; /* backing dev IO list */ struct list_head i_sb_list; //主次設(shè)備號(hào) dev_t i_rdev; struct list_head i_devices; //用聯(lián)合體是因?yàn)樵撐募赡苁菈K設(shè)備文件或者字符設(shè)備文件 union { struct pipe_inode_info *i_pipe; //管道文件 struct block_device *i_bdev; //塊設(shè)備文件 struct cdev *i_cdev; //字符設(shè)備文件 }; //私有數(shù)據(jù) void *i_private; /* fs or device private pointer */ };
功能:struct inode結(jié)構(gòu)體是用來(lái)表示一個(gè)靜態(tài)文件的,每個(gè)文件都會(huì)對(duì)應(yīng)唯一的struct inode結(jié)構(gòu)體,結(jié)構(gòu)體里描述了文件的詳細(xì)信息。
第二:struct file結(jié)構(gòu)體
struct file { union { struct list_head fu_list; struct rcu_head fu_rcuhead; } f_u; ······ const struct file_operations *f_op; //該文件對(duì)應(yīng)的操作方法 unsigned int f_flags; fmode_t f_mode; //打開(kāi)文件的權(quán)限,比如:只讀打開(kāi)、只寫(xiě)打開(kāi)、讀寫(xiě)打開(kāi) loff_t f_pos; //文件指針的偏移量 /* needed for tty driver, and maybe others */ void *private_data; //私有數(shù)據(jù) };
功能:struct file結(jié)構(gòu)體 用來(lái)表示一個(gè)動(dòng)態(tài)的設(shè)備,每當(dāng)open打開(kāi)一個(gè)文件時(shí)就會(huì)產(chǎn)生一個(gè)struct file結(jié)構(gòu)體 與之對(duì)應(yīng)。
第三:struct file_operations結(jié)構(gòu)體
struct file_operations { struct module *owner; ······ loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); int (*open) (struct inode *, struct file *); int (*release) (struct inode *, struct file *); };
功能:struct file_operations結(jié)構(gòu)體是用來(lái)描述設(shè)備的操作方法的。在linux中一切皆是文件,不管是普通文件還是設(shè)備驅(qū)動(dòng)文件上層應(yīng)用都是用同一的open、read函數(shù)去操作。每一個(gè)struct file結(jié)構(gòu)體 中都保存了一個(gè)struct file_operations結(jié)構(gòu)體,雖然上層應(yīng)用都是調(diào)用的read函數(shù),但是在內(nèi)部實(shí)際通過(guò)函數(shù)指針調(diào)用了不同的read函數(shù)。
第四:struct cdev結(jié)構(gòu)體
struct cdev { struct kobject kobj; struct module *owner; const struct file_operations *ops; //設(shè)備的操作方法 struct list_head list; dev_t dev; //主次設(shè)備號(hào) unsigned int count; //引用計(jì)數(shù) };
第五:結(jié)構(gòu)體之間的關(guān)聯(lián)
1、struct inode結(jié)構(gòu)體和struct file結(jié)構(gòu)體
(1)struct inode結(jié)構(gòu)體和struct file結(jié)構(gòu)體 都是用來(lái)描述文件信息的,struct inode結(jié)構(gòu)體是描述靜態(tài)的文件,struct file結(jié)構(gòu)體描述動(dòng)態(tài)的文件(也就是打開(kāi)的文件);
(2)每個(gè)文件只有唯一的struct inode結(jié)構(gòu)體,但是可以有多個(gè)struct file結(jié)構(gòu)體,文件每被打開(kāi)一次就多一個(gè) struct file結(jié)構(gòu)體 ;
2、struct file_operations結(jié)構(gòu)體和struct cdev結(jié)構(gòu)體
(1)struct file_operations結(jié)構(gòu)體描述設(shè)備的操作方法,struct cdev結(jié)構(gòu)體描述字符設(shè)備全部的信息;
(2)struct cdev結(jié)構(gòu)體包含struct file_operations結(jié)構(gòu)體,在注冊(cè)驅(qū)動(dòng)時(shí)需要將struct file_operations結(jié)構(gòu)體指針賦值給struct cdev結(jié)構(gòu)體;
3、struct inode結(jié)構(gòu)體和struct cdev結(jié)構(gòu)體
(1)上層應(yīng)用訪問(wèn)設(shè)備驅(qū)動(dòng)是通過(guò)設(shè)備節(jié)點(diǎn),設(shè)備節(jié)點(diǎn)就是一個(gè)文件,在創(chuàng)建設(shè)備節(jié)點(diǎn)時(shí)需要指明主次設(shè)備號(hào),主次設(shè)備號(hào)就會(huì)保存在設(shè)備節(jié)點(diǎn)對(duì)應(yīng)的 struct inode結(jié)構(gòu)體的i_rdev變量中;
(2)在向內(nèi)核注冊(cè)字符設(shè)備驅(qū)動(dòng)時(shí)就是將對(duì)應(yīng)的struct cdev結(jié)構(gòu)體注冊(cè)到chrdevs全局變量中,其中struct cdev結(jié)構(gòu)體就保存了主次設(shè)備號(hào);
(3)struct inode結(jié)構(gòu)體的聯(lián)合體中有struct cdev結(jié)構(gòu)體指針,將來(lái)找到對(duì)應(yīng)的struct cdev結(jié)構(gòu)體會(huì)對(duì)該指針賦值;
(4)聯(lián)系:在用open打開(kāi)設(shè)備節(jié)點(diǎn)時(shí)從struct inode結(jié)構(gòu)體中獲取初次設(shè)備號(hào),然后用這個(gè)主次設(shè)備號(hào)去chrdevs全局變量中找到對(duì)應(yīng)的struct cdev結(jié)構(gòu)體。
總結(jié):依靠主次設(shè)備號(hào)聯(lián)系起來(lái)。
編輯:黃飛
?
評(píng)論
查看更多