亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Linux 字符設備驅動結構(三)—— file、inode結構體及chardevs數組等相關知識解析

2019-11-10 19:02:19
字體:
來源:轉載
供稿:網友
 前面我們學習了字符設備結構體cdev linux 字符設備驅動開發 (一)—— 字符設備驅動結構(上)  下面繼續學習字符設備另外幾個重要的數據結構。

       先看下面這張圖,這是Linux 中虛擬文件系統、一般的設備文件與設備驅動程序值間的函數調用關系;

        上面這張圖展現了一個應用程序調用字符設備驅動的過程, 在設備驅動程序的設計中,一般而言,會關心 file 和 inode 這兩個結構體

        用戶空間使用 open() 函數打開一個字符設備 fd = open("/dev/hello",O_RDWR) , 這一函數會調用兩個數據結構 struct inode{...}struct file{...} ,二者均在虛擬文件系統VFS處,下面對兩個數據結構進行解析:

一、file 文件結構體

       在設備驅動中,這也是個非常重要的數據結構,必須要注意一點,這里的file與用戶空間程序中的FILE指針是不同的,用戶空間FILE是定義在C庫中,從來不會出現在內核中。而struct file,卻是內核當中的數據結構,因此,它也不會出現在用戶層程序中。

       file結構體指示一個已經打開的文件(設備對應于設備文件),其實系統中的每個打開的文件在內核空間都有一個相應的struct file結構體,它由內核在打開文件時創建,并傳遞給在文件上進行操作的任何函數,直至文件被關閉。如果文件被關閉,內核就會釋放相應的數據結構。

     在內核源碼中,struct file要么表示為file,或者為filp(意指“file pointer”), 注意區分一點,file指的是struct file本身,而filp是指向這個結構體的指針。

下面是幾個重要成員:

a -- fmode_t f_mode;

      此文件模式通過FMODE_READ, FMODE_WRITE識別了文件為可讀的,可寫的,或者是二者。在open或ioctl函數中可能需要檢查此域以確認文件的讀/寫權限,你不必直接去檢測讀或寫權限,因為在進行octl等操作時內核本身就需要對其權限進行檢測。

 b -- loff_t f_pos;

     當前讀寫文件的位置。為64位。如果想知道當前文件當前位置在哪,驅動可以讀取這個值而不會改變其位置。對read,write來說,當其接收到一個loff_t型指針作為其最后一個參數時,他們的讀寫操作便作更新文件的位置,而不需要直接執行filp ->f_pos操作。而llseek方法的目的就是用于改變文件的位置。

c -- unsigned int f_flags;

     文件標志,如O_RDONLY, O_NONBLOCK以及O_SYNC。在驅動中還可以檢查O_NONBLOCK標志查看是否有非阻塞請求。其它的標志較少使用。特別地注意的是,讀寫權限的檢查是使用f_mode而不是f_flog。所有的標量定義在頭文件中

d -- struct file_Operations *f_op;

    與文件相關的各種操作。當文件需要迅速進行各種操作時,內核分配這個指針作為它實現文件打開,讀,寫等功能的一部分。filp->f_op 其值從未被內核保存作為下次的引用,即你可以改變與文件相關的各種操作,這種方式效率非常高。

    file_operation 結構體解析如下:Linux 字符設備驅動結構(四)—— file_operations 結構體知識解析

e -- void *PRivate_data;

      在驅動調用open方法之前,open系統調用設置此指針為NULL值。你可以很自由的將其做為你自己需要的一些數據域或者不管它,如,你可以將其指向一個分配好的數據,但是你必須記得在file struct被內核銷毀之前在release方法中釋放這些數據的內存空間。private_data用于在系統調用期間保存各種狀態信息是非常有用的。

二、 inode結構體

         VFS inode 包含文件訪問權限、屬主、組、大小、生成時間、訪問時間、最后修改時間等信息。它是Linux 管理文件系統的最基本單位,也是文件系統連接任何子目錄、文件的橋梁。

        內核使用inode結構體在內核內部表示一個文件。因此,它與表示一個已經打開的文件描述符的結構體(即file 文件結構)是不同的,我們可以使用多個file 文件結構表示同一個文件的多個文件描述符,但此時,所有的這些file文件結構全部都必須只能指向一個inode結構體

      inode結構體包含了一大堆文件相關的信息,但是就針對驅動代碼來說,我們只要關心其中的兩個域即可:

(1) dev_t i_rdev;

      表示設備文件的結點,這個域實際上包含了設備號。

(2) struct cdev *i_cdev;

      struct cdev是內核的一個內部結構,它是用來表示字符設備的,當inode結點指向一個字符設備文件時,此域為一個指向inode結構的指針。

下面是源代碼:

