<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 3.4.?字符設備注冊 如我們提過的, 內核在內部使用類型 struct cdev 的結構來代表字符設備. 在內核調用你的設備操作前, 你編寫分配并注冊一個或幾個這些結構. [[11](#)]為此, 你的代碼應當包含 <linux/cdev.h>, 這個結構和它的關聯幫助函數定義在這里. 有 2 種方法來分配和初始化一個這些結構. 如果你想在運行時獲得一個獨立的 cdev 結構, 你可以為此使用這樣的代碼: ~~~ struct cdev *my_cdev = cdev_alloc(); my_cdev->ops = &my_fops; ~~~ 但是, 偶爾你會想將 cdev 結構嵌入一個你自己的設備特定的結構; scull 這樣做了. 在這種情況下, 你應當初始化你已經分配的結構, 使用: ~~~ void cdev_init(struct cdev *cdev, struct file_operations *fops); ~~~ 任一方法, 有一個其他的 struct cdev 成員你需要初始化. 象 file_operations 結構, struct cdev 有一個擁有者成員, 應當設置為 THIS_MODULE. 一旦 cdev 結構建立, 最后的步驟是把它告訴內核, 調用: ~~~ int cdev_add(struct cdev *dev, dev_t num, unsigned int count); ~~~ 這里, dev 是 cdev 結構, num 是這個設備響應的第一個設備號, count 是應當關聯到設備的設備號的數目. 常常 count 是 1, 但是有多個設備號對應于一個特定的設備的情形. 例如, 設想 SCSI 磁帶驅動, 它允許用戶空間來選擇操作模式(例如密度), 通過安排多個次編號給每一個物理設備. 在使用 cdev_add 是有幾個重要事情要記住. 第一個是這個調用可能失敗. 如果它返回一個負的錯誤碼, 你的設備沒有增加到系統中. 它幾乎會一直成功, 但是, 并且帶起了其他的點: cdev_add 一返回, 你的設備就是"活的"并且內核可以調用它的操作. 除非你的驅動完全準備好處理設備上的操作, 你不應當調用 cdev_add. 為從系統去除一個字符設備, 調用: ~~~ void cdev_del(struct cdev *dev); ~~~ 顯然, 你不應當在傳遞給 cdev_del 后存取 cdev 結構. ### 3.4.1.?scull 中的設備注冊 在內部, scull 使用一個 struct scull_dev 類型的結構表示每個設備. 這個結構定義為: ~~~ struct scull_dev { struct scull_qset *data; /* Pointer to first quantum set */ int quantum; /* the current quantum size */ int qset; /* the current array size */ unsigned long size; /* amount of data stored here */ unsigned int access_key; /* used by sculluid and scullpriv */ struct semaphore sem; /* mutual exclusion semaphore */ struct cdev cdev; /* Char device structure */ }; ~~~ 我們在遇到它們時討論結構中的各個成員, 但是現在, 我們關注于 cdev, 我們的設備與內核接口的 struct cdev. 這個結構必須初始化并且如上所述添加到系統中; 處理這個任務的 scull 代碼是: ~~~ static void scull_setup_cdev(struct scull_dev *dev, int index) { int err, devno = MKDEV(scull_major, scull_minor + index); cdev_init(&dev->cdev, &scull_fops); dev->cdev.owner = THIS_MODULE; dev->cdev.ops = &scull_fops; err = cdev_add (&dev->cdev, devno, 1); /* Fail gracefully if need be */ if (err) printk(KERN_NOTICE "Error %d adding scull%d", err, index); } ~~~ 因為 cdev 結構嵌在 struct scull_dev 里面, cdev_init 必須調用來進行那個結構的初始化. ### 3.4.2.?老方法 如果你深入瀏覽 2.6 內核的大量驅動代碼, 你可能注意到有許多字符驅動不使用我們剛剛描述過的 cdev 接口. 你見到的是還沒有更新到 2.6 內核接口的老代碼. 因為那個代碼實際上能用, 這個更新可能很長時間不會發生. 為完整, 我們描述老的字符設備注冊接口, 但是新代碼不應當使用它; 這個機制在將來內核中可能會消失. 注冊一個字符設備的經典方法是使用: ~~~ int register_chrdev(unsigned int major, const char *name, struct file_operations *fops); ~~~ 這里, major 是感興趣的主編號, name 是驅動的名子(出現在 /proc/devices), fops 是缺省的 file_operations 結構. 一個對 register_chrdev 的調用為給定的主編號注冊 0 - 255 的次編號, 并且為每一個建立一個缺省的 cdev 結構. 使用這個接口的驅動必須準備好處理對所有 256 個次編號的 open 調用( 不管它們是否對應真實設備 ), 它們不能使用大于 255 的主或次編號. 如果你使用 register_chrdev, 從系統中去除你的設備的正確的函數是: ~~~ int unregister_chrdev(unsigned int major, const char *name); ~~~ major 和 name 必須和傳遞給 register_chrdev 的相同, 否則調用會失敗. [[11](#)] 有一個早些的機制以避免使用 cdev 結構(我們在"老方法"一節中討論).但是, 新代碼應當使用新技術.
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看