1. 程式人生 > >字元裝置cdev的分配和初始化

字元裝置cdev的分配和初始化

我們知道註冊字元裝置首先要有已經分配並初始化好的的cdev,那麼就需要核心提供的介面cdev_alloccdev_init。下面我們來看看著兩個介面是如何實現的:
裝置驅動程式中可以使用兩種方式來產生struct cdev物件。一種是靜態定義的方式,一種是在程式執行期間通過動態分配方式產生:
1.靜態定義
static struct cdev chr_dev;
2.動態分配
static struct cdev *chr_dev=kmalloc(sizeof(struct cdev),GFP_KERNEL);
其實,Linux核心中已經提供了一個函式cdev_alloc,是專門用來分配struct cdev物件的。cdev_init不僅會為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;
}

下面我們看看cdev的初始化介面的實現:

<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; }

函式程式碼也是非常直觀:首先對結構記憶體進行清零操作,然後初始化內部的核心連結串列因子,接下來初始化kobject,最後是檔案操作fops賦值到內部的ops中。
一個struct cdev物件在被最終加入系統前,都應該被初始化,無論是直接通過或者是其他途徑。理由很簡單,這是Linux系統中字元裝置驅動框架設計的需要。