freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

高級(jí)字符驅(qū)動(dòng)操作說明(編輯修改稿)

2025-05-15 04:29 本頁(yè)面
 

【文章內(nèi)容簡(jiǎn)介】 /* Tell: arg is the value */ if (! capable (CAP_SYS_ADMIN)) return EPERM。 scull_quantum = arg。 break。case SCULL_IOCGQUANTUM: /* Get: arg is pointer to result */ retval = __put_user(scull_quantum, (int __user *)arg)。 break。case SCULL_IOCUANTUM: /* Query: return it (it39。s positive) */ return scull_quantum。case SCULL_IOCXQUANTUM: /* eXchange: use arg as pointer */ if (! capable (CAP_SYS_ADMIN)) return EPERM。 tmp = scull_quantum。 retval = __get_user(scull_quantum, (int __user *)arg)。 if (retval == 0) retval = __put_user(tmp, (int __user *)arg)。 break。case SCULL_IOCHQUANTUM: /* sHift: like Tell + Query */ if (! capable (CAP_SYS_ADMIN)) return EPERM。 tmp = scull_quantum。 scull_quantum = arg。 return tmp。default: /* redundant, as cmd was checked against MAXNR */ return ENOTTY。}return retval。scull 還包含 6 個(gè)入口項(xiàng)作用于 scull_qset. 這些入口項(xiàng)和給 scull_quantum 的是一致的, 并且不值得展示出來.從調(diào)用者的觀點(diǎn)看(即從用戶空間), 這 6 種傳遞和接收參數(shù)的方法看來如下:int quantum。ioctl(fd,SCULL_IOCSQUANTUM, amp。quantum)。 /* Set by pointer */ioctl(fd,SCULL_IOCTQUANTUM, quantum)。 /* Set by value */ioctl(fd,SCULL_IOCGQUANTUM, amp。quantum)。 /* Get by pointer */quantum = ioctl(fd,SCULL_IOCUANTUM)。 /* Get by return value */ioctl(fd,SCULL_IOCXQUANTUM, amp。quantum)。 /* Exchange by pointer */quantum = ioctl(fd,SCULL_IOCHQUANTUM, quantum)。 /* Exchange by value */當(dāng)然, 一個(gè)正常的驅(qū)動(dòng)不可能實(shí)現(xiàn)這樣一個(gè)調(diào)用模式的混合體. 我們這里這樣做只是為了演示做事情的不同方式. 但是, 正常地, 數(shù)據(jù)交換將一致地進(jìn)行, 通過指針或者通過值, 并且要避免混合這 2 種技術(shù)..不用 ioctl 的設(shè)備控制有時(shí)控制設(shè)備最好是通過寫控制序列到設(shè)備自身來實(shí)現(xiàn). 例如, 這個(gè)技術(shù)用在控制臺(tái)驅(qū)動(dòng)中, 這里所謂的 escape 序列被用來移動(dòng)光標(biāo), 改變?nèi)笔〉念伾? 或者進(jìn)行其他的配置任務(wù). 這樣實(shí)現(xiàn)設(shè)備控制的好處是用戶可僅僅通過寫數(shù)據(jù)控制設(shè)備, 不必使用(或者有時(shí)候?qū)?只為配置設(shè)備而建立的程序. 當(dāng)設(shè)備可這樣來控制, 發(fā)出命令的程序甚至常常不需要運(yùn)行在和它要控制的設(shè)備所在的同一個(gè)系統(tǒng)上.例如, setterm 程序作用于控制臺(tái)(或者其他終端)配置, 通過打印 escape 序列. 控制程序可位于和被控制的設(shè)備不同的一臺(tái)計(jì)算機(jī)上, 因?yàn)橐粋€(gè)簡(jiǎn)單的數(shù)據(jù)流重定向可完成這個(gè)配置工作. 這是每次你運(yùn)行一個(gè)遠(yuǎn)程 tty 會(huì)話時(shí)所發(fā)生的事情: escape 序列在遠(yuǎn)端被打印但是影響到本地的 tty。 然而, 這個(gè)技術(shù)不局限于 ttys.通過打印來控制的缺點(diǎn)是它給設(shè)備增加了策略限制。 例如, 它僅僅當(dāng)你確信在正常操作時(shí)控制序列不會(huì)出現(xiàn)在正被寫入設(shè)備的數(shù)據(jù)中. 這對(duì)于 ttys 只是部分正確的. 盡管一個(gè)文本顯示意味著只顯示 ASCII 字符, 有時(shí)控制字符可潛入正被寫入的數(shù)據(jù)中, 并且可能, 因此, 影響控制臺(tái)的配置. 例如, 這可能發(fā)生在你顯示一個(gè)二進(jìn)制文件到屏幕時(shí)。 產(chǎn)生的亂碼可能包含任何東西, 并且最后你常常在你的控制臺(tái)上出現(xiàn)錯(cuò)誤的字體.通過寫來控制是當(dāng)然的使用方法了, 對(duì)于不用傳送數(shù)據(jù)而只是響應(yīng)命令的設(shè)備, 例如遙控設(shè)備.例如, 被你們作者當(dāng)中的一個(gè)編寫來好玩的驅(qū)動(dòng), 移動(dòng)一個(gè) 2 軸上的攝像機(jī). 在這個(gè)驅(qū)動(dòng)里, 這個(gè)設(shè)備是一對(duì)老式步進(jìn)電機(jī), 它們不能真正讀或?qū)? 給一個(gè)步進(jìn)電機(jī)發(fā)送數(shù)據(jù)流的概念沒有任何意義. 在這個(gè)情況下, 驅(qū)動(dòng)解釋正被寫入的數(shù)據(jù)作為 ASCII 命令并且轉(zhuǎn)換這個(gè)請(qǐng)求為脈沖序列, 來操縱步進(jìn)電機(jī). 這個(gè)概念類似于, 有些, 你發(fā)給貓的 AT 命令來建立通訊, 主要的不同是和貓通訊的串口必須也傳送真正的數(shù)據(jù). 直接設(shè)備控制的好處是你可以使用 cat 來移動(dòng)攝像機(jī), 而不必寫和編譯特殊的代碼來發(fā)出 ioctl 調(diào)用.當(dāng)編寫面向命令的驅(qū)動(dòng), 沒有理由實(shí)現(xiàn) ioctl 命令. 一個(gè)解釋器中的額外命令更容易實(shí)現(xiàn)并使用.有時(shí), 然而, 你可能選擇使用其他的方法:不必轉(zhuǎn)變 write 方法為一個(gè)解釋器和避免 ioctl, 你可能選擇完全避免寫并且專門使用 ioctl 命令, 而實(shí)現(xiàn)驅(qū)動(dòng)為使用一個(gè)特殊的命令行工具來發(fā)送這些命令到驅(qū)動(dòng). 這個(gè)方法轉(zhuǎn)移復(fù)雜性從內(nèi)核空間到用戶空間, 這里可能更易處理, 并且?guī)椭3烛?qū)動(dòng)小, 而拒絕使用簡(jiǎn)單的 cat 或者 echo 命令.[] 但是, 這個(gè)文件的維護(hù)在后來有些少見了.[] 實(shí)際上, 所有的當(dāng)前使用的 libc 實(shí)現(xiàn)(包括 uClibc) 僅將 4095 到 1 的值當(dāng)作錯(cuò)誤碼. 不幸的是, 能夠返回大的負(fù)數(shù)而不是小的, 沒有多大用處..阻塞 I/O回顧第 3 章, 我們看到如何實(shí)現(xiàn) read 和 write 方法. 在此, 但是, 我們跳過了一個(gè)重要的問題:一個(gè)驅(qū)動(dòng)當(dāng)它無法立刻滿足請(qǐng)求應(yīng)當(dāng)如何響應(yīng)? 一個(gè)對(duì) read 的調(diào)用可能當(dāng)沒有數(shù)據(jù)時(shí)到來, 而以后會(huì)期待更多的數(shù)據(jù). 或者一個(gè)進(jìn)程可能試圖寫, 但是你的設(shè)備沒有準(zhǔn)備好接受數(shù)據(jù), 因?yàn)槟愕妮敵鼍彌_滿了. 調(diào)用進(jìn)程往往不關(guān)心這種問題。 程序員只希望調(diào)用 read 或 write 并且使調(diào)用返回, 在必要的工作已完成后. 這樣, 在這樣的情形中, 你的驅(qū)動(dòng)應(yīng)當(dāng)(缺省地)阻塞進(jìn)程, 使它進(jìn)入睡眠直到請(qǐng)求可繼續(xù). 本節(jié)展示如何使一個(gè)進(jìn)程睡眠并且之后再次喚醒它. 如常, 但是, 我們必須首先解釋幾個(gè)概念..睡眠的介紹對(duì)于一個(gè)進(jìn)程睡眠意味著什么? 當(dāng)一個(gè)進(jìn)程被置為睡眠, 它被標(biāo)識(shí)為處于一個(gè)特殊的狀態(tài)并且從調(diào)度器的運(yùn)行隊(duì)列中去除. 直到發(fā)生某些事情改變了那個(gè)狀態(tài), 這個(gè)進(jìn)程將不被在任何 CPU 上調(diào)度, 并且, 因此, 將不會(huì)運(yùn)行. 一個(gè)睡著的進(jìn)程已被擱置到系統(tǒng)的一邊, 等待以后發(fā)生事件.對(duì)于一個(gè) Linux 驅(qū)動(dòng)使一個(gè)進(jìn)程睡眠是一個(gè)容易做的事情. 但是, 有幾個(gè)規(guī)則必須記住以安全的方式編碼睡眠.這些規(guī)則的第一個(gè)是: 當(dāng)你運(yùn)行在原子上下文時(shí)不能睡眠. 我們?cè)诘?5 章介紹過原子操作。 一個(gè)原子上下文只是一個(gè)狀態(tài), 這里多個(gè)步驟必須在沒有任何類型的并發(fā)存取的情況下進(jìn)行. 這意味著, 對(duì)于睡眠, 是你的驅(qū)動(dòng)在持有一個(gè)自旋鎖, seqlock, 或者 RCU 鎖時(shí)不能睡眠. 如果你已關(guān)閉中斷你也不能睡眠. 在持有一個(gè)旗標(biāo)時(shí)睡眠是合法的, 但是你應(yīng)當(dāng)仔細(xì)查看這樣做的任何代碼. 如果代碼在持有一個(gè)旗標(biāo)時(shí)睡眠, 任何其他的等待這個(gè)旗標(biāo)的線程也睡眠. 因此發(fā)生在持有旗標(biāo)時(shí)的任何睡眠應(yīng)當(dāng)短暫, 并且你應(yīng)當(dāng)說服自己, 由于持有這個(gè)旗標(biāo), 你不能阻塞這個(gè)將最終喚醒你的進(jìn)程.另一件要記住的事情是, 當(dāng)你醒來, 你從不知道你的進(jìn)程離開 CPU 多長(zhǎng)時(shí)間或者同時(shí)已經(jīng)發(fā)生了什么改變. 你也常常不知道是否另一個(gè)進(jìn)程已經(jīng)睡眠等待同一個(gè)事件。 那個(gè)進(jìn)程可能在你之前醒來并且獲取了你在等待的資源. 結(jié)果是你不能關(guān)于你醒后的系統(tǒng)狀態(tài)做任何的假設(shè), 并且你必須檢查來確保你在等待的條件是, 確實(shí), 真的.一個(gè)另外的相關(guān)的點(diǎn), 當(dāng)然, 是你的進(jìn)程不能睡眠除非確信其他人, 在某處的, 將喚醒它. 做喚醒工作的代碼必須也能夠找到你的進(jìn)程來做它的工作. 確保一個(gè)喚醒發(fā)生, 是深入考慮你的代碼和對(duì)于每次睡眠, 確切知道什么系列的事件將結(jié)束那次睡眠. 使你的進(jìn)程可能被找到, 真正地, 通過一個(gè)稱為等待隊(duì)列的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的. 一個(gè)等待隊(duì)列就是它聽起來的樣子:一個(gè)進(jìn)程列表, 都等待一個(gè)特定的事件.在 Linux 中, 一個(gè)等待隊(duì)列由一個(gè)等待隊(duì)列頭來管理, 一個(gè) wait_queue_head_t 類型的結(jié)構(gòu), 定義在linux/中. 一個(gè)等待隊(duì)列頭可被定義和初始化, 使用:DECLARE_WAIT_QUEUE_HEAD(name)。 或者動(dòng)態(tài)地, 如下:wait_queue_head_t my_queue。init_waitqueue_head(amp。my_queue)。我們將很快返回到等待隊(duì)列結(jié)構(gòu), 但是我們知道了足夠多的來首先看看睡眠和喚醒..簡(jiǎn)單睡眠當(dāng)一個(gè)進(jìn)程睡眠, 它這樣做以期望某些條件在以后會(huì)成真. 如我們之前注意到的, 任何睡眠的進(jìn)程必須在它再次醒來時(shí)檢查來確保它在等待的條件真正為真. Linux 內(nèi)核中睡眠的最簡(jiǎn)單方式是一個(gè)宏定義, 稱為 wait_event(有幾個(gè)變體)。 它結(jié)合了處理睡眠的細(xì)節(jié)和進(jìn)程在等待的條件的檢查. wait_event 的形式是:wait_event(queue, condition)wait_event_interruptible(queue, condition)wait_event_timeout(queue, condition, timeout)wait_event_interruptible_timeout(queue, condition, timeout)在所有上面的形式中, queue 是要用的等待隊(duì)列頭. 注意它是通過值傳遞的. 條件是一個(gè)被這個(gè)宏在睡眠前后所求值的任意的布爾表達(dá)式。 直到條件求值為真值, 進(jìn)程繼續(xù)睡眠. 注意條件可能被任意次地求值, 因此它不應(yīng)當(dāng)有任何邊界效應(yīng).如果你使用 wait_event, 你的進(jìn)程被置為不可中斷地睡眠, 如同我們之前已經(jīng)提到的, 它常常不是你所要的. 首選的選擇是 wait_event_interruptible, 它可能被信號(hào)中斷. 這個(gè)版本返回一個(gè)你應(yīng)當(dāng)檢查的整數(shù)值。 一個(gè)非零值意味著你的睡眠被某些信號(hào)打斷, 并且你的驅(qū)動(dòng)可能應(yīng)當(dāng)返回 ERESTARTSYS. 最后的版本(wait_event_timeout 和 wait_event_interruptible_timeout)等待一段有限的時(shí)間。 在這個(gè)時(shí)間期間(以嘀噠數(shù)表達(dá)的, 我們將在第 7 章討論)超時(shí)后, 這個(gè)宏返回一個(gè) 0 值而不管條件是如何求值的.圖片的另一半, 當(dāng)然, 是喚醒. 一些其他的執(zhí)行線程(一個(gè)不同的進(jìn)程, 或者一個(gè)中斷處理, 也許)必須為你進(jìn)行喚醒, 因?yàn)槟愕倪M(jìn)程, 當(dāng)然, 是在睡眠. 基本的喚醒睡眠進(jìn)程的函數(shù)稱為 wake_up. 它有幾個(gè)形式(但是我們現(xiàn)在只看其中 2 個(gè)):void wake_up(wait_queue_head_t *queue)。void wake_up_interruptible(wait_queue_head_t *queue)。wake_up 喚醒所有的在給定隊(duì)列上等待的進(jìn)程(盡管這個(gè)情形比那個(gè)要復(fù)雜一些, 如同我們之后將見到的). 其他的形式(wake_up_interruptible)限制它自己到處理一個(gè)可中斷的睡眠. 通常, 這 2 個(gè)是不用區(qū)分的(如果你使用可中斷的睡眠)。 實(shí)際上, 慣例是使用 wake_up 如果你在使用 wait_event , wake_up_interruptible 如果你在使用 wait_event_interruptible.我們現(xiàn)在知道足夠多來看一個(gè)簡(jiǎn)單的睡眠和喚醒的例子. 在這個(gè)例子代碼中, 你可找到一個(gè)稱為 sleepy 的模塊. 它實(shí)現(xiàn)一個(gè)有簡(jiǎn)單行為的設(shè)備:任何試圖從這個(gè)設(shè)備讀取的進(jìn)程都被置為睡眠. 無論何時(shí)一個(gè)進(jìn)程寫這個(gè)設(shè)備, 所有的睡眠進(jìn)程被喚醒. 這個(gè)行為由下面的 read 和 write 方法實(shí)現(xiàn):static DECLARE_WAIT_QUEUE_HEAD(wq)。static int flag = 0。ssize_t sleepy_read (struct file *filp, char __user *buf, size_t count, loff_t *pos){ printk(KERN_DEBUG process %i (%s) going to sleep\n, currentpid, currentm)。 wait_event_interruptible(wq,
點(diǎn)擊復(fù)制文檔內(nèi)容
公司管理相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖片鄂ICP備17016276號(hào)-1