LDD:字符設備驅動程序

1.主設備號和次設備號

對字符設備的訪問是通過文件系統內的設備名稱進行的。通常位於/dev/目錄下。

對於設備文件,ls -l命令可以看到兩個數,就是相應設備的主設備號和次設備號。

主設備號標識設備對應的驅動程序(driver)。次設備號由內核使用,用於正確確定設備文件所指的設備。

dev_t類型用來保存設備編號

MAJOR(dev_t dev)     MINOR(dev_t dev)     MKDEV(int major, int minor)

 

分配主設備號:

事先已知所需要的設備編號:register_chrdev_gegion

事先不知道設備使用的設備編號,動態分配:alloc_chrdev_region

釋放設備編號:unregister_chrdev_region

  

cat /proc/devices

mknod /dev/scull0 c $major 3

設備節點的訪問策略

*分配主設備號的最佳方式是:默認採用動態分配,同時保留在加載甚至是編譯時指定主設備號的餘地。

 

 

 

三個重要的內核數據結構

file_operations     file      inode

file_operations:用來將驅動程序操作連接到設備編號。

面向對象編程的例證:每個打開的文件(用struct file表示)和一組函數關聯(通常包含指向一個file_operations結構的f_op字段)。文件是一個“對象”,而操作它的函數是“方法”,對象聲明的動作將作用於其本身。

_ _user字符串:參數帶有_ _user字符串,表明指針是一個用戶空間地址,不能被直接引用

llseek   read    write    ioctl      mmap     open     release   

file_operation結構初始化的形式:

struct file_operation scull_fops = 

{

.owner = THIS_MODULE,

.llseek = scull_llseek,

.read = scull_read,

.write = scill_write,

.ioctl = scull_ioctl,

.open = scull_open,

.release = scull_release,

};

 

file:file結構表示一個打開的文件。

 

inode:文件索引信息

 

字符設備的註冊

struct cdev結構表示字符設備

cdev_alloc()    ——>    cdev_init     ——>    cdev_add()  

 

open和release方法 

open應完成如下工作:

1.檢查設備特定的錯誤(如設備未就緒或類似的硬件問題)

2.如果設備是首次打開,則對其進行初始化

3.如有必要,更新f_op指針。

4.分配並填寫置於filp->private_data裏的數據結構

container_of            

filp->private_data = dev

 

release方法

當關閉一個設備文件的次數比打開它的次數多時,系統中會發生什麼情況?例如大多數程序從來不打開它們的stdin文件(或設備),但它們都會在終止時被關閉。驅動程序如何才能知道一個打開的設備文件要被真正關閉?

答案很簡單:並不是每一個close系統調用都會引起release方法的調用。只有那些真正釋放設備數據結構的close調用纔會調用release。內核對每個file結構維護其被使用多少次的計數器,只有在file結構的計數歸0時,close系統調用纔會指向release方法。

 

 

scull的內存使用

對於驅動程序中任何不確定的或與策略相關的數組,用戶可以採用以下方法來修改:

編譯時,可以修改宏

模塊加載時,可以設置模塊參數

運行時,可以使用ioctl修改

 

read和write方法

read write方法的buff參數是用戶空間的指針。因此內核代碼不能直接引用其中的內容。

爲了確保安全,應該使用內核提供的專用函數:

copy_to_user

copy_from_user

scull的實現例程

 

readv和writev

這些“向量型”的函數具有一個結構數組,每個結構包含一個指向緩衝區的指針和一個長度值。

 

strace監視應用程序調用的系統調用以及它們的返回值。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章