Ioctl使用及與unlocked ioctl區別

2021-06-27 16:20:32 字數 2707 閱讀 7632

1. ioctl 用來做什麼?

大部分驅動除了需要具備讀寫裝置的能力外,還需要具備對硬體控制的能力。例如,要求裝置報告錯誤資訊,改變波特率,這些操作常常通過ioctl方法來實現。

1.1 使用者使用方法

在使用者空間,使用ioctl 系統呼叫來控制裝置,原型如下:

int ioctl(int fd,unsigned long cmd,...)

原型中的點表示這是乙個可選的引數,存在與否依賴於控制命令(第2 個引數)是否涉及到與裝置的資料互動。

1.2 驅動ioctl方法

ioctl 驅動方法有和使用者空間版本不同的原型:

int (*ioctl)(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)

cmd引數從使用者空間傳下來,可選的引數arg 以乙個unsigned long 的形式傳遞,不管它是乙個整數或乙個指標。如果cmd命令不涉及資料傳輸,則第3 個引數arg的值無任何意義。

2. ioctl實現

2.1 實現ioctl方法的步驟:

1)  定義命令

2.)  實現命令

2.2 定義命令

在編寫ioctl**之前,首先需要定義命令。為了防止對錯誤的裝置使用正確的命令,命令號應該在系統範圍內是唯一的。ioctl 命令編碼被劃分為幾個位段,include/asm/ioctl.h中定義了這些位欄位:型別(幻數),序號,傳送方向,引數的大小。documentation/ioctl-number.txt檔案中羅列了在核心中已經使用了的幻數。

定義ioctl 命令的正確方法是使用4 個位段, 這個列表中介紹的符號定義在中:

1) type

幻數(型別): 表明哪個裝置的命令,在參考了ioctlnumber.txt之後選出,8 位寬。

2)  number

序號,表明裝置命令中的第幾個,8 位寬

3) direction

資料傳送的方向,可能的值是_ioc_none(沒有資料傳輸),_ioc_read, _ioc_write。資料傳送是從應用程式的觀點來看待的,_ioc_read 意思是從裝置讀。

4) size

使用者資料的大小。(13/14位寬,視處理器而定)

核心提供了下列巨集來幫助定義命令:

1)  _io(type,nr)

沒有引數的命令

2)  _ior(type,nr,datatype)

從驅動中讀資料

3)  _iow(type,nr,datatype)

寫資料到驅動

4) _iowr(type,nr,datatype)

雙向傳送,type 和number 成員作為引數被傳遞。

定義命令(範例)

#define mem_ioc_magic 『m』 //定義幻數

#define mem_iocset

_iow(mem_ioc_magic, 0, int)

#define mem_iocgqset

_ior(mem_ioc_magic, 1, int)

2.3 ioctl函式實現

定義好了命令,下一步就是要實現ioctl函式了,ioctl函式的實現包括如下3個技術環節:

1)  返回值

2) 引數使用

3) 命令操作

2.3.1 ioctl函式實現(返回值)

ioctl函式的實現通常是根據命令執行的乙個switch語句。但是,當命令號不能匹配任何乙個裝置所支援的命令時,通常返回-einval(「非法引數」)。

2.3..2 ioctl函式實現(引數)

如何使用ioctl中的引數?

如果是乙個整數,可以直接使用。如果是指標,我們必須確保這個使用者位址是有效的,因此使用前需進行正確的檢查。

2.3.3 ioctl函式實現(引數檢查)

不需要檢測:

1) copy_from_user

2) copy_to_user

3) get_user

4) put_user

需要檢測:

1) __get_user

2) __put_user

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

第乙個引數是verify_read 或者verify_write,用來表明是讀使用者記憶體還是寫使用者記憶體。addr 引數是要操作的使用者記憶體位址,size 是操作的長度。如果ioctl 需要從使用者空間讀乙個整數,那麼size引數等於sizeof(int)。access_ok 返回乙個布林值: 1 是成功(訪問沒問題)和0 是失敗(訪問有問題),如果該函式返回失敗, 則ioctl應當返回–efault 。

2.3 ioctl與unlocked_ioctl的區別

使用ioctl的函式宣告為:(int *ioctl)(struct inode *inodep, struct file *filp, unsigned int cmd, unsigned long arg)

使用unlock_ioctl的函式宣告:(int *ioctl)(struct file *filp, unsigned int cmd, unsigned long arg)

不然會導致傳入的cmd改變

使用ioctl與核心交換資料

1.前言 使用ioctl 系統呼叫是使用者空間向核心交換資料的常用方法之一,從 ioctl 這個名稱上看,本意是針對 i o裝置進行的控制操作,但實際並不限制是真正的 i o裝置,可以是任何乙個核心裝置即可。2.基本過程 在核心空間中 ioctl 是很多核心操作結構的乙個成員函式,如檔案操作結構 s...

使用ioctl與核心交換資料

1.前言 使用ioctl系統呼叫是使用者空間向核心交換資料的常用方法之一,從ioctl這個名稱上看,本意是針對i o裝置進行的控制操作,但實際並不限制是真正的i o裝置,可以是任何乙個核心裝置即可。2.基本過程 在核心空間中ioctl是很多核心操作結構的乙個成員函式,如檔案操作結構struct fi...

linux系統ioctl使用示例

linux系統ioctl使用示例 these were writed and collected by kf701,you can use and modify them but no warranty.contact with me kf 701 21cn.com 程式1 檢測介面的 inet a...