裝置驅動程式學習筆記 4 裝置控制ioctl方法

2021-04-28 21:36:41 字數 3841 閱讀 4926

by:

潘雲登

對於商業目的下對本文的任何行為需經作者同意。

寫在前面

1.本文內容對應《

linux

裝置驅動程式》第六章。 2.

參考俞永昌的《裝置驅動開發技術及應用》,以及

documentation/ioctl-number.txt

和include/asm/ioctl.h

兩個檔案。 3.

裝置控制

ioctl

對於那種不傳送資料而只響應命令的裝置,如機械人

j,可以通過向裝置寫入控制序列進行控制。然而,對於具備讀寫操作的裝置,通過列印序列進行控制將給裝置增加策略限制。更好的裝置控制方式是

ioctl

方法。在使用者空間,

ioctl

系統呼叫具有如下原型:

int ioctl(int fd, unsigned long cmd, char *argp);

控制命令

cmd由使用者空間不加修改地傳遞到驅動程式的

ioctl

方法。argp

為可選引數,它可以是乙個整型引數或者是乙個指標引數,具體形式依賴於要完成的控制命令

cmd。使用指標可以向

ioctl

呼叫傳遞任意資料,從而與使用者空間交換任意數量的資料。不論

argp

是何種型別,它都以

unsigned long

的形式傳遞給驅動程式。然後,由驅動程式根據具體情況進行型別轉換,如轉換為整型指標(

int __user *

)arg

,__user

表明指標是乙個使用者空間位址,不能直接引用。驅動程式的

ioctl

方法原型如下:

int (*ioctl) (struct inode *inode, struct file *filp,

unsigned int cmd, unsigned long arg);

其返回值,也是系統呼叫的返回值,可以向使用者空間提供裝置資訊。負的返回值被認為是乙個錯誤,通常為

-enotty (

不合適的裝置

ioctl)

或-einval (

非法引數

),被用來設定使用者空間的

errno

變數。

控制命令

高位低位 2

位 14位

8位 8位

direction

size

number

type

øtype

:幻數,可以在

documentation/ioctl-number.txt

中選擇乙個未使用的號碼。如果整個控制命令能夠被核心識別,將無法到達驅動程式。 ø

number

:序數,一般從

0開始順序編號。 ø

size

:使用者資料大小,用於檢查引數型別的大小,如

sizeof(int) < (1 << size)。

ødirection

:資料傳輸方向,可以使用的值包括

_ioc_none (

無資料傳輸),

_ioc_read (

從裝置中讀資料),

_ioc_write (

向裝置寫資料

),以及

_ioc_read|_ioc_write (

雙向資料傳輸)。

中包含的

標頭檔案定義了一些構造命令編號的巨集:

_io(type,nr)

_ior(type,nr,datatype)

_iow(type,nr,datatype)

_iowr(type,nr,datatype)

以及用於解開位字段的巨集:

_ioc_type(nr)

_ioc_nr(nr)

_ioc_size(nr)

_ioc_dir(nr)

大多數ioctl

的實現中都包含了乙個

switch

語句來根據控制命令選擇對應的操作。

ioctl

工作模型

scull

中的幾處檢查

ø控制命令檢查

檢查裝置幻數和命令序數。

if (_ioc_type(cmd) != scull_ioc_magic) return -enotty;

if (_ioc_nr(cmd) > scull_ioc_maxnr) return -enotty;

ø使用者位址空間檢查

當用乙個指標指向使用者空間時,必須確保指向的使用者空間是合法的,這通過

access_ok

函式完成。通常不需要真正呼叫

access_ok

,因為資料交換函式

copy_to_user, copy_from_user, put_user, get_user

會處理它。

int access_ok(int type, const void *addr, unsigned long size);

/*scull*/

if (_ioc_dir(cmd) & _ioc_read)

err = !access_ok(verify_write, (void __user *)arg, _ioc_size(cmd));

else if (_ioc_dir(cmd) & _ioc_write)

err =!access_ok(verify_read, (void __user *)arg, _ioc_size(cmd));

if (err) return -efault;

ø權能檢查

對裝置的讀寫訪問由裝置檔案的許可權控制,驅動程式通常不進行許可權檢查。然而,當使用者試圖修改裝置引數時,裝置驅動程式應該檢查呼叫程序是否有合適的權能,這通過

capable

函式完成。

int capable(int capability);

/*scull*/

if (! capable (cap_sys_admin))

return -eperm;

裝置驅動程式學習筆記 6 裝置訪問控制

by 潘雲登 對於商業目的下對本文的任何行為需經作者同意。寫在前面 1.本文內容對應 linux 裝置驅動程式 第六章。2.修改scull load 指令碼中的 mode 為 666 使普通使用者具有裝置讀寫許可權。3.希望本文對您有所幫助,也歡迎您給我提意見和建議。這裡描述的裝置訪問控制是在檔案系...

筆記 裝置驅動程式

驅動程式一般指的是裝置驅動程式 device driver 是一種可以使 計算機和裝置通訊的特殊程式。相當於 硬體的介面,作業系統只有通過這個介面,才能控制 硬體裝置的工作,假如某裝置的驅動程式未能正確安裝,便不能正常工作。因此,驅動程式被比作 硬體的靈魂 硬體的主宰 和 硬體和系統之間的橋梁 等。...

linux裝置驅動程式 字元裝置驅動程式

先留個 有一起學習驅動程式的加qq295699450 字元裝置驅動 這篇比較惱火。載入成功,但是讀不出來資料,有知道怎麼回事的,留個言,一起討論下 資料結構 struct scull mem struct scull dev dev 整個驅動程式 如下 include include include...