17.12. 定制 ioctl 命令

2018-02-24 15:50 更新

17.12.?定制 ioctl 命令

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

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

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

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

當(dāng)這些命令中的一個(gè)被識別, dev->do_ioctl 在相關(guān)的接口驅(qū)動(dòng)中被調(diào)用. 這個(gè)函數(shù)接收與通用 ioctl 函數(shù)使用的相同的 struct ifreq * 指針.


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

ifr 指針指向一個(gè)內(nèi)核空間地址, 這個(gè)地址持有用戶傳遞的結(jié)構(gòu)的一個(gè)拷貝. 在 do_ioctl 返回之后, 結(jié)構(gòu)被拷貝回用戶空間; 因此, 驅(qū)動(dòng)可以使用這些私有命令接收和返回?cái)?shù)據(jù).

設(shè)備特定的命令可以選擇使用結(jié)構(gòu) ifreq 中的成員, 但是它們已經(jīng)傳達(dá)一個(gè)標(biāo)準(zhǔn)意義, 并且不可能驅(qū)動(dòng)使這個(gè)結(jié)構(gòu)適應(yīng)自己的需要. 成員 ifr_data 是一個(gè) caddr_t 項(xiàng)( 一個(gè)指針 ), 是打算用做設(shè)備特定的需要. 驅(qū)動(dòng)和用來調(diào)用它的 ioctl 命令的程序應(yīng)當(dāng)一致地使用 ifr_data. 例如, ppp-stats 使用設(shè)備特定的命令來從 ppp 接口驅(qū)動(dòng)獲取信息.

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

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

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號