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

正文內(nèi)容

高級(jí)字符驅(qū)動(dòng)操作說(shuō)明-文庫(kù)吧資料

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

【正文】 t, loff_t *pos){ printk(KERN_DEBUG process %i (%s) going to sleep\n, currentpid, currentm)。 實(shí)際上, 慣例是使用 wake_up 如果你在使用 wait_event , wake_up_interruptible 如果你在使用 wait_event_interruptible.我們現(xiàn)在知道足夠多來(lái)看一個(gè)簡(jiǎn)單的睡眠和喚醒的例子. 在這個(gè)例子代碼中, 你可找到一個(gè)稱為 sleepy 的模塊. 它實(shí)現(xiàn)一個(gè)有簡(jiǎn)單行為的設(shè)備:任何試圖從這個(gè)設(shè)備讀取的進(jìn)程都被置為睡眠. 無(wú)論何時(shí)一個(gè)進(jìn)程寫這個(gè)設(shè)備, 所有的睡眠進(jìn)程被喚醒. 這個(gè)行為由下面的 read 和 write 方法實(shí)現(xiàn):static DECLARE_WAIT_QUEUE_HEAD(wq)。void wake_up_interruptible(wait_queue_head_t *queue)。 一個(gè)非零值意味著你的睡眠被某些信號(hào)打斷, 并且你的驅(qū)動(dòng)可能應(yīng)當(dāng)返回 ERESTARTSYS. 最后的版本(wait_event_timeout 和 wait_event_interruptible_timeout)等待一段有限的時(shí)間。 它結(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ì)列頭. 注意它是通過(guò)值傳遞的. 條件是一個(gè)被這個(gè)宏在睡眠前后所求值的任意的布爾表達(dá)式。我們將很快返回到等待隊(duì)列結(jié)構(gòu), 但是我們知道了足夠多的來(lái)首先看看睡眠和喚醒..init_waitqueue_head(amp。 那個(gè)進(jìn)程可能在你之前醒來(lái)并且獲取了你在等待的資源. 結(jié)果是你不能關(guān)于你醒后的系統(tǒng)狀態(tài)做任何的假設(shè), 并且你必須檢查來(lái)確保你在等待的條件是, 確實(shí), 真的.一個(gè)另外的相關(guān)的點(diǎn), 當(dāng)然, 是你的進(jìn)程不能睡眠除非確信其他人, 在某處的, 將喚醒它. 做喚醒工作的代碼必須也能夠找到你的進(jìn)程來(lái)做它的工作. 確保一個(gè)喚醒發(fā)生, 是深入考慮你的代碼和對(duì)于每次睡眠, 確切知道什么系列的事件將結(jié)束那次睡眠. 使你的進(jìn)程可能被找到, 真正地, 通過(guò)一個(gè)稱為等待隊(duì)列的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的. 一個(gè)等待隊(duì)列就是它聽起來(lái)的樣子:一個(gè)進(jìn)程列表, 都等待一個(gè)特定的事件.在 Linux 中, 一個(gè)等待隊(duì)列由一個(gè)等待隊(duì)列頭來(lái)管理, 一個(gè) wait_queue_head_t 類型的結(jié)構(gòu), 定義在linux/中. 一個(gè)等待隊(duì)列頭可被定義和初始化, 使用:DECLARE_WAIT_QUEUE_HEAD(name)。睡眠的介紹對(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 章介紹過(guò)原子操作。阻塞 I/O回顧第 3 章, 我們看到如何實(shí)現(xiàn) read 和 write 方法. 在此, 但是, 我們跳過(guò)了一個(gè)重要的問(wèn)題:一個(gè)驅(qū)動(dòng)當(dāng)它無(wú)法立刻滿足請(qǐng)求應(yīng)當(dāng)如何響應(yīng)? 一個(gè)對(duì) read 的調(diào)用可能當(dāng)沒有數(shù)據(jù)時(shí)到來(lái), 而以后會(huì)期待更多的數(shù)據(jù). 或者一個(gè)進(jìn)程可能試圖寫, 但是你的設(shè)備沒有準(zhǔn)備好接受數(shù)據(jù), 因?yàn)槟愕妮敵鼍彌_滿了. 調(diào)用進(jìn)程往往不關(guān)心這種問(wèn)題。 例如, 它僅僅當(dāng)你確信在正常操作時(shí)控制序列不會(huì)出現(xiàn)在正被寫入設(shè)備的數(shù)據(jù)中. 這對(duì)于 ttys 只是部分正確的. 盡管一個(gè)文本顯示意味著只顯示 ASCII 字符, 有時(shí)控制字符可潛入正被寫入的數(shù)據(jù)中, 并且可能, 因此, 影響控制臺(tái)的配置. 例如, 這可能發(fā)生在你顯示一個(gè)二進(jìn)制文件到屏幕時(shí)。不用 ioctl 的設(shè)備控制有時(shí)控制設(shè)備最好是通過(guò)寫控制序列到設(shè)備自身來(lái)實(shí)現(xiàn). 例如, 這個(gè)技術(shù)用在控制臺(tái)驅(qū)動(dòng)中, 這里所謂的 escape 序列被用來(lái)移動(dòng)光標(biāo), 改變?nèi)笔〉念伾? 或者進(jìn)行其他的配置任務(wù). 這樣實(shí)現(xiàn)設(shè)備控制的好處是用戶可僅僅通過(guò)寫數(shù)據(jù)控制設(shè)備, 不必使用(或者有時(shí)候?qū)?只為配置設(shè)備而建立的程序. 當(dāng)設(shè)備可這樣來(lái)控制, 發(fā)出命令的程序甚至常常不需要運(yùn)行在和它要控制的設(shè)備所在的同一個(gè)系統(tǒng)上.例如, setterm 程序作用于控制臺(tái)(或者其他終端)配置, 通過(guò)打印 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。 /* Exchange by pointer */quantum = ioctl(fd,SCULL_IOCHQUANTUM, quantum)。 /* Get by return value */ioctl(fd,SCULL_IOCXQUANTUM, amp。quantum)。 /* Set by pointer */ioctl(fd,SCULL_IOCTQUANTUM, quantum)。ioctl(fd,SCULL_IOCSQUANTUM, amp。}return retval。 return tmp。 tmp = scull_quantum。 break。 retval = __get_user(scull_quantum, (int __user *)arg)。case SCULL_IOCXQUANTUM: /* eXchange: use arg as pointer */ if (! capable (CAP_SYS_ADMIN)) return EPERM。case SCULL_IOCUANTUM: /* Query: return it (it39。case SCULL_IOCGQUANTUM: /* Get: arg is pointer to result */ retval = __put_user(scull_quantum, (int __user *)arg)。 scull_quantum = arg。 break。case SCULL_IOCSQUANTUM: /* Set: arg points to the value */ if (! capable (CAP_SYS_ADMIN)) return EPERM。 scull_qset = SCULL_QSET。在這個(gè)任務(wù)缺乏一個(gè)更加特定的能力時(shí), CAP_SYS_ADMIN 被選擇來(lái)做這個(gè)測(cè)試.. 不這樣做可能導(dǎo)致用戶進(jìn)程進(jìn)行非法的操作, 對(duì)系統(tǒng)的穩(wěn)定和安全有壞的后果. 能力檢查是通過(guò) capable 函數(shù)來(lái)進(jìn)行的(定義在 linux/): int capable(int capability)。兼容性和受限操作存取一個(gè)設(shè)備由設(shè)備文件上的許可權(quán)控制, 并且驅(qū)動(dòng)正常地不涉及到許可權(quán)的檢查. 但是, 有些情形, 在保證給任何用戶對(duì)設(shè)備的讀寫許可的地方, 一些控制操作仍然應(yīng)當(dāng)被拒絕. 例如, 不是所有的磁帶驅(qū)動(dòng)器的用戶都應(yīng)當(dāng)能夠設(shè)置它的缺省塊大小, 并且一個(gè)已經(jīng)被給予對(duì)一個(gè)磁盤設(shè)備讀寫權(quán)限的用戶應(yīng)當(dāng)仍然可能被拒絕來(lái)格式化它. 在這樣的情況下, 驅(qū)動(dòng)必須進(jìn)行額外的檢查來(lái)確保用戶能夠進(jìn)行被請(qǐng)求的操作.傳統(tǒng)上 unix 系統(tǒng)對(duì)超級(jí)用戶帳戶限制了特權(quán)操作. 這意味著特權(quán)是一個(gè)全有或全無(wú)的東西 超級(jí)用戶可能任意做任何事情, 但是所有其他的用戶被高度限制了. Linux 內(nèi)核提供了一個(gè)更加靈活的系統(tǒng), 稱為能力. 一個(gè)基于能力的系統(tǒng)丟棄了全有或全無(wú)模式, 并且打破特權(quán)操作為獨(dú)立的子類. 這種方式, 一個(gè)特殊的用戶(或者是程序)可被授權(quán)來(lái)進(jìn)行一個(gè)特定的特權(quán)操作而不必泄漏進(jìn)行其他的, 無(wú)關(guān)的操作的能力. 內(nèi)核在許可權(quán)管理上排他地使用能力, 并且輸出 2 個(gè)系統(tǒng)調(diào)用 capget 和 capset, 來(lái)允許它們被從用戶空間管理.全部能力可在 linux/ 中找到. 這些是對(duì)系統(tǒng)唯一可用的能力。 它們相對(duì)快, 并且應(yīng)當(dāng)被調(diào)用來(lái)代替 copy_to_user 無(wú)論何時(shí)要傳送單個(gè)值時(shí). 這些宏已被編寫來(lái)允許傳遞任何類型的指針到 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 檢查來(lái)確保這個(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 檢查過(guò)的時(shí)候.作為一個(gè)通用的規(guī)則, 當(dāng)你實(shí)現(xiàn)一個(gè) read 方法時(shí), 調(diào)用 __put_user 來(lái)節(jié)省幾個(gè)周期, 或者當(dāng)你拷貝幾個(gè)項(xiàng)時(shí), 因此, 在第一次數(shù)據(jù)傳送之前調(diào)用 access_ok 一次, 如同上面 ioctl 所示.get_user(local, ptr) __get_user(local, ptr) 這些宏定義用來(lái)從用戶空間接收單個(gè)數(shù)據(jù). 它們象 put_user 和 __put_user, 但是在相反方向傳遞數(shù)據(jù). 獲取的值存儲(chǔ)于本地變量 local。if (err) return EFAULT。else if (_IOC_DIR(cmd) amp。 is useroriented, while * access_ok is kerneloriented, so the concept of read and * write is reversed */if (_IOC_DIR(cmd) amp。if (_IOC_NR(cmd) SCULL_IOC_MAXNR) return ENOTTY。/* * extract the type and number bitfields, and don39。 它只檢查看這個(gè)內(nèi)存引用是在這個(gè)進(jìn)程有合理權(quán)限的內(nèi)存范圍中. 特別地, access_ok 確保這個(gè)地址不指向內(nèi)核空間內(nèi)存. 第2, 大部分驅(qū)動(dòng)代碼不需要真正調(diào)用 access_ok. 后面描述的內(nèi)存存取函數(shù)為你負(fù)責(zé)這個(gè). 但是, 我們來(lái)演示它的使用, 以便你可見到它如何完成.scull 源碼利用了 ioclt 號(hào)中的位段來(lái)檢查參數(shù), 在 switch 之前:int err = 0, tmp。使用 ioctl 參數(shù)在看 scull 驅(qū)動(dòng)的 ioctl 代碼之前, 我們需要涉及的另一點(diǎn)是如何使用這個(gè)額外的參數(shù). 如果它是一個(gè)整數(shù), 就容易: 它可以直接使用. 如果它是一個(gè)指針, 但是, 必須小心些.當(dāng)用一個(gè)指針引用用戶空間, 我們必須確保用戶地址是有效的. 試圖存取一個(gè)沒驗(yàn)證過(guò)的用戶提供的指針可能導(dǎo)致不正確的行為, 一個(gè)內(nèi)核 oops, 系統(tǒng)崩潰, 或者安全問(wèn)題. 它是驅(qū)動(dòng)的責(zé)任來(lái)對(duì)每個(gè)它使用的用戶空間地址進(jìn)行正確的檢查, 并且返回一個(gè)錯(cuò)誤如果它是無(wú)效的.在第 3 章, 我們看了 copy_from_user 和 copy_to_user 函數(shù), 它們可用來(lái)安全地移動(dòng)數(shù)據(jù)到和從用戶空間. 這些函數(shù)也可用在 ioctl 方法中, 但是 ioctl 調(diào)用常常包含小數(shù)據(jù)項(xiàng), 可通過(guò)其他方法更有效地操作. 開始, 地址校驗(yàn)(不傳送數(shù)據(jù))由函數(shù) access_ok 實(shí)現(xiàn), 它定義在 asm/:int access_ok(int type, const void *addr, unsigned long size)。 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è)命令來(lái)修改 O_SYNC 標(biāo)志. 因?yàn)閮蓚€(gè)動(dòng)作都可通過(guò) ftl 來(lái)完成, 沒有人真正使用 FIOASYNC 命令, 它在這里出現(xiàn)只是為了完整性.FIOQSIZE 這個(gè)命令返回一個(gè)文件或者目錄的大小。 只對(duì)常規(guī)文件發(fā)出的那些.預(yù)定義的命令盡管 ioctl 系統(tǒng)調(diào)用最常用來(lái)作用于設(shè)備, 內(nèi)核能識(shí)別幾個(gè)命令. 注意這
點(diǎn)擊復(fù)制文檔內(nèi)容
公司管理相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖鄂ICP備17016276號(hào)-1