[cpp] view plain copy 在CODE上查看代碼片struct inode {   struct hlist_node i_hash;   struct list_head i_list;   struct list_head i_sb_list;   struct list_head i_dentry;   unsigned long  i_ino;   atomic_t  i_count;   unsigned int  i_nlink;   uid_t   i_uid;//inode擁有者id   gid_t   i_gid;//inode所屬群組id   dev_t   i_rdev;//若是設備文件,表示記錄設備的設備號   u64   i_version;   loff_t   i_size;//inode所代表大少  #ifdef __NEED_I_SIZE_ORDERED   seqcount_t  i_size_seqcount;  #endif   struct timespec  i_atime;//inode最近一次的存取時間   struct timespec  i_mtime;//inode最近一次修改時間   struct timespec  i_ctime;//inode的生成時間   unsigned int  i_blkbits;   blkcnt_t  i_blocks;   unsigned short          i_bytes;   umode_t   i_mode;   spinlock_t  i_lock;    struct mutex  i_mutex;   struct rw_semaphore i_alloc_sem;   const struct inode_operations *i_op;   const struct file_operations *i_fop;    struct super_block *i_sb;   struct file_lock *i_flock;   struct address_space *i_mapping;   struct address_space i_data;  #ifdef CONFIG_QUOTA   struct dquot  *i_dquot[MAXQUOTAS];  #endif   struct list_head i_devices;   union {    struct p#define CHRDEV_MAJOR_HASH_SIZE 255  static DEFINE_MUTEX(chrdevs_lock);    static struct char_device_struct {      struct char_device_struct *next; // 結構體指針      unsigned int major;              // 主設備號      unsigned int baseminor;          // 次設備起始號      int minorct;                     // 次備號個數      char name[64];      struct cdev *cdev; /* will die */  } *chrdevs[CHRDEV_MAJOR_HASH_SIZE];      // 只能掛255個字符主設備<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">  </span>  

 %20 %20 %20 可以看到全局數組%20chrdevs%20包含了255(CHRDEV_MAJOR_HASH_SIZE%20的值)個%20struct%20char_device_struct的元素,每一個對應一個相應的主設備號。

 %20 %20 %20 如果分配了一個設備號,就會創建一個%20struct%20char_device_struct%20的對象,并將其添加到%20chrdevs%20中;這樣,通過chrdevs數組,我們就可以知道分配了哪些設備號。

相關函數,(這些函數在上篇已經介紹過,現在回顧一下:

  register_chrdev_region( ) 分配指定的設備號范圍

  alloc_chrdev_region( ) 動態分配設備范圍

他們都主要是通過調用函數 __register_chrdev_region() 來實現的;要注意,這兩個函數僅僅是注冊設備號!如果要和cdev關聯起來,還要調用cdev_add()。

  register_chrdev( )申請指定的設備號,并且將其注冊到字符設備驅動模型中.

  它所做的事情為:

a -- 注冊設備號, 通過調用 __register_chrdev_region() 來實現

b -- 分配一個cdev, 通過調用 cdev_alloc() 來實現

c -- 將cdev添加到驅動模型中, 這一步將設備號和驅動關聯了起來. 通過調用 cdev_add() 來實現

d -- 將第一步中創建的 struct char_device_struct 對象的 cdev 指向第二步中分配的cdev. 由于register_chrdev()是老的接口,這一步在新的接口中并不需要。

四、cdev 結構體

        在 Linux 字符設備驅動開發 (一)—— 字符設備驅動結構(上) 有解析。

五、文件系統中對字符設備文件的訪問

        下面看一下上層應用open() 調用系統調用函數的過程

        對于一個字符設備文件, 其inode->i_cdev 指向字符驅動對象cdev, 如果i_cdev為 NULL ,則說明該設備文件沒有被打開.

  由于多個設備可以共用同一個驅動程序.所以,通過字符設備的inode 中的i_devices 和 cdev中的list組成一個鏈表

        首先,系統調用open打開一個字符設備的時候, 通過一系列調用,最終會執行到 chrdev_open

  (最終是通過調用到def_chr_fops中的.open, 而def_chr_fops.open = chrdev_open. 這一系列的調用過程,本文暫不討論)

  int chrdev_open(struct inode * inode, struct file * filp)

chrdev_open()所做的事情可以概括如下:

  1. 根據設備號(inode->i_rdev), 在字符設備驅動模型中查找對應的驅動程序, 這通過kobj_lookup() 來實現, kobj_lookup()會返回對應驅動程序cdev的kobject.

  2. 設置inode->i_cdev , 指向找到的cdev.

  3. 將inode添加到cdev->list 的鏈表中.

  4. 使用cdev的ops 設置file對象的f_op

  5. 如果ops中定義了open方法,則調用該open方法

  6. 返回

執行完 chrdev_open()之后,file對象的f_op指向cdev的ops,因而之后對設備進行的read, write等操作,就會執行cdev的相應操作。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久久久久久尿| 97在线观看视频| 91香蕉国产在线观看| 亚洲视频在线观看免费| 国产亚洲综合久久| 国产成人精品一区二区在线| 久久久999精品视频| 色妞久久福利网| 在线日韩第一页| 国产亚洲精品高潮| 国产欧美日韩中文字幕| 69av在线视频| 亚洲精品电影网站| 美女久久久久久久| 色综合影院在线| 97超碰国产精品女人人人爽| 高清在线视频日韩欧美| 亚洲色图15p| 欧美国产日韩一区| 日本19禁啪啪免费观看www| 国产欧美一区二区三区久久人妖| 久久久女女女女999久久| 一本色道久久综合狠狠躁篇的优点| 国产精品第一页在线| 国产精品高潮呻吟久久av野狼| 777午夜精品福利在线观看| 欧美日韩色婷婷| 国产精品中文字幕在线| 日韩精品极品在线观看播放免费视频| 亚洲精品视频网上网址在线观看| 国产精品激情av电影在线观看| 欧美性受xxx| 久久精品电影一区二区| 亚洲成年网站在线观看| 精品呦交小u女在线| 91免费国产视频| 在线播放国产一区中文字幕剧情欧美| 69av成年福利视频| 成人精品久久一区二区三区| 久久久久久国产精品三级玉女聊斋| 久久精品99久久香蕉国产色戒| 国产精品久久久久久久久久小说| 欧美午夜久久久| 久久久国产精品免费| 色婷婷亚洲mv天堂mv在影片| 久久久久久久久久久久av| 久99九色视频在线观看| 成人免费午夜电影| 日本久久久久久久久| 日韩视频在线一区| 国产精品第10页| 国产精品一区二区三区成人| 亚洲人成在线一二| 欧美成人国产va精品日本一级| 亚洲激情久久久| 91色视频在线导航| 91美女片黄在线观看游戏| 精品香蕉一区二区三区| 国产日韩欧美电影在线观看| 久久久久久com| 久久婷婷国产麻豆91天堂| 国产精品视频xxx| 久久久久久久久久久亚洲| 日韩高清av一区二区三区| 国产精品视频专区| 欧美性xxxx在线播放| 久久精品国产v日韩v亚洲| 亚洲天堂色网站| 91欧美激情另类亚洲| 自拍偷拍亚洲在线| 亚洲mm色国产网站| 91国产美女在线观看| 色悠久久久久综合先锋影音下载| 午夜精品久久久久久久久久久久久| 国产精品福利在线| 欧美日韩日本国产| 欧美日产国产成人免费图片| 国产精品久久综合av爱欲tv| 亚洲欧美综合另类中字| 麻豆国产精品va在线观看不卡| 伦伦影院午夜日韩欧美限制| 欧美成人合集magnet| 亚洲中国色老太| 91精品久久久久久久久青青| 国产精品美腿一区在线看| 91精品久久久久久久久不口人| 神马久久桃色视频| 国产69精品久久久久久| 欧美在线视频播放| 欧美精品午夜视频| 久久免费在线观看| 欧美中文字幕在线视频| 精品久久香蕉国产线看观看gif| 久久成人综合视频| 97国产suv精品一区二区62| 91精品国产色综合久久不卡98口| 中文字幕综合一区| 国产一区二区三区在线观看网站| 欧美极品少妇xxxxx| 一本久久综合亚洲鲁鲁| 欧美精品久久久久久久免费观看| 亚洲日本成人女熟在线观看| 91久久国产婷婷一区二区| 91精品成人久久| 久久久久久亚洲精品中文字幕| 成人黄色av网站| 国产亚洲精品高潮| 亚洲久久久久久久久久| 精品国产鲁一鲁一区二区张丽| 亚洲第一中文字幕| 欧美性受xxx| 日韩av中文字幕在线| 久久69精品久久久久久国产越南| 久久久久国产精品免费| 亚洲精品一区二三区不卡| 欧美性生交大片免费| 欧美成人小视频| 91精品在线播放| 国产精品日韩精品| 久久成人这里只有精品| 中文在线资源观看视频网站免费不卡| 日韩影视在线观看| 欧美精品一二区| 91久久精品久久国产性色也91| 激情成人中文字幕| 色www亚洲国产张柏芝| 亚洲精品videossex少妇| 亚洲最新av在线| 97国产精品人人爽人人做| 国产精品三级美女白浆呻吟| 亚洲三级 欧美三级| 国产综合久久久久久| 1769国内精品视频在线播放| 性欧美激情精品| 国内精品美女av在线播放| 久久精品这里热有精品| 97不卡在线视频| 成人在线中文字幕| 少妇高潮久久77777| 97视频com| 久久精品国产电影| 在线观看国产成人av片| 亚洲午夜国产成人av电影男同| 欧美国产日韩一区二区在线观看| 欧美性猛交视频| 精品久久久久久久久中文字幕| 欧美日韩在线一区| 国产一区二区三区日韩欧美| 久久成人人人人精品欧| 色综合久久中文字幕综合网小说| 91精品国产777在线观看| 日本不卡视频在线播放| 久久韩剧网电视剧| 亚洲免费小视频| 日韩av观看网址| 美日韩精品免费观看视频| 日韩av电影中文字幕| 在线免费观看羞羞视频一区二区| 亚洲无限乱码一二三四麻| 国产精品揄拍一区二区| 精品国偷自产在线视频| 欧美一级bbbbb性bbbb喷潮片| 日韩成人在线视频| 91成人在线播放|