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

正文內(nèi)容

高級字符驅(qū)動操作說明-免費閱讀

2025-05-12 04:29 上一頁面

下一頁面
  

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