顧名思義,字元設備驅動程序管理的核心對象是字元設備.從字元設備驅動程序的設計框架角度出發,內核為字元設備抽象出了一個具體的數據結構struct cdev,其定義如下:
<include/linux/cdev.h>
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
在本章後續的內容中將陸續看到它們的實際用法,這裡只把這些成員的作用簡單描述如下:
struct kobject kobj
內嵌的內核對象,其用途將在“Linux設備驅動模型”一章中討論.
struct module *owner
字元設備驅動程序所在的內核模塊對象指針.
const struct file_operations *ops
字元設備驅動程序中一個極其關鍵的數據結構,在應用程序通過文件系統介面呼叫到設備驅動程序中實現的文件操作類函數的過程中,ops指針起著橋樑紐帶的作用.
struct list_head list
用來將系統中的字元設備形成鏈表.
dev_t dev
字元設備的設備號,由主設備號和次設備號構成.
unsigned int count
隸屬於同一主設備號的次設備號的個數,用於表示由當前設備驅動程序控制的實際同類設備的數量.
設備驅動程序中可以用兩種方式來產生struct cdev對象.一是靜態定義的方式,比如在前面的那個示常式序中,通過下列代碼靜態定義了一個struct cdev對象:
static struct cdev chr_dev;
另一種是在程序的執行期通過動態分配的方式產生,比如:
static struct cdev *p = kmalloc(sizeof(struct cdev), GFP_KERNEL);
其實Linux內核源碼中提供了一個函數cdev_alloc,專門用於動態分配struct cdev對象.cdev_alloc不僅會為struct cdev對象分配內存空間,還會對該對象進行必要的初始化:
<fs/char_dev.c>
struct cdev *cdev_alloc(void)
{
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
if (p) {
INIT_LIST_HEAD(&p->list);
kobject_init(&p->kobj, &ktype_cdev_dynamic);
}
return p;
}
需要注意的是,內核引入struct cdev數據結構作為字元設備的抽象,僅僅是為了滿足系統對字元設備驅動程序框架結構設計的需要,現實中一個具體的字元硬體設備的數據結構的抽象往往要複雜得多,在這種情況下struct cdev常常作為一種內嵌的成員變數出現在實際設備的數據機構中,比如:
struct my_keypad_dev{
//硬體相關的成員變數
int a;
int b;
int c;
…
//內嵌的struct cdev數據結構
struct cdev cdev;
};
在這樣的情況下,如果要動態分配一個struct real_char_dev對象,cdev_alloc函數顯然就無能為力了,此時只能使用下面的方法:
static struct real_char_dev *p = kzalloc(sizeof(struct real_char_dev), GFP_KERNEL);
前面討論了如何分配一個struct cdev對象,接下來的一個話題是如何初始化一個cdev對象,內核為此提供的函數是
cdev_init:<fs/char_dev.c>
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, 0, sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
kobject_init(&cdev->kobj, &ktype_cdev_default);
cdev->ops = fops;
}
函數的代碼非常直白,不再贅述.一個
struct cdev對象在被最終加入系統前,都應該被初始化,無論是直接通過cdev_init或者是其他途徑.理由很簡單,這是Linux系統中字元設備驅動程序框架設計的需要.照理在談完cdev對象的分配和初始化之後,下面應該討論如何將一個cdev對象加入到系統了,但是由於這個過程需要用到設備號相關的技術點,暫且先來探討設備號的問題.
——本段文位元組選自《深入
Linux設備驅動程序內核機制》圖書詳細信息:http://bvbroadview.blog.51cto.com/addblog.php
[火星人 ] 字元設備的內核抽象已經有341次圍觀