日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux中字符设备注册方式,3.4. 字符设备注册

發布時間:2025/3/15 linux 7 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux中字符设备注册方式,3.4. 字符设备注册 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

3.4.?字符設備注冊

如我們提過的, 內核在內部使用類型 struct cdev 的結構來代表字符設備. 在內核調用你的設備操作前, 你編寫分配并注冊一個或幾個這些結構. [11]為此, 你的代碼應當包含 , 這個結構和它的關聯幫助函數定義在這里.

有 2 種方法來分配和初始化一個這些結構. 如果你想在運行時獲得一個獨立的 cdev 結構, 你可以為此使用這樣的代碼:

struct cdev *my_cdev = cdev_alloc();

my_cdev->ops = &my_fops;

但是, 偶爾你會想將 cdev 結構嵌入一個你自己的設備特定的結構; scull 這樣做了. 在這種情況下, 你應當初始化你已經分配的結構, 使用:

void cdev_init(struct cdev *cdev, struct file_operations *fops);

任一方法, 有一個其他的 struct cdev 成員你需要初始化. 象 file_operations 結構, struct cdev 有一個擁有者成員, 應當設置為 THIS_MODULE. 一旦 cdev 結構建立, 最后的步驟是把它告訴內核, 調用:

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

這里, dev 是 cdev 結構, num 是這個設備響應的第一個設備號, count 是應當關聯到設備的設備號的數目. 常常 count 是 1, 但是有多個設備號對應于一個特定的設備的情形. 例如, 設想 SCSI 磁帶驅動, 它允許用戶空間來選擇操作模式(例如密度), 通過安排多個次編號給每一個物理設備.

在使用 cdev_add 是有幾個重要事情要記住. 第一個是這個調用可能失敗. 如果它返回一個負的錯誤碼, 你的設備沒有增加到系統中. 它幾乎會一直成功, 但是, 并且帶起了其他的點: cdev_add 一返回, 你的設備就是"活的"并且內核可以調用它的操作. 除非你的驅動完全準備好處理設備上的操作, 你不應當調用 cdev_add.

為從系統去除一個字符設備, 調用:

void cdev_del(struct cdev *dev);

顯然, 你不應當在傳遞給 cdev_del 后存取 cdev 結構.

3.4.1.?scull 中的設備注冊

在內部, scull 使用一個 struct scull_dev 類型的結構表示每個設備. 這個結構定義為:

struct scull_dev {

struct scull_qset *data; /* Pointer to first quantum set */

int quantum; /* the current quantum size */

int qset; /* the current array size */

unsigned long size; /* amount of data stored here */

unsigned int access_key; /* used by sculluid and scullpriv */

struct semaphore sem; /* mutual exclusion semaphore */

struct cdev cdev; /* Char device structure */

};

我們在遇到它們時討論結構中的各個成員, 但是現在, 我們關注于 cdev, 我們的設備與內核接口的 struct cdev. 這個結構必須初始化并且如上所述添加到系統中; 處理這個任務的 scull 代碼是:

static void scull_setup_cdev(struct scull_dev *dev, int index)

{

int err, devno = MKDEV(scull_major, scull_minor + index);

cdev_init(&dev->cdev, &scull_fops);

dev->cdev.owner = THIS_MODULE;

dev->cdev.ops = &scull_fops;

err = cdev_add (&dev->cdev, devno, 1);

/* Fail gracefully if need be */

if (err)

printk(KERN_NOTICE "Error %d adding scull%d", err, index);

}

因為 cdev 結構嵌在 struct scull_dev 里面, cdev_init 必須調用來進行那個結構的初始化.

3.4.2.?老方法

如果你深入瀏覽 2.6 內核的大量驅動代碼, 你可能注意到有許多字符驅動不使用我們剛剛描述過的 cdev 接口. 你見到的是還沒有更新到 2.6 內核接口的老代碼. 因為那個代碼實際上能用, 這個更新可能很長時間不會發生. 為完整, 我們描述老的字符設備注冊接口, 但是新代碼不應當使用它; 這個機制在將來內核中可能會消失.

注冊一個字符設備的經典方法是使用:

int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);

這里, major 是感興趣的主編號, name 是驅動的名子(出現在 /proc/devices), fops 是缺省的 file_operations 結構. 一個對 register_chrdev 的調用為給定的主編號注冊 0 - 255 的次編號, 并且為每一個建立一個缺省的 cdev 結構. 使用這個接口的驅動必須準備好處理對所有 256 個次編號的 open 調用( 不管它們是否對應真實設備 ), 它們不能使用大于 255 的主或次編號.

如果你使用 register_chrdev, 從系統中去除你的設備的正確的函數是:

int unregister_chrdev(unsigned int major, const char *name);

major 和 name 必須和傳遞給 register_chrdev 的相同, 否則調用會失敗.

[11]有一個早些的機制以避免使用 cdev 結構(我們在"老方法"一節中討論).但是, 新代碼應當使用新技術.

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的Linux中字符设备注册方式,3.4. 字符设备注册的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。