亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? (ldd) ch05-字符設備驅動程序的擴展操作.txt

?? 獻給ARM初學者
?? TXT
?? 第 1 頁 / 共 4 頁
字號:
(LDD) Ch05-字符設備驅動程序的擴展操作

      第5章 字符設備驅動程序的擴展操作
       
       
      在關于字符設備驅動程序的那一章中,我們構建了一個完整的設備驅動程序,從中用戶
      可以讀也可以寫。但實際一個驅動程序通常會提供比同步read和write更多的功能?,F在
      如果出了什么毛病,我已經配備了調試工具,我們可以大膽的實驗并實現新操作。
       
      通過補充設備讀寫操作的功能之一就是控制硬件,最常用的通過設備驅動程序完成控制
      動作的方法就是實現ioctl方法。另一種方法是檢查寫到設備中的數據流,使用特殊序列
      做為控制命令。盡管有時也使用后者,但應該盡量避免這樣使用。不過稍后我們還是會
      在本章的“非ioctl設備控制”一節中介紹這項技術。
       
      正如我在前一章中所猜想的,ioctl系統調用為驅動程序執行“命令”提供了一個設備相
      關的入口點。與read和其他方法不同,ioctl是設備相關的,它允許應用程序訪問被驅動
      硬件的特殊功能――配置設備以及進入或退出操作模式。這些“控制操作”通常無法通

      硬件的特殊功能――配置設備以及進入或退出操作模式。這些“控制操作”通常無法通
      過read/write文件操作完成。例如,你向串口寫的所有數據都通過串口發送出去了,你
      無法通過寫設備改變波特率。這就是ioctl所要做的:控制I/O通道。
       
      實際設備(與scull不同)的另一個重要功能是,讀或寫的數據需要同其他硬件交互,需
      要某些同步機制。阻塞型I/O和異步觸發的概念將滿足這些需求,本章將通過一個改寫的
      scull設備介紹這些內容。驅動程序利用不同進程間的交互產生異步事件。與最初的scul
      l相同,你無需特殊硬件來測試驅動程序是否可以工作。直到第8章“硬件管理”我才會
      真正去與硬件打交道。
       
      ioctl
      在用戶空間內調用ioctl函數的原型大致如下:
       
      (代碼)
       
      由于使用了一連串的“.”的緣故,該原型在Unix系統調用列表之中非常突出,這些點代
      表可變數目參數。但是在實際系統中,系統調用實際上不會有可變數目個參數。因為用
      戶程序只能通過第2章“編寫和運行模塊”的“用戶空間和內核空間”一節中介紹的硬件
      “門”才能訪問內核,系統調用必須有精確定義的參數個數。因此,ioctl的第3個參數
      事實上只是一個可選參數,這里用點只是為了在編譯時防止編譯器進行類型檢查。第3個
      參數的具體情況與要完成的控制命令(第2個參數)有關。某些命令不需要參數,某些需
      要一個整數做參數,而某些則需要一個指針做參數。使用指針通常是可以用來向ioctl傳
      遞任意數目數據;設備可以從用戶空間接收任意大小的數據。

      遞任意數目數據;設備可以從用戶空間接收任意大小的數據。
       
      系統調用的參數根據方法的聲明傳遞給驅動程序方法:
       
      (代碼)
       
      inode和filp指針是根據應用程序傳遞的文件描述符fd計算而得的,與read和write的用
      法一致。參數cmd不經修改地傳遞給驅動程序,可選的arg參數無論是指針還是整數值,
      它都以unsigned long的形式傳遞給驅動程序。如果調用程序沒有傳遞第3個參數,驅動
      程序所接收的arg沒有任何意義。
       
      由于附加參數的類型檢查被關閉了,如果非法參數傳遞給ioctl,編譯器無法向你報警,
      程序員在運行前是無法注意這個錯誤的。這是我所見到的ioctl語義方面的唯一一個問題
      。
       
      如你所想,大多數ioctl實現都包括一個switch語句來根據cmd參數選擇正確的操作。不
      同的命令對應不同的數值,為了簡化代碼我們通常會使用符號名代替數值。這些符號名
      都是在預處理中賦值的。不同的驅動程序通常會在它們的頭文件中聲明這些符號;scull
      就在scull.h中聲明了這些符號。
       
      選擇ioctl命令
      在編寫ioctl代碼之前,你需要選擇對應不同命令的命令號。遺憾的是,簡單地從1開始
      選擇號碼是不能奏效的。

      選擇號碼是不能奏效的。
       
      為了防止對錯誤的設備使用正確的命令,命令號應該在系統范圍內是唯一的。這種失配
      并不是不很容易發生,程序可能發現自己正在對象FIFO和kmouse這類非串口輸入流修改
      波特率。如果每一個ioctl命令都是唯一的,應用程序就會獲得一個EINVAL錯誤,而不是
      無意間成功地完成了操作。
       
      為了達到唯一性的目的,每一個命令號都應該由多個位字段組成。Linux的第一版使用了
      一個16位整數:高8位是與設備相關的“幻”數,低8位是一個序列號碼,在設備內是唯
      一的。這是因為,用Linus的話說,他有點“無頭緒”,后來才接收了一個更好的位字段
      分割方案。遺憾的是,很少有驅動程序使用新的約定,這就挫傷了程序員使用新約定的
      熱情。在我的源碼中,為了發掘這種約定都提供了那些功能,同時防止被其他開發人員
      當成異教徒而禁止,我使用了新的定義命令的方法。
       
      為了給我的驅動程序選擇ioctl號,你應該首先看看include/asm/ioctl.h和Documentati
      on/ioctl-number.txt這兩個文件。頭文件定義了位字段:類型(幻數),基數,傳送方
      向,參數的尺寸等等。ioctl-number.txt文件中羅列了在內核中使用的幻數。這個文件
      的新版本(2.0以及后繼內核)也給出了為什么應該使用這個約定的原因。
       
      很不幸,在1.2.x中發行的頭文件沒有給出切分ioctl位字段宏的全集。如果你需要象我
      的scull一樣使用這種新方法,同時還要保持向后兼容性,你使用scull/sysdep.h中的若
      干代碼行,我在那里給出了解決問題的文檔的代碼。
       

       
      現在已經不贊成使用的選擇ioctl號碼的舊方法非常簡單:選擇一個8位幻數,比如“k”
      (十六進制為0x6b),然后加上一個基數,就象這樣:
       
      (代碼)
       
      如果應用程序和驅動程序都使用了相同的號碼,你只要在驅動程序里實現switch語句就
      可以了。但是,這種在傳統Unix中有基礎的定義ioctl號碼的方法,不應該再在新約定中
      使用。這里我介紹就方法只是想給你看看一個ioctl號碼大致是個什么樣子的。
       
      新的定義號碼的方法使用了4個位字段,它們有如下意義。下面我所介紹的新符號都定義
      在<linux/ioctl.h>中。
       
      類型
       
      幻數。選擇一個號碼,并在整個驅動程序中使用這個號碼。這個字段有8位寬(_IOC_TYP
      EBITS)。
       
      號碼
       
      基(序列)數。它也是8位寬(_IOC_NRBITS)。
       
      方向

      方向
       
      如果該命令有數據傳輸,它定義數據傳輸的方向??梢允褂玫闹涤?,_IOC_NONE(沒有數
      據傳輸),_IOC_READ,_IOC_WRITE和_IOC_READ | _IOC_WRITE(雙向傳輸數據)。數據
      傳輸是從應用程序的角度看的;IOC_READ意味著從設備中讀數據,驅動程序必須向用戶
      空間寫數據。注意,該字段是一個位屏蔽碼,因此可以用邏輯AND操作從中分解出_IOC_R
      EAD和_IOC_WRITE。
       
      尺寸
       
      所涉及的數據大小。這個字段的寬度與體系結構有關,當前的范圍從8位到14位不等。你
      可以在宏_IOC_SIZEBITS中找到某種體系結構的具體數值。不過,如果你想要你的驅動程
      序可移植,你只能認為最大尺寸可達255個字節。系統并不強制你使用這個字段。如果你
      需要更大尺度的數據傳輸,你可以忽略這個字段。下面我們將介紹如何使用這個字段。
       
      包含在<linux/ioctl.h>之中的頭文件<asm/ioctl.h>定義了可以用來構造命令號碼的宏
      :_IO(type,nr),_IOR(type,nr,size),_IOW(type,nr,size)和IOWR(type,nr,size)。
      每一個宏都對應一種可能的數據傳輸方向,其他字段通過參數傳遞。頭文件還定義了解
      碼宏:_IOC_DIR(nr),_IOC_TYPE(nr),_IOC_NR(nr)和_IOC_SIZE(nr)。我不打算詳細介
      紹這些宏,頭文件里的定義已經足夠清楚了,本節稍后會給出樣例。
       
      這里是scull中如果定義ioctl命令的。特別地,這些命令設置并獲取驅動程序的配置參
      數。在標準的宏定義中,要傳送的數據項的尺寸有數據項自身的實例代表,而不是sizeo

      數。在標準的宏定義中,要傳送的數據項的尺寸有數據項自身的實例代表,而不是sizeo
      f(item),這是因為sizeof是宏擴展后的一部分。
       
      (代碼)
       
      最后一條命令,HARDRESET,用來將模塊使用計數器復位為0,這樣就可以在計數器發生
      錯誤時就可以卸載模塊了。實際的源碼定義了從IOCHQSET到HARDRESET間的所有命令,但
      這里沒有列出。
       
      我選擇用兩種方法實現整數參數傳 莰D―通過指針和顯式數值,盡管根據已有的約定,i
      octl應該使用指針完成數據交換。同樣,這兩種方法還用于返回整數:通過指針和設置
      返回值。如果返回值是正的,這就可以工作;對與任何一個系統調用的返回值,正值是
      受保護的(如我們在read和write所見到的),而負值則被認為是一個錯誤值,用其設置
      用戶空間中的errno變量。
       
      “交換”和“移位”操作并不專用于scull設備。我實現“交換”操作是為了給出“方向
      ”字段的所有可能值,而“移位”操作則將“告知”和“查詢”操作組合在一起。某些
      時候是需要原子性*測試兼設置這類操作的――特別是當應用程序需要加鎖和解鎖時。
       
      顯式的命令基數沒有什么特殊意義。它只是用來區分命令的。事實上,由于ioctl號碼的
      “方向”為會有所不同,你甚至可以在讀命令和寫命令中使用同一個基數。我選擇除了
      在聲明中使用基數外,其他地方都不使用它,這樣我就不必為符號值賦值了。這也是為
      什么顯式的號碼出現在上面的定義中。我只是向你介紹一種使用命令號碼的方法,你可

      什么顯式的號碼出現在上面的定義中。我只是向你介紹一種使用命令號碼的方法,你可
      以自由地采用不同的方法使用它。
       
      當前,參數cmd的值內核并沒有使用,而且以后也不可能使用。因此,如果你想偷懶,你
      可以省去上面那些復雜的聲明,而直接顯式地使用一組16位數值。但另一方面,如果你
      這樣做了,你就無法從使用位字段中受益了。頭文件<linux/kd.h>就是這種舊風格方法
      的例子,但是它們并不是因為偷懶才這樣做的。修改這個文件需要重新編譯許多應用程
      序。
       

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美性欧美巨大黑白大战| 久久成人久久鬼色| 91丨九色丨黑人外教| 国产精品动漫网站| 91猫先生在线| 亚洲成人午夜影院| 欧美一区二区精美| 精品制服美女久久| 欧美激情综合五月色丁香| 国产不卡在线播放| 中文字幕一区在线| 欧洲av在线精品| 日韩不卡一区二区三区 | 国产亚洲欧洲997久久综合 | 一本色道a无线码一区v| 亚洲美女免费视频| 欧美日韩一级二级| 美国av一区二区| 国产欧美日韩另类一区| 色婷婷精品大在线视频| 五月天久久比比资源色| 精品国产乱码久久久久久免费| 国产一区二区导航在线播放| 国产精品嫩草影院av蜜臀| 色综合久久88色综合天天免费| 亚洲国产精品精华液网站| 日韩视频在线观看一区二区| 丁香亚洲综合激情啪啪综合| 亚洲午夜私人影院| 精品处破学生在线二十三| 99精品一区二区| 日韩精品高清不卡| 国产欧美日韩不卡免费| 日本精品视频一区二区| 久久国产福利国产秒拍| 亚洲欧美日韩国产中文在线| 777xxx欧美| 99久久免费国产| 久久精品噜噜噜成人av农村| 国产精品初高中害羞小美女文| 精品视频一区三区九区| 国产成人综合在线观看| 亚洲综合激情小说| 中文字幕欧美三区| 欧美日韩国产色站一区二区三区| 国产乱人伦偷精品视频不卡| 一区二区三区四区国产精品| 日韩欧美黄色影院| 在线观看不卡视频| 丁香另类激情小说| 美女视频黄免费的久久 | 亚洲欧美中日韩| 中文字幕乱码久久午夜不卡| 久久久久久久性| 欧美日韩一卡二卡| 99综合电影在线视频| 狠狠色丁香久久婷婷综合丁香| 亚洲欧美怡红院| 久久久久国产一区二区三区四区| 欧洲一区二区三区在线| 99久久久久免费精品国产 | 一区二区三区不卡视频 | 欧美日韩国产综合一区二区| 不卡视频免费播放| 国产成人av一区二区| 美腿丝袜一区二区三区| 亚洲电影激情视频网站| 日韩久久一区二区| 国产精品久久影院| 欧美激情一区二区在线| 久久一日本道色综合| 日韩免费在线观看| 欧美一区二区三区的| 欧美日韩国产不卡| 欧美日韩精品福利| 欧美另类z0zxhd电影| 欧洲激情一区二区| 欧美系列一区二区| 欧美专区在线观看一区| 欧美亚洲高清一区二区三区不卡| 99视频一区二区| 91社区在线播放| 色域天天综合网| 在线观看一区不卡| 在线观看欧美精品| 欧美性猛交xxxxxxxx| 欧美日韩一区二区三区四区| 欧美日韩免费不卡视频一区二区三区| 日本精品免费观看高清观看| 在线观看亚洲成人| 欧美久久久久免费| 日韩一区二区电影网| 精品少妇一区二区三区日产乱码 | 欧美精选一区二区| 91精品福利在线一区二区三区| 欧美丰满一区二区免费视频| 这里只有精品99re| 日韩欧美不卡一区| 2020国产精品久久精品美国| 久久综合色综合88| 日本一区二区电影| 亚洲伦理在线精品| 午夜视频在线观看一区二区| 日韩av成人高清| 国产精品一区二区91| 成人丝袜视频网| 91久久精品日日躁夜夜躁欧美| 欧美亚洲综合在线| 欧美大度的电影原声| 日本一区二区综合亚洲| 亚洲精品高清在线观看| 肉肉av福利一精品导航| 国产一区二区三区电影在线观看 | 欧美在线一区二区| 日韩欧美国产三级| 亚洲国产精品成人综合色在线婷婷| 中文字幕一区在线观看| 午夜视频一区二区三区| 国产一区二区三区电影在线观看| 成人av电影在线| 欧美精品久久天天躁| 国产视频不卡一区| 亚洲高清三级视频| 国产一区二区毛片| 国产日产欧美一区| 亚洲精品国产精华液| 美女脱光内衣内裤视频久久网站| 国产高清久久久久| 欧美丰满美乳xxx高潮www| 欧美国产禁国产网站cc| 日韩精品免费专区| 99久久精品免费| 日韩一级片网站| 一区二区三区在线免费视频| 久久精品国产一区二区三区免费看| 不卡免费追剧大全电视剧网站| 在线成人av影院| 日本一二三不卡| 免费观看一级特黄欧美大片| 91理论电影在线观看| 精品国产一区二区三区忘忧草| 亚洲精品一卡二卡| 国产成人亚洲综合a∨婷婷图片| 欧美日韩国产影片| 亚洲乱码中文字幕| 高清不卡在线观看| 精品国产一区二区三区久久影院| 亚洲激情自拍偷拍| 成人久久18免费网站麻豆| 日韩精品一区二区三区蜜臀| 亚洲电影视频在线| 色综合婷婷久久| 国产精品美女久久久久高潮| 久久国产精品99精品国产| 欧美精选一区二区| 亚洲图片一区二区| 色婷婷综合久久久中文一区二区| 国产色婷婷亚洲99精品小说| 欧美aaa在线| 欧美日韩国产不卡| 亚洲一区二区视频在线观看| 91亚洲国产成人精品一区二区三| 国产亚洲精品中文字幕| 国产在线一区观看| 日韩欧美的一区二区| 日本美女一区二区| 欧美日韩视频在线一区二区| 尤物在线观看一区| 91精品91久久久中77777| 亚洲三级电影全部在线观看高清| 国产成人精品影视| 国产日韩欧美麻豆| 成人一二三区视频| 国产欧美一区二区精品仙草咪| 狠狠色丁香九九婷婷综合五月| 日韩一级二级三级| 日本欧美加勒比视频| 日韩欧美在线一区二区三区| 天天综合天天做天天综合| 欧美日韩和欧美的一区二区| 午夜精品久久久久久久蜜桃app| 欧美色图片你懂的| 国产亚洲欧美日韩俺去了| 日本一区二区三区dvd视频在线| 在线观看视频91| 色综合色综合色综合色综合色综合 | 91国模大尺度私拍在线视频| 精东粉嫩av免费一区二区三区| 午夜久久久久久久久| 精品国产伦一区二区三区观看方式| 黑人精品欧美一区二区蜜桃 | 中文字幕在线观看不卡| 成人综合日日夜夜| 中文字幕一区二区三区蜜月| 99re这里都是精品| 亚洲一区二区四区蜜桃| 欧美二区三区91| 久久精品国产在热久久| 欧美激情在线一区二区三区| 日本黄色一区二区|