国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

電子工程網

標題: Linux字符設備驅動程序工作機理分析 [打印本頁]

作者: huangedu    時間: 2016-4-11 15:26
標題: Linux字符設備驅動程序工作機理分析
1 本文主題
    本文主要分析Linux字符設備驅動程序的工作機理。主要內容以及代碼片段來源于《LDD3》,俺只是從另外一個角度來講述。
    見過很多關于驅動程序的書,基本上都是告訴你怎么做,然后你STEP BY STEP,然后運行完后結果就出來了,可是其背后到底是如何工作的呢?雖說《LDD3》也講了很多原理性的東西,但是我覺得這個問題其描述得并不明確。
2 關于scull
    scull是《LDD3》的一個字符設備驅動程序,其加載之后會在文件系統下生成/dev/scull文件,在shell下可以對其進行一系列的操作,例如可以使用cpdd或者輸入輸出重定向等命令來訪問這個文件,也就是訪問這個字符設備。
3 /dev/scull是如何生成的
    該文件是在驅動程序模塊加載時生成的,具體實現是在scull_load(可以到www.oreilly.com下載,或者《LDD3_中文》的P51)這個腳本里。
    在shellinsmodscull.ko之后,系統會在/proc/devices文件里生成設備名以及與之對應的主設備號信息,scull_load腳本根據該信息mknod/dev/scull文件節點。
    注意下mknod時給的參數信息,其中注明了主設備號以及次設備號信息。
4 shell下操作/dev/scull是如何關聯到我們自己編寫的scull模塊的
    這個問題一直困擾了我很久,不過現在我基本上算是弄明白了。
4.1 先回顧下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);
        ...
    }
   
    scull_fops是一個數組,其中保存了我們的scull實際的操作:
    struct file_operation scull_fops = {
        ...
        .open = scull_open,
        .read = scull_read,
        .write = scull_write,
        .release = scull_release,
        cdevstruct cdev類型(該類型由系統定義)的變量,其嵌入在struct scull_dev(該類型由scull模塊定義)中:
    struct scull_dev{
        ...
        struct cdev cdev;
        ...
    }
      從這句代碼
    cdev_add(&dev->cdev, devno, 1);
    我們可以發現,設備號devno已經和內核內部結構cdev關聯起來了。
4.2 /dev/scull設備的打開操作

    /dev/scull是文件系統中的一個設備文件,其在內核中由sturct inode結構表示。
   
    一般說來,inode結構下由兩個元素和驅動程序有關:
    dev_t i_rdev;                 這個是設備號
    struct cdev *i_cdev;          這里是一個指針,struct cdev是字符設備在內核里的表示,注意我們在4.1小節里也提到了這個結構。
     也就是說,系統在打開/dev/scull之前僅知道inode信息。在4.1小節里已經說過了,設備號和內核內部結構cdev關聯起來了,因此cdev下的ops也和設備號關聯起來了,ops已經初始化為scull_fops。所以我們才能夠通過inode中的設備號i_rdev定位到此時打開的是哪一個設備,從而去調用相應設備的open操作。
  看看open函數的原型吧:
    int (*open)(struct inode*, struct file*);
    第一個參數是struct inode類型的指針,該指針由內核傳遞過來,是設備文件在內核中的表示。
    第二個參數struct file類型的指針,open之后,設備文件在內核中就以struct file結構來表示了。
看看open操作在scull里的實現吧:
    int scull_open(struct inode *inode, struct file *filp)
    {
        struct scull_dev *dev;

        dev = container_of(inode->i_cdev, struct scull_dev, cdev);
        filp->private_data = dev;
        ...
    }
    第一句代碼通過宏container_of把包裹inode->i_cdev的結構提取出來了,該結構就是在scull模塊里定以的struct scull_dev,其中包含了scull模塊所需要的私有信息。
    第二句代碼把該私有信息加入內核數據結構struct file,之前說過了,open后的文件在內核里以struct file結構表示。
4.3 /dev/scull的讀寫操作

    先看下讀寫操作的函數原型:
    ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
    ssize_t (*write)(struct file*, char __user *, size_t, loff_t *);
    其參數內容我不做過多解釋,注意其第一個參數是struct file類型的指針,該指針由內核傳入,也就是open之后的那個文件指針。

    通過這個指針,能夠找到scull模塊的私有數據結構struct scull_dev,并對其操作,我們可以從read/write操作在scull里的實現看到這個做法:
    ssize_t scull_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
    {
        sturct scull_dev *dev = filp->private_data;
        int quantum = dev->quantum, qset = dev->qset;
        ...
    }
   
    ssize_t scull_write(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
    {
        sturct scull_dev *dev = filp->private_data;
        int quantum = dev->quantum, qset = dev->qset;
        ...
    }

u=2429609584,2450763625&fm=21&gp=0 - 副本.jpg (4.55 KB)

u=2429609584,2450763625&fm=21&gp=0 - 副本.jpg

10671746 - 副本.gif (36.64 KB)

10671746 - 副本.gif





歡迎光臨 電子工程網 (http://m.qingdxww.cn/) Powered by Discuz! X3.4
主站蜘蛛池模板: 99久久精品免费看国产情侣 | 国亚洲欧美日韩精品 | 麻豆动漫| 岛国在线免费 | 日韩免费一区二区三区在线 | 日日噜噜夜夜狠狠视频buoke | 欧洲97色综合成人网 | 国产馆在线观看免费的 | 国产精品一区二区综合 | 色费女人18毛片a级视频在线 | 欧美精品亚洲精品日韩专区va | 99精品在线观看视频 | 九色 在线| 爱爱综合社区 | 毛片在线视频观看 | 欧美三级在线观看视频 | 欧美特级特黄a大片免费 | 日韩新片在线观看 | 国产一区二区三区在线观看精品 | 国产精品香蕉 | 欧美黑人乱大交ⅹxxxxx | 国产精品v在线播放观看 | 看全色黄一级毛片 | 啊用力点国产嗯快在线观看 | 麻豆免费在线视频 | 久久国产乱子伦精品免费强 | 色噜噜色噜噜天天拍一拍 | 综合成人在线 | 91热在线| 欧美曰逼| 黑人又大又粗好爽好猛视频 | 亚洲一区欧美在线 | 欧美性另类高清 | 四虎影院免费在线播放 | 国产成人黄网址在线视频 | 在线视频亚洲欧美 | 国产精品欧美一区二区三区不卡 | 国产三级全黄在线观看 | 99国产精品久久久久久久成人热 | 一区二区三区四区在线观看视频 | 中文字幕成人网 |