欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
內核驅動(dòng)之ioctl接口的實(shí)現

http://blog.csdn.net/skyflying2012/article/details/8210799

2012

大部分驅動(dòng)需要 --除了讀寫(xiě)設備的能力 -- 通過(guò)設備驅動(dòng)進(jìn)行各種硬件控制的能力.大部分設備可進(jìn)行超出簡(jiǎn)單的數據傳輸之外的操作; 用戶(hù)空間必須常常能夠請求,例如, 設備鎖上它的門(mén), 彈出它的介質(zhì),報告錯誤信息, 改變波特率, 或者自我銷(xiāo)毀.這些操作常常通過(guò) ioctl 方法來(lái)支持, 它通過(guò)相同名子的系統調用來(lái)實(shí)現.

在用戶(hù)空間, ioctl系統調用有下面的原型:

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

ioctl驅動(dòng)方法有和用戶(hù)空間版本不同的原型:

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

inode filp 指針是對應應用程序傳遞的文件描述符 fd的值, 和傳遞給 open 方法的相同參數. cmd參數從用戶(hù)那里不改變地傳下來(lái), 并且可選的參數 arg 參數以一個(gè) unsigned long 的形式傳遞, 不管它是否由用戶(hù)給定為一個(gè)整數或一個(gè)指針.如果調用程序不傳遞第 3 個(gè)參數, 被驅動(dòng)操作收到的 arg值是無(wú)定義的. 因為類(lèi)型檢查在這個(gè)額外參數上被關(guān)閉, 編譯器不能警告你如果一個(gè)無(wú)效的參數被傳遞給 ioctl, 并且任何關(guān)聯(lián)的錯誤將難以查找.

ioctl命令數字應當在這個(gè)系統是唯一的,為了阻止向錯誤的設備發(fā)出正確的命令而引起的錯誤.為幫助程序員創(chuàng )建唯一的 ioctl命令代碼,這些編碼已被劃分為幾個(gè)位段.

定義 ioctl命令號的正確方法使用 4 個(gè)位段, 它們有下列的含義.這個(gè)列表中介紹的新符號定義在 <linux/ioctl.h>.

type

魔數.只是選擇一個(gè)數(在參考了 ioctl-number.txt之后)并且使用它在整個(gè)驅動(dòng)中.這個(gè)成員是 8 位寬(_IOC_TYPEBITS).

number

(順序).它是 8 (_IOC_NRBITS).

direction

數據傳送的方向,如果這個(gè)特殊的命令涉及數據傳送.可能的值是 _IOC_NONE(沒(méi)有數據傳輸), _IOC_READ, _IOC_WRITE, _IOC_READ|_IOC_WRITE (數據在2個(gè)方向被傳送).數據傳送是從應用程序的觀(guān)點(diǎn)來(lái)看待的; _IOC_READ意思是從設備讀, 因此設備必須寫(xiě)到用戶(hù)空間. 注意這個(gè)成員是一個(gè)位掩碼, 因此 _IOC_READ _IOC_WRITE可使用一個(gè)邏輯 AND 操作來(lái)抽取.

size

涉及到的用戶(hù)數據的大小.這個(gè)成員的寬度是依賴(lài)體系的, 但是常常是 13 或者 14 . 你可為你的特定體系在宏 _IOC_SIZEBITS中找到它的值. 你使用這個(gè) size 成員不是強制的 -內核不檢查它 -- 但是它是一個(gè)好主意. 正確使用這個(gè)成員可幫助檢測用戶(hù)空間程序的錯誤并使你實(shí)現向后兼容,如果你曾需要改變相關(guān)數據項的大小. 如果你需要更大的數據結構,但是, 你可忽略這個(gè) size 成員.我們很快見(jiàn)到如何使用這個(gè)成員.

定義宏來(lái)幫助建立命令號,如下:

 _IO(type,nr)(給沒(méi)有參數的命令),

_IOR(type, nre, datatype)(給從驅動(dòng)中讀數據的),

_IOW(type,nr,datatype)(給寫(xiě)數據),

 _IOWR(type,nr,datatype)(給雙向傳送).

type number成員作為參數被傳遞,并且 size成員通過(guò)應用 sizeof datatype參數而得到.

