cdev結(jié)構(gòu)在Linux2.6內(nèi)核中一個(gè)字符設(shè)備用cdev結(jié)構(gòu)來描述,其定義如下: #define MINORBITS 20 在注冊(cè)時(shí)應(yīng)該先調(diào)用:int register_chrdev_region(dev_t from,unsigned count,const char *name)函數(shù)為其分配設(shè)備號(hào),此函數(shù)可用:int alloc_chrdev_region(dev_t *dev,unsigned baseminor,unsigned count,const char *name)函數(shù)代替,他們之間的區(qū)別在于:register_chrdev_region()用于已知設(shè)備號(hào)時(shí),另一個(gè)用于動(dòng)態(tài)申請(qǐng),其優(yōu)點(diǎn)在于不會(huì)造成設(shè)備號(hào)重復(fù)的沖突。 cdev 結(jié)構(gòu)體與字符設(shè)備的注冊(cè)在 linux 2.6內(nèi)核中,使用 cdev結(jié)構(gòu)體描述字符設(shè)備,cdev 的定義在 <linux/cdev.h> 中可找到,其定義如下: cdev 結(jié)構(gòu)體中的 dev_t 成員定義了設(shè)備號(hào),為 32 位,其中高 12 位為主設(shè)備號(hào),低 20 位為次設(shè)備號(hào)。 使用以下宏可以從 dev_t 獲得主設(shè)備號(hào)和次設(shè)備號(hào): 而使用下面宏可以通過主設(shè)備號(hào)和次設(shè)備號(hào)生成 dev_t :
有兩個(gè)方法可以分配并初始化 cedv 結(jié)構(gòu)。如果希望在運(yùn)行時(shí)動(dòng)態(tài)的獲得一個(gè)獨(dú)立的 cdev 結(jié)構(gòu),可以如下這么做: cdev_alloc(void) 函數(shù)的代碼為(對(duì) cdev 結(jié)構(gòu)體操作的系列函數(shù)可在 fs/char_dev.c 中找到): cdev_alloc() 的源代碼可能由于內(nèi)核版本號(hào)的不同而有差別(上面的代碼為 2.6.30)
有時(shí)可能希望就把 cdev 結(jié)構(gòu)內(nèi)嵌在自己的特定設(shè)備結(jié)構(gòu)里,那么在分配好 cdev 結(jié)構(gòu)后,就用 cdev_init() 函數(shù)對(duì)其初始化: 引用 void cdev_init (struct cdev *cdev, struct file_operations *fops) cdev_init() 函數(shù)代碼為: 另外,像 cdev 中的 owner 要設(shè)置為 THIS_MOULE 。 cdev_add() 對(duì)應(yīng)的代碼為: 參數(shù) p 是 cdev 結(jié)構(gòu)體的指針; cdev_add 如果失敗了,那么返回一個(gè)負(fù)值,表明驅(qū)動(dòng)無法加載到系統(tǒng)中。然而它一般情況下都會(huì)成功,一旦 cdev_add 返回,設(shè)備也就 “活” 了起來,于是所對(duì)應(yīng)的操作方法(file_operations 結(jié)構(gòu)里所定義的各種函數(shù))也就能為內(nèi)核所調(diào)用。 從系統(tǒng)中移除一個(gè)字符設(shè)備,可以調(diào)用:
老版本的字符設(shè)備注冊(cè)與注銷 用于注冊(cè)字符設(shè)備驅(qū)動(dòng)程序的老式函數(shù) register_chrdev() 函數(shù)定義如下: 利用該函數(shù)注冊(cè)時(shí),應(yīng)先定義好主設(shè)備號(hào)、設(shè)備驅(qū)動(dòng)程序的名稱、file_operations 結(jié)構(gòu)體的變量。 應(yīng)用程序中利用設(shè)備文件搜索設(shè)備驅(qū)動(dòng)程序的時(shí)候使用主設(shè)備號(hào) (major) 。 在內(nèi)核中表示 proc 文件系統(tǒng)或錯(cuò)誤代碼時(shí),使用設(shè)備驅(qū)動(dòng)程序名稱。 另外,利用 unregister_chrdev() 函數(shù)注銷字符設(shè)備驅(qū)動(dòng)程序時(shí),可以作為區(qū)分標(biāo)志。注冊(cè)函數(shù)中關(guān)鍵的地方是定義 file_operations 結(jié)構(gòu)體變量的地址。 所謂注冊(cè)字符設(shè)備驅(qū)動(dòng)程序,應(yīng)理解為在內(nèi)核中注冊(cè)與主設(shè)備號(hào)相關(guān)的 file_operations 結(jié)構(gòu)體。 register_chrdev() 函數(shù)注冊(cè)完設(shè)備驅(qū)動(dòng)程序,把定義主設(shè)備號(hào)的 major 設(shè)置為 0,返回注冊(cè)的主設(shè)備號(hào)(動(dòng)態(tài)分配),把已知的主設(shè)備號(hào)設(shè)為 major 值時(shí),返回 0 (人工指定)。注冊(cè)失敗時(shí),返回負(fù)值 從內(nèi)核中注銷字符設(shè)備驅(qū)動(dòng)程序的 unregister_chrdev() 函數(shù)形式如下: 該函數(shù)中使用主設(shè)備號(hào)(major) 和設(shè)備驅(qū)動(dòng)程序名稱 (name) 與 register_chrdev 函數(shù)中使用的值相同,因?yàn)閮?nèi)核會(huì)把這些參數(shù)作為注銷字符設(shè)備驅(qū)動(dòng)程序的基準(zhǔn)對(duì)比兩個(gè)設(shè)定內(nèi)容。從內(nèi)核成功注銷了字符設(shè)備驅(qū)動(dòng)程序時(shí),返回 0 ,失敗則返回負(fù)值。 |
|