17.12. 定制 ioctl 命令

2018-02-24 15:50 更新

17.12.?定制 ioctl 命令

我們硬件看到給 socket 實現(xiàn)的 ioctl 系統(tǒng)調用; SIOCSIFADDR 和 SIOCSIFMAP 是 "socket ioctls" 的例子. 現(xiàn)在我們看看網絡代碼如何使用這個系統(tǒng)調用的 3 個參數(shù).

當 ioctl 系統(tǒng)調用在一個 socket 上被調用, 命令號是 <linux/sockios.h>中定義的符號中的一個, 并且 sock_ioctl 函數(shù)直接調用一個協(xié)議特定的函數(shù)(這里"協(xié)議"指的是使用的主要網絡協(xié)議, 例如, IP 或者 AppleTalk).

任何協(xié)議層不識別的 ioctl 命令傳遞給設備層. 這些設備有關的 ioctl 命令從用戶空間接收一個第 3 個參數(shù), 一個 struct ifreq*. 這個結構定義在 <linux/if.h>. SIOCSIFADDR 和 SIOCSIFMAP 命令實際上在 ifreq 結構上工作. SIOCSIFMAP 的額外參數(shù), 定義為 ifmap, 只是 ifreq 的一個成員.

除了使用標準調用, 每個接口可以定義它自己的 ioctl 命令. plip 接口, 例如, 允許接口通過 ioctl 修改它內部的超時值. socket 的 ioctl 實現(xiàn)認識 16 作為接口私有的個命令: SIOCDEVPRIVATE 到 SIOCDEVPRIVATE+15.[53]

當這些命令中的一個被識別, dev->do_ioctl 在相關的接口驅動中被調用. 這個函數(shù)接收與通用 ioctl 函數(shù)使用的相同的 struct ifreq * 指針.


int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); 

ifr 指針指向一個內核空間地址, 這個地址持有用戶傳遞的結構的一個拷貝. 在 do_ioctl 返回之后, 結構被拷貝回用戶空間; 因此, 驅動可以使用這些私有命令接收和返回數(shù)據(jù).

設備特定的命令可以選擇使用結構 ifreq 中的成員, 但是它們已經傳達一個標準意義, 并且不可能驅動使這個結構適應自己的需要. 成員 ifr_data 是一個 caddr_t 項( 一個指針 ), 是打算用做設備特定的需要. 驅動和用來調用它的 ioctl 命令的程序應當一致地使用 ifr_data. 例如, ppp-stats 使用設備特定的命令來從 ppp 接口驅動獲取信息.

這里不值得展示一個 do_ioctl 的實現(xiàn), 但是有了本章的信息和內核例子, 你應當能夠在你需要時編寫一個. 注意, 但是, plip 實現(xiàn)使用 ifr_data 不正確, 不應當作為一個 ioctl 實現(xiàn)的例子.

[53] 注意, 根據(jù) <linux/sockios.h>, SIOCDEVPRIVATE 命令是被不贊成的. 應當使用什么來代替它們是不明確的, 但是, 并且不少在目錄樹中的驅動還使用它們.

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號