一、cdev結構體
?成員/功能? | ?說明? | ?相關操作函數/宏? | |
---|---|---|---|
?kobj? | 內嵌的kobject對象,用于Linux設備模型管理,實現引用計數和sysfs接口 | kobject_init() | |
?owner? | 指向擁有該結構體的模塊指針(通常為THIS_MODULE ),防止模塊卸載時設備仍被使用 | 模塊宏THIS_MODULE | |
?ops? | 指向file_operations 結構體的指針,定義設備操作接口(如read /write ) | cdev_init() 初始化時綁定 | |
?list? | 鏈表頭,用于將多個cdev 連接成鏈表,由內核統一管理 | list_add() 等內核鏈表操作 | |
?dev? | 設備號(32位),高12位為主設備號,低20位為次設備號 | MKDEV() 、MAJOR() 、MINOR() | |
?count? | 設備實例數量(如一個驅動管理多個同類設備) | 注冊時通過cdev_add() 的count 參數指定 | |
?初始化函數? | cdev_init() :關聯cdev 與file_operations ;cdev_alloc() :動態分配cdev 內存 | cdev_init(struct cdev *, struct file_operations *) | |
?注冊/注銷函數? | cdev_add() :向內核注冊設備;cdev_del() :注銷設備 | 需配合register_chrdev_region() 或alloc_chrdev_region() 使用 | |
?設備號管理? | register_chrdev_region() :已知設備號時注冊;alloc_chrdev_region() :動態申請未占用設備號 | 釋放設備號需調用unregister_chrdev_region() |
?二、字符設備驅動的組成
?組件? | ?功能描述? | ?關鍵數據結構/API? | ?開發注意事項? |
---|---|---|---|
?設備號管理? | 標識設備實例(主設備號區分驅動,次設備號區分實例) | dev_t 類型、MKDEV() /MAJOR() /MINOR() 宏、register_chrdev_region() 或動態分配alloc_chrdev_region() 48 | 需避免直接操作設備號位寬,使用內核宏保證兼容性4 |
?cdev結構體? | 內核中描述字符設備的核心對象,關聯操作方法與設備號 | struct cdev (含kobj 、ops 、dev 等成員)、cdev_init() 初始化、cdev_add() 注冊58 | 需通過cdev_del() 注銷防止內存泄漏8 |
?file_operations? | 定義設備操作接口(如open /read /write /ioctl ) | struct file_operations (需實現至少owner 、read 、write 等函數指針)35 | 用戶空間數據交互需使用copy_{to,from}_user() 保證安全23 |
?設備文件節點? | 用戶空間訪問設備的入口(如/dev/xxx ) | 手動mknod 或自動生成(class_create() +device_create() )18 | 推薦自動生成節點以適配現代內核1 |
?模塊初始化/退出? | 驅動加載/卸載時的資源管理 | module_init() /module_exit() 宏、資源釋放函數(如unregister_chrdev_region() )12 | 必須實現清理邏輯防止殘留2 |
?同步機制? | 處理多進程/線程并發訪問 | mutex_lock() 、spin_lock() 等內核同步原語7 | 需根據場景選擇鎖類型(如互斥鎖適合長時間持有)7 |
?調試與日志? | 驅動調試信息輸出 | printk() 分級日志、dynamic_debug 動態調試3 | 生產環境需控制日志級別3 |
注意:
- ?完整驅動流程?:設備號申請 →?
cdev
初始化 → 實現file_operations
?→ 注冊設備 → 創建設備節點。 - ?用戶空間交互?:通過
/dev/
下的文件節點調用驅動接口,內核通過file_operations
轉發到具體函數。
?