字元裝置的註冊

2021-04-22 09:29:08 字數 1205 閱讀 1005

核心中每個字元裝置都對應乙個 cdev 結構的變數,下面是它的定義:

struct cdev ;

乙個 cdev 一般它有兩種定義初始化方式:靜態的和動態的。

靜態記憶體定義初始化:

struct cdev my_cdev;

cdev_init(&my_cdev, &fops);

my_cdev.owner = this_module;

動態記憶體定義初始化:

struct cdev *my_cdev = cdev_alloc();

my_cdev->ops = &fops;

my_cdev->owner = this_module;

兩種使用方式的功能是一樣的,只是使用的記憶體區不一樣,一般視實際的資料結構需求而定。

下面貼出了兩個函式的**,以具體看一下它們之間的差異。

struct cdev *cdev_alloc(void)

return p;

}void cdev_init(struct cdev *cdev, const struct file_operations *fops)

由此可見,兩個函式完成都功能基本一致,只是 cdev_init() 還多賦了乙個 cdev->ops 的值。

初始化 cdev 後,需要把它新增到系統中去。為此可以呼叫 cdev_add() 函式。傳入 cdev 結構的指標,起始裝置編號,以及裝置編號範圍。

int cdev_add(struct cdev *p, dev_t dev, unsigned count)

關於 kobj_map() 函式就不展開了,我只是大致講一下它的原理。核心中所有都字元裝置都會記錄在乙個 kobj_map 結構的 cdev_map 變數中。這個結構的變數中包含乙個雜湊表用來快速訪問所有的物件。kobj_map() 函式就是用來把字元裝置編號和 cdev 結構變數一起儲存到 cdev_map 這個雜湊表裡。當後續要開啟乙個字元裝置檔案時,通過呼叫 kobj_lookup() 函式,根據裝置編號就可以找到 cdev 結構變數,從而取出其中的 ops 字段。

當乙個字元裝置驅動不再需要的時候(比如模組解除安裝),就可以用 cdev_del() 函式來釋放 cdev 占用的記憶體。

void cdev_del(struct cdev *p)

其中 cdev_unmap() 呼叫 kobj_unmap() 來釋放 cdev_map 雜湊表中的物件。kobject_put() 釋放 cdev 結構本身。

字元裝置的註冊

前面提到,核心內部使用struct cdev結構來表示字元裝置。在核心呼叫裝置的操作之前,必須分配並註冊乙個或者多個上述結構。在 linux cdev.h 中定義了這個結構以及與其相關的一些輔助函式。如果需要動態的初始化,應該編寫如下 struct cdev my cdev cdev alloc m...

字元裝置編號的註冊分配

核心中所有已分配的字元裝置編號都記錄在乙個名為 chrdevs 雜湊表裡。該雜湊表中的每乙個元素是乙個 char device struct 結構,它的定義如下 static struct char device struct chrdevs chrdev major hash size 注意,核心...

Linux字元裝置驅動的註冊

很多學習linux程式設計的新人都會被字元裝置註冊搞糊塗了,我剛開始也一樣糊里糊塗的,看到網上例程有各種版本,就是呼叫module init時傳遞的實參,先記為 init 大家可能還會看到雜項裝置驅動misc register 平台裝置驅動platform device register 但是作為l...