驅動(dòng)中來(lái)解碼這個(gè)號:_IOC_DIR(nr), _IOC_TYPE(nr), _IOC_NR(nr), _IOC_SIZE(nr).

 

/* Ioctlün */

#define MEM_IOC_MAGIC 'k'  

 

#define MEM_IOC_RESET   _IO(MEM_IOC_MAGIC, 0)     

#define MEM_IOC_GET     _IOR(MEM_IOC_MAGIC, 1, int)

#define MEM_IOC_SET     _IOW(MEM_IOC_MAGIC, 2, int)

 

使用 ioctl參數

在看 scull驅動(dòng)的 ioctl 代碼之前, 我們需要涉及的另一點(diǎn)是如何使用這個(gè)額外的參數.如果它是一個(gè)整數, 就容易: 它可以直接使用.如果它是一個(gè)指針, 但是, 必須小心些.

當用一個(gè)指針引用用戶(hù)空間,我們必須確保用戶(hù)地址是有效的. 試圖存取一個(gè)沒(méi)驗證過(guò)的用戶(hù)提供的指針可能導致不正確的行為,一個(gè)內核 oops, 系統崩潰, 或者安全問(wèn)題.它是驅動(dòng)的責任來(lái)對每個(gè)它使用的用戶(hù)空間地址進(jìn)行正確的檢查, 并且返回一個(gè)錯誤如果它是無(wú)效的.

copy_from_user copy_to_user函數, 它們可用來(lái)安全地移動(dòng)數據到和從用戶(hù)空間.這些函數也可用在 ioctl 方法中, 但是 ioctl調用常常包含小數據項, 可通過(guò)其他方法更有效地操作. 開(kāi)始, 地址校驗(不傳送數據)由函數 access_ok實(shí)現, 它定義在 <asm/uaccess.h>:

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

第一個(gè)參數應當是 VERIFY_READ或者 VERIFY_WRITE, 依據這個(gè)要進(jìn)行的動(dòng)作是否是讀用戶(hù)空間內存區或者寫(xiě)它. addr參數持有一個(gè)用戶(hù)空間地址, size 是一個(gè)字節量. 例如, 如果 ioctl 需要從用戶(hù)空間讀一個(gè)整數, size sizeof(int). 如果你需要讀和寫(xiě)給定地址, 使用 VERIFY_WRITE, 因為它是 VERIRY_READ 的超集.

不象大部分的內核函數, access_ok返回一個(gè)布爾值: 1 是成功(存取沒(méi)問(wèn)題) 0是失敗(存取有問(wèn)題). 如果它返回假,驅動(dòng)應當返回 -EFAULT 給調用者.

ioctl命令的實(shí)現

 

long mem_ioctl(struct file*filp,unsignedint cmd,unsignedlong arg)

{

    struct mem_dev *dev= filp->private_data;

   int ret=0, err =0;

 

   /*ünēАД */

   if(_IOC_TYPE(cmd)!= MEM_IOC_MAGIC)

       return-ENOTTY;

   if(_IOC_NR(cmd)> MEM_IOC_MAXNR)

       return-ENOTTY;

   

   /*n*/

   if(_IOC_DIR(cmd)& _IOC_READ) 

       err =!access_ok(VERIFY_WRITE,(void __user *)arg, _IOC_SIZE(cmd));

   elseif(_IOC_DIR(cmd)& _IOC_WRITE)       

       err = !access_ok(VERIFY_READ,(void __user *)arg, _IOC_SIZE(cmd));

   if(err)       

       return-EFAULT;

 

   /*

   switch(cmd)

   {

   case MEM_IOC_RESET:

       dev->size=0;

       break;

       

   case MEM_IOC_GET:

       ret = put_user(dev->size,(int __user *) arg);

       break;

       

   case MEM_IOC_SET:

       ret = get_user(dev->size,(int __user *) arg);

       break;

       

   default:   

       return-EINVAL;    

   }

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
ioctl(int fd,unsigned long cmd,...)命令詳解
Linux設備驅動(dòng)之Ioctl控制
Linux驅動(dòng)總結3- unlocked_ioctl和堵塞(waitqueue)讀寫(xiě)函數的實(shí)現
ioctl()
linux設備驅動(dòng)歸納總結(三):4.ioctl的實(shí)現
linux內核驅動(dòng)中_IO, _IOR, _IOW, _IOWR 宏的用法與解析
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久