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

正文內(nèi)容

高級(jí)字符驅(qū)動(dòng)操作說明-免費(fèi)閱讀

  

【正文】 /* signal: tell the fs layer to handle it */ if (down_interruptible(amp。 prepare_to_wait(amp。 return count。 if (devwp == devend) devwp = devbuffer。devsem) */ /* ok, space is there, accept something */ count = min(count, (size_t)spacefree(dev))。}static ssize_t scull_p_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){ struct scull_pipe *dev = filpprivate_data。 其中, name 是等待隊(duì)列入口項(xiàng)的名子. 你可用 2 步來做:wait_queue_t my_wait。 在老的代碼中, 你常常見到如此的東西:currentstate = TASK_INTERRUPTIBLE。}如同你可見的, 我們?cè)诖a中留有一些 PDEBUG 語(yǔ)句. 當(dāng)你編譯這個(gè)驅(qū)動(dòng), 你可使能消息機(jī)制來易于跟隨不同進(jìn)程間的交互.讓我們仔細(xì)看看 scull_p_read 如何處理對(duì)數(shù)據(jù)的等待. 這個(gè) while 循環(huán)在持有設(shè)備旗標(biāo)下測(cè)試這個(gè)緩沖. 如果有數(shù)據(jù)在那里, 我們知道我們可立刻返回給用戶, 不必睡眠, 因此整個(gè)循環(huán)被跳過. 相反, 如果這個(gè)緩沖是空的, 我們必須睡眠. 但是在我們可做這個(gè)之前, 我們必須丟掉設(shè)備旗標(biāo)。 } devrp += count。 if (wait_event_interruptible(devinq, (devrp != devwp))) return ERESTARTSYS。讀實(shí)現(xiàn)既管理阻塞也管理非阻塞輸入, 看來如此:static ssize_t scull_p_read (struct file *filp, char __user *buf, size_t count, loff_t *f_pos){ struct scull_pipe *dev = filpprivate_data。 /* read and write queues */ char *buffer, *end。 實(shí)際上, 幾乎每個(gè)設(shè)備驅(qū)動(dòng)都有. 要求有輸入緩沖是為了避免丟失到達(dá)的數(shù)據(jù), 當(dāng)無人在讀時(shí). 相反, 數(shù)據(jù)在寫時(shí)不能丟失, 因?yàn)槿绻到y(tǒng)調(diào)用不能接收數(shù)據(jù)字節(jié), 它們保留在用戶空間緩沖. 即便如此, 輸出緩沖幾乎一直有用, 對(duì)于從硬件擠出更多的性能.在驅(qū)動(dòng)中實(shí)現(xiàn)輸出緩沖所獲得的性能來自減少了上下文切換和用戶級(jí)/內(nèi)核級(jí)切換的次數(shù). 沒有一個(gè)輸出緩沖(假定一個(gè)慢速設(shè)備), 每次系統(tǒng)調(diào)用接收這樣一個(gè)或幾個(gè)字符, 并且當(dāng)一個(gè)進(jìn)程在 write 中睡眠, 另一個(gè)進(jìn)程運(yùn)行(那是一次上下文切換). 當(dāng)?shù)谝粋€(gè)進(jìn)程被喚醒, 它恢復(fù)(另一次上下文切換), 寫返回(內(nèi)核/用戶轉(zhuǎn)換), 并且這個(gè)進(jìn)程重新發(fā)出系統(tǒng)調(diào)用來寫入更多的數(shù)據(jù)(用戶/內(nèi)核轉(zhuǎn)換)。 wake_up_interruptible(amp。static int flag = 0。簡(jiǎn)單睡眠當(dāng)一個(gè)進(jìn)程睡眠, 它這樣做以期望某些條件在以后會(huì)成真. 如我們之前注意到的, 任何睡眠的進(jìn)程必須在它再次醒來時(shí)檢查來確保它在等待的條件真正為真. Linux 內(nèi)核中睡眠的最簡(jiǎn)單方式是一個(gè)宏定義, 稱為 wait_event(有幾個(gè)變體)。 程序員只希望調(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è)概念..quantum)。scull 還包含 6 個(gè)入口項(xiàng)作用于 scull_qset. 這些入口項(xiàng)和給 scull_quantum 的是一致的, 并且不值得展示出來.從調(diào)用者的觀點(diǎn)看(即從用戶空間), 這 6 種傳遞和接收參數(shù)的方法看來如下:int quantum。 if (retval == 0) retval = __put_user(tmp, (int __user *)arg)。 break。ioctl 命令的實(shí)現(xiàn)ioctl 的 scull 實(shí)現(xiàn)只傳遞設(shè)備的配置參數(shù), 并且象下面這樣容易:switch(cmd){case SCULL_IOCRESET: scull_quantum = SCULL_QUANTUM。在調(diào)用 access_ok 之后, 驅(qū)動(dòng)可安全地進(jìn)行真正的傳輸. 加上 copy_from_user 和 copy_to_user_ 函數(shù), 程序員可利用一組為被最多使用的數(shù)據(jù)大小(1, 2, 4, 和 8 字節(jié))而優(yōu)化過的函數(shù). 這些函數(shù)在下面列表中描述, 它們定義在 asm/:put_user(datum, ptr) __put_user(datum, ptr) 這些宏定義寫 datum 到用戶空間。t decode * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() */if (_IOC_TYPE(cmd) != SCULL_IOC_MAGIC) return ENOTTY。 對(duì)文件系統(tǒng)類型特殊的那些.最后一類的命令由宿主文件系統(tǒng)的實(shí)現(xiàn)來執(zhí)行(這是 chattr 命令如何工作的). 設(shè)備驅(qū)動(dòng)編寫者只對(duì)第一類命令感興趣, 它們的魔數(shù)是 T. 查看其他類的工作留給讀者作為練習(xí)。 as magic number */define SCULL_IOC_MAGIC 39。 設(shè)備接著可與用戶空間交換任何數(shù)量的數(shù)據(jù).ioctl 調(diào)用的非結(jié)構(gòu)化特性使它在內(nèi)核開發(fā)者中失寵. 每個(gè) ioctl 命令, 基本上, 是一個(gè)單獨(dú)的, 常常無文檔的系統(tǒng)調(diào)用, 并且沒有方法以任何類型的全面的方式核查這些調(diào)用. 也難于使非結(jié)構(gòu)化的 ioctl 參數(shù)在所有系統(tǒng)上一致工作。高級(jí)字符驅(qū)動(dòng)操作說明作者:日期:n更多企業(yè)學(xué)院: 《中小企業(yè)管理全能版》183套講座+89700份資料《總經(jīng)理、高層管理》49套講座+16388份資料《中層管理學(xué)院》46套講座+6020份資料 例如, 考慮運(yùn)行在 32位模式的一個(gè)用戶進(jìn)程的 64位 系統(tǒng). 結(jié)果, 有很大的壓力來實(shí)現(xiàn)混雜的控制操作, 只通過任何其他的方法. 可能的選擇包括嵌入命令到數(shù)據(jù)流(本章稍后我們將討論這個(gè)方法)或者使用虛擬文件系統(tǒng), 要么是 sysfs 要么是設(shè)備特定的文件系統(tǒng). (我們將在 14 章看看 sysfs). 但是, 事實(shí)是 ioctl 常常是最容易的和最直接的選擇,對(duì)于真正的設(shè)備操作.ioctl 驅(qū)動(dòng)方法有和用戶空間版本不同的原型:int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)。k39。 ext2_ioctl 是最有趣的函數(shù)(并且比預(yù)期的要容易理解), 因?yàn)樗鼘?shí)現(xiàn) appendonly 標(biāo)志和 immutable 標(biāo)志.下列 ioctl 命令是預(yù)定義給任何文件, 包括設(shè)備特殊的文件:FIOCLEX 設(shè)置 closeonexec 標(biāo)志(File IOctl Close on EXec). 設(shè)置這個(gè)標(biāo)志使文件描述符被關(guān)閉, 當(dāng)調(diào)用進(jìn)程執(zhí)行一個(gè)新程序時(shí).FIONCLEX 清除 closenoexec 標(biāo)志(File IOctl Not CLose on EXec). 這個(gè)命令恢復(fù)普通文件行為, 復(fù)原上面 FIOCLEX 所做的. FIOASYNC 為這個(gè)文件設(shè)置或者復(fù)位異步通知(如同在本章中異步通知一節(jié)中討論的). 注意直到 Linux 版本的內(nèi)核不正確地使用這個(gè)命令來修改 O_SYNC 標(biāo)志. 因?yàn)閮蓚€(gè)動(dòng)作都可通過 ftl 來完成, 沒有人真正使用 FIOASYNC 命令, 它在這里出現(xiàn)只是為了完整性.FIOQSIZE 這個(gè)命令返回一個(gè)文件或者目錄的大小。if (_IOC_NR(cmd) SCULL_IOC_MAXNR) return ENOTTY。 它們相對(duì)快, 并且應(yīng)當(dāng)被調(diào)用來代替 copy_to_user 無論何時(shí)要傳送單個(gè)值時(shí). 這些宏已被編寫來允許傳遞任何類型的指針到 put_user, 只要它是一個(gè)用戶空間地址. 傳送的數(shù)據(jù)大小依賴 prt 參數(shù)的類型, 并且在編譯時(shí)使用 sizeof 和 typeof 等編譯器內(nèi)建宏確定. 結(jié)果是, 如果 prt 是一個(gè) char 指針, 傳送一個(gè)字節(jié), 以及對(duì)于 2, 4, 和 可能的 8 字節(jié).put_user 檢查來確保這個(gè)進(jìn)程能夠?qū)懭虢o定的內(nèi)存地址. 它在成功時(shí)返回 0, 并且在錯(cuò)誤時(shí)返回 EFAULT. __put_user 進(jìn)行更少的檢查(它不調(diào)用 access_ok), 但是仍然能夠失敗如果被指向的內(nèi)存對(duì)用戶是不可寫的. 因此, __put_user 應(yīng)當(dāng)只用在內(nèi)存區(qū)已經(jīng)用 access_ok 檢查過的時(shí)候.作為一個(gè)通用的規(guī)則, 當(dāng)你實(shí)現(xiàn)一個(gè) read 方法時(shí), 調(diào)用 __put_user 來節(jié)省幾個(gè)周期, 或者當(dāng)你拷貝幾個(gè)項(xiàng)時(shí), 因此, 在第一次數(shù)據(jù)傳送之前調(diào)用 access_ok 一次, 如同上面 ioctl 所示.get_user(local, ptr) __get_user(local, ptr) 這些宏定義用來從用戶空間接收單個(gè)數(shù)據(jù). 它們象 put_user 和 __put_user, 但是在相反方向傳遞數(shù)據(jù). 獲取的值存儲(chǔ)于本地變量 local。 scull_qset = SCULL_QSET。case SCULL_IOCGQUANTUM: /* Get: arg is pointer to result */ retval = __put_user(scull_quantum, (int __user *)arg)。 break。ioctl(fd,SCULL_IOCSQUANTUM, amp。 /* Exchange by pointer */quantum = ioctl(fd,SCULL_IOCHQUANTUM, quantum)。睡眠的介紹對(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 章介紹過原子操作。 它結(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á)式。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)。wq)。 這個(gè)調(diào)用阻塞并且循環(huán)繼續(xù). 增加一個(gè)輸出緩沖可允許驅(qū)動(dòng)在每個(gè)寫調(diào)用中接收大的數(shù)據(jù)塊, 性能上有相應(yīng)的提高. 如果這個(gè)緩沖足夠大, 寫調(diào)用在第一次嘗試就成功 被緩沖的數(shù)據(jù)之后將被推到設(shè)備 不必控制需要返回用戶空間來第二次或者第三次寫調(diào)用. 選擇一個(gè)合適的值給輸出緩沖顯然是設(shè)備特定的.我們不使用一個(gè)輸入緩沖在 scull中, 因?yàn)閿?shù)據(jù)當(dāng)發(fā)出 read 時(shí)已經(jīng)可用. 類似的, 不用輸出緩沖, 因?yàn)閿?shù)據(jù)被簡(jiǎn)單地拷貝到和設(shè)備關(guān)聯(lián)的內(nèi)存區(qū). 本質(zhì)上, 這個(gè)設(shè)備是一個(gè)緩沖, 因此額外緩沖的實(shí)現(xiàn)可能是多余的. 我們將在第 10 章見到緩沖的使用.如果指定 O_NONBLOCK, read 和 write 的行為是不同的. 在這個(gè)情況下, 這個(gè)調(diào)用簡(jiǎn)單地返回 EAGAIN((try it agin)如果一個(gè)進(jìn)程當(dāng)沒有數(shù)據(jù)可
點(diǎn)擊復(fù)制文檔內(nèi)容
公司管理相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖鄂ICP備17016276號(hào)-1