小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

uio.c 分析

 lifei_szdz 2012-04-05

uio.c 分析

分類: Linux 驅動 Linux 基礎學習 雜項 實時操作系統(tǒng) Linux 內核 214人閱讀 評論(0) 收藏 舉報
AUTHOR: Joseph Yang (楊紅剛) <ganggexiongqi@gmail.com>
CONTENT: uio.c source code notes
NOTE: linux-3.0
LAST MODIFIED:09-04-2011
--------------------------------------
Distributed and Embedded System Lab (分布式嵌入式系統(tǒng)實驗室,蘭州大學)

===============================================================================







uio.c 導出的可以在您的uio驅動中使用的函數(shù):
            EXPORT_SYMBOL_GPL(uio_event_notify);
            EXPORT_SYMBOL_GPL(__uio_register_device);
            EXPORT_SYMBOL_GPL(uio_unregister_device);
-------------------------------------------------------------------------------------------------
uio.c 函數(shù)列表
|-   function
||     map_name_show
||     map_addr_show
||     map_size_show
||     map_offset_show
||     map_release
||     map_type_show
||     portio_name_show
||     portio_start_show
||     portio_size_show
||     portio_porttype_show
||     portio_release
||     portio_type_show
||     show_name
||     show_version
||     show_event
||     uio_dev_add_attributes
||     uio_dev_del_attributes
||     uio_get_minor
||     uio_free_minor
||     uio_event_notify
||     uio_interrupt
||     uio_open
||     uio_fasync
||     uio_release
||     uio_poll
||     uio_read
||     uio_write
||     uio_find_mem_index
||     uio_vma_open
||     uio_vma_close
||     uio_vma_fault
||     uio_mmap_physical
||     uio_mmap_logical
||     uio_mmap
||     uio_major_init
||     uio_major_cleanup
||     init_uio_class
||     release_uio_class
||     __uio_register_device
||     uio_unregister_device
||     uio_init
||     uio_exit
---------------------------一些重要的數(shù)據(jù)結構----------------------------------------------
  1.  struct uio_portio {  
  2.     struct kobject kobj;  
  3.     struct uio_port *port;  
  4. };  
  5.   
  6. /**  
  7.  * struct uio_port - description of a UIO port region  
  8.  * @name:       name of the port region for identification  
  9.  * @start:      start of port region  
  10.  * @size:       size of port region  
  11.  * @porttype:       type of port (see UIO_PORT_* below)  
  12.  * @portio:     for use by the UIO core only.  
  13.  */  
  14. struct uio_port {  
  15.     const char      *name;  
  16.     unsigned long       start;  
  17.     unsigned long       size;  
  18.     int         porttype;  
  19.     struct uio_portio   *portio;  
  20. };  
  21.   
  22. /* defines for uio_port->porttype */  
  23. #define UIO_PORT_NONE   0  
  24. #define UIO_PORT_X86    1  
  25. #define UIO_PORT_GPIO   2  
  26. #define UIO_PORT_OTHER  3  
  27.   
  28.    
  29.   /*  
  30.   * struct uio_mem - description of a UIO memory region  
  31.  * @name:       name of the memory region for identification  
  32.  * @addr:       address of the device's memory  
  33.  * @size:       size of IO  
  34.  * @memtype:        type of memory addr points to  
  35.  * @internal_addr:  ioremap-ped version of addr, for driver internal use  
  36.  * @map:        for use by the UIO core only.  
  37.  */  
  38. struct uio_mem {  
  39.     const char      *name;// 內存映射的名字  
  40.     unsigned long       addr; // 內存塊的地址  
  41.     unsigned long       size; //addr所指向的內存塊的大小  
  42.     int         memtype; //UIO_MEM_PHYS,UIO_MEM_LOGICAL(kmalloc()),UIO_MEM_VIRTUAL( virtual memory)  
  43.     void __iomem        *internal_addr; // If you have to access this memory region from within your kernel module,  
  44.                                                                // you will want to map it internally by using something like ioremap().  
  45.   
  46.     struct uio_map      *map;  
  47. };  
  48.    
  49.  struct uio_map {  
  50.     struct kobject kobj;  
  51.     struct uio_mem *mem;  
  52. };  
  53.   
  54.    
  55.  static const struct vm_operations_struct uio_vm_ops = {  
  56.     .open = uio_vma_open,  
  57.     .close = uio_vma_close,  
  58.     .fault = uio_vma_fault,  
  59. };  
  60.  static struct device_attribute uio_class_attributes[] = {  
  61.     __ATTR(name, S_IRUGO, show_name, NULL),  
  62.     __ATTR(version, S_IRUGO, show_version, NULL),  
  63.     __ATTR(event, S_IRUGO, show_event, NULL),  
  64.     {}  
  65. };  
  66.  /* UIO class infrastructure */  
  67. static struct class uio_class = {  
  68.     .name = "uio",// /sys/class/uio  
  69.     .dev_attrs = uio_class_attributes,  
  70. };  
  71.   
  72. static const struct file_operations uio_fops = {  
  73.     .owner      = THIS_MODULE,  
  74.     .open       = uio_open,  
  75.     .release    = uio_release,  
  76.     .read       = uio_read,  
  77.     .write      = uio_write,  
  78.     .mmap       = uio_mmap,  
  79.     .poll       = uio_poll,  
  80.     .fasync     = uio_fasync,  
  81.     .llseek     = noop_llseek,  
  82. };  
  83.   
  84. /* Protect idr accesses */  
  85. static DEFINE_MUTEX(minor_lock);  
  86. static DEFINE_IDR(uio_idr);  
  87. //關于idr機制,參見 http://blog.csdn.net/ganggexiongqi/article/details/6737389  
  88.   
  89. struct uio_device {  
  90.     struct module       *owner;  
  91.     struct device       *dev; //在__uio_register_device中初始化  
  92.     int         minor; // 次設備id號,uio_get_minor  
  93.     atomic_t        event; //中斷事件計數(shù)  
  94.     struct fasync_struct    *async_queue;//該設備上的異步等待隊列//  
  95.                                                                // 關于 “異步通知“ //參見LDD3第六章  
  96.     wait_queue_head_t   wait; //該設備上的等待隊列,在注冊設備時(__uio_register_device)初始化  
  97.     int         vma_count;  
  98.     struct uio_info     *info;// 指向用戶注冊的uio_info,在__uio_register_device中被賦值的  
  99.     struct kobject      *map_dir;  
  100.     struct kobject      *portio_dir;  
  101. };    
  102. /*  
  103.  * struct uio_info - UIO device capabilities  
  104.  * @uio_dev:        the UIO device this info belongs to  
  105.  * @name:       device name  
  106.  * @version:        device driver version  
  107.  * @mem:        list of mappable memory regions, size==0 for end of list  
  108.  * @port:       list of port regions, size==0 for end of list  
  109.  * @irq:        interrupt number or UIO_IRQ_CUSTOM  
  110.  * @irq_flags:      flags for request_irq()  
  111.  * @priv:       optional private data  
  112.  * @handler:        the device's irq handler  
  113.  * @mmap:       mmap operation for this uio device  
  114.  * @open:       open operation for this uio device  
  115.  * @release:        release operation for this uio device  
  116.  * @irqcontrol:     disable/enable irqs when 0/1 is written to /dev/uioX  
  117.  */       
  118. struct uio_info {  
  119.     struct uio_device   *uio_dev; // 在__uio_register_device中初始化  
  120.     const char      *name; // 調用__uio_register_device之前必須初始化  
  121.     const char      *version; //調用__uio_register_device之前必須初始化  
  122.     struct uio_mem      mem[MAX_UIO_MAPS];  
  123.     struct uio_port     port[MAX_UIO_PORT_REGIONS];  
  124.     long            irq; //分配給uio設備的中斷號,調用__uio_register_device之前必須初始化  
  125.     unsigned long       irq_flags;// 調用__uio_register_device之前必須初始化  
  126.     void            *priv; //  
  127.     irqreturn_t (*handler)(int irq, struct uio_info *dev_info); //uio_interrupt中調用,用于中斷處理  
  128.                                                                 // 調用__uio_register_device之前必須初始化  
  129.     int (*mmap)(struct uio_info *info, struct vm_area_struct *vma); //在uio_mmap中被調用,  
  130.                                                                     // 執(zhí)行設備打開特定操作  
  131.     int (*open)(struct uio_info *info, struct inode *inode);//在uio_open中被調用,執(zhí)行設備打開特定操作  
  132.     int (*release)(struct uio_info *info, struct inode *inode);//在uio_device中被調用,執(zhí)行設備打開特定操作  
  133.     int (*irqcontrol)(struct uio_info *info, s32 irq_on);//在uio_write方法中被調用,執(zhí)行用戶驅動的  
  134.                                                                                        //特定操作。  
  135. };  


------------------------------------ 函數(shù)的詳細解釋 ---------------------------------------------
1.  
 函數(shù): static int __init uio_init(void)
 功能:申請字符設備號,設備,并注冊到系統(tǒng)中,注冊uio_class到系統(tǒng)中
 調用模塊:init_uio_class()
 執(zhí)行流程:
               申請字符設備號,設備,并注冊到系統(tǒng)中,注冊uio_class到系統(tǒng)中 //init_uio_class
                                                                                        //創(chuàng)建"/sys/class/uio"
 2.
  函數(shù):uio_exit
 參數(shù):
 返回值:
 功能:注銷uio_class,注銷字符設備編號,刪除設備
 調用模塊:release_uio_class
 執(zhí)行流程:
                     注銷uio_class,注銷字符設備編號,刪除設備 //release_uio_class
 3.
 函數(shù):static void release_uio_class(void)  
 參數(shù):
 返回值:
 功能:注銷uio_class,注銷字符設備編號,刪除設備
 調用模塊:
 執(zhí)行流程:   
         注銷uio_class//class_unregister  
         注銷字符設備編號,刪除設備 //uio_major_cleanup
-------------------------------------------------
4.
 函數(shù):static int init_uio_class(void)
 參數(shù):
 返回值:
 功能:申請字符設備號,設備,并注冊到系統(tǒng)中,注冊uio_class到系統(tǒng)中
 調用模塊: uio_major_init()
                       class_register()
 執(zhí)行流程:
     申請字符設備編號,設備,并初始化//uio_major_init
     注冊class 類型全局變量uio_class到系統(tǒng)//class_register
                                                                            //ls -l /sys/class 查看

5.
 函數(shù): static int uio_major_init(void)
 參數(shù):
 返回值:
 功能:申請字符設備編號,設備,并初始化
 調用模塊:    alloc_chrdev_region()
             cdev_alloc()
             kobject_set_name()
             cdev_add()
 執(zhí)行流程:
     申請字符設備編號(多個)//alloc_chrdev_region
                                   //2^UIO_MAX_DEVICES個從設備
                                   //設備的名字為"uio"
      分配一個表示字符設備的cdev結構//cdev_alloc
      初始化cdev結構的file_operations類型字段//控制cdev設備的各種操作,
                                            // 如 open, close, read, write...
      設置cdev結構的kobj字段的name為uio //kobject_set_name
      添加字符設備到系統(tǒng)中 //cdev_add,調用成功后,我們的設備就“活了”
                              // cat /proc/devices ,可以查看到分配到主設備號
      保存主設備號到全局變量uio_major    
      保存設備指針到全局變量uio_cdev    
     
      返回                              
                                          
6.
  函數(shù):static void uio_major_cleanup(void)    
 參數(shù):
 返回值:
 功能:注銷字符設備編號,刪除設備
 調用模塊:unregister_chrdev_region
 執(zhí)行流程:
           注銷字符設備編號//unregister_chrdev_region
           刪除設備uio_cdev //cdev_del
 
  ===== file_operations         
 7.
 函數(shù):static int uio_open(struct inode *inode, struct file *filep)
 參數(shù):inode:
              filep:
 返回值:
 功能:獲得和次設備號關聯(lián)的uio_device指針,創(chuàng)建一個輔助變量listener, 并調用
              info指向的uio_info結構中的open方法
 調用模塊:
 執(zhí)行流程:
         獲得保護uio_idr的鎖  //mutex_lock
         從inode 結構中獲取次編號 //iminor
         獲得和次編號關聯(lián)的uio_device指針 //idr_find <----------<<<< 在那里進行地設置呢???
                                                                                  // 在 uio_get_minor 中分配的次設備編號并設置的關聯(lián)
         放棄鎖 //mutex_unlock
         增加uio_device類型指針指向的模塊的引用計數(shù)  //try_module_get
         分配一個uio_listener類型的listener  //kmalloc
         關聯(lián)listener和 uio_device 指針
         獲得uio_device 指向設備的事件計數(shù)值,并存入listener //atomic_read
         把listener指針保存到filep->private_data字段
         調用uio_device的info字段指向的uio_info中的open方法//*****
 
 8.
  函數(shù):static int uio_release(struct inode *inode, struct file *filep)        
 參數(shù):inode
              filep
 返回值:
 功能:從而調用uio_device的字段info指向的uio_info中的release方法
              釋放輔助結構體listener
 調用模塊:
 執(zhí)行流程:
           從filep->private_data中獲得uio_open中保存的listener指針。
           利用listener指針找到指向uio_device類型結構指針
           從而調用uio_device的字段info指向的uio_info中的release方法。
           減少uio_device類型指針指向的模塊的引用計數(shù)//module_put
           釋放listener結構體 //kfree
           
 9.
  函數(shù):static int uio_fasync(int fd, struct file *filep, int on)
 參數(shù):
         fd
         filep
         on : 0, 刪除;非零,添加
 返回值:
 功能: 管理uio_device的async_queue
 調用模塊:fasync_helper()
 執(zhí)行流程:
             從filep->private_data中獲得uio_open中保存的listener指針。
            利用listener指針找到指向uio_device類型結構指針    
            設置uio_device的async_queue//fasync_helper

10.
 函數(shù):static unsigned int uio_poll(struct file *filep, poll_table *wait)
 參數(shù):  filep
                wait
 返回值:
 功能:    使進程在傳遞到該系統(tǒng)調用的所有文件描述符對應的等待隊列上等待,
                  并返回一個是否可以立即無阻塞執(zhí)行的位掩碼
 調用模塊:
 執(zhí)行流程:
              從filep->private_data中獲得uio_open中保存的listener指針。
            利用listener指針找到指向uio_device類型結構指針    
            判斷用uio_device類型指針的info字段(uio_info類型)的irq成員不為0,則繼續(xù),
                        否則,返回IO錯誤
            向poll_table類型的wait表中添加uio_device類型指針指向結構的wait等待隊列//poll_wait
                                                                      //!!!! 注意poll_wait并不阻塞
            如果listener中的事件計數(shù)值event_count和uio_device的
                     事件計數(shù)值count不一致時// uio_interrupt調用了uio_event_notify對
                                                                    //中斷事件計數(shù)器增一
                        返回“通?!钡臄?shù)據(jù)可讀的位掩碼
    
11.     
 函數(shù):static ssize_t uio_read(struct file *filep, char __user *buf,
            size_t count, loff_t *ppos)
 參數(shù):
            filep
            buf
            count
            ppos
 返回值:
 功能:復制uio設備中斷事件計數(shù)器的值到用戶空間
 調用模塊:
 執(zhí)行流程:
                 從filep->private_data中獲得uio_open中保存的listener指針
                 利用listener指針找到指向uio_device類型結構指針    
                 創(chuàng)建一個等待隊列的項 //DECLARE_WAITQUEUE
                  檢查確認uio設備的設備info的中斷號(0)不為零
                  添加本進程到uio設備的等待隊列wait上 // add_wait_queue
                                            //由uio_interrupt調用uio_event_notify喚醒
    REP:    設置當前進程的 "可中斷標志"
                   檢查是否有中斷事件發(fā)生,
                            如果有(listener中的中斷事件計數(shù)值event_count)和uio設備中的中斷事件
                                           計數(shù)器值不一致),則將設備中斷計數(shù)器的值復制到用戶空間
                                            并將listener中的中斷事件計數(shù)值更新為設備的中斷事件計數(shù)值
                                            把當前進程設置為TASK_RUNNING狀態(tài),
                                                     并將當前進程從uio設備的等待隊列wait上刪除
                            如果文件讀時設置了O_NONBLOCK標志,
                                        那么,把當前進程設置為TASK_RUNNING狀態(tài),
                                                     并將當前進程從uio設備的等待隊列wait上刪除
                                                     返回 -EAGAIN
                           檢查當前進程是否有信號處理 //signal_pending
                                          //http://blog./space.php?uid=20746501&do=blog&cuid=1820175
                                        如有,把當前進程設置為TASK_RUNNING狀態(tài),
                                        并將當前進程從uio設備的等待隊列wait上刪除
                                        并返回 -ERESTARTSYS
                           執(zhí)行調度 //schedule
                           JMP REP
                                       
                  
                  
 
12.
 函數(shù):static irqreturn_t uio_interrupt(int irq, void *dev_id)  // <---------------<<<<<<<<<<被誰調用呢??? __uio_register_device中設定
 參數(shù):    irq
                  dev_id
 返回值:
 功能: 調用uio_info中注冊的handler中斷處理函數(shù),對設備的中斷事件計數(shù)器增一
                并通知各讀進程,有數(shù)據(jù)可讀
 調用模塊:
 執(zhí)行流程:     
                   從filep->private_data中獲得uio_open中保存的listener指針
                   調用 uio_device類型指針的info字段(uio_info類型)的handler  
                   如果屬于本設備的中斷,并且在handler中已經(jīng)處理過
                             那么對設備的中斷事件計數(shù)器增一,
                            并通知各讀進程,有數(shù)據(jù)可讀 //uio_event_notify
 
13.
  函數(shù):void uio_event_notify(struct uio_info *info)
 參數(shù):
 返回值:
 功能:“觸發(fā)“ 一個中斷事件,對設備的中斷事件計數(shù)器增一,并通知各讀進程,有數(shù)據(jù)
               可讀
 調用模塊:
 執(zhí)行流程:          
                從filep->private_data中獲得uio_open中保存的listener指針
                對中斷事件計數(shù)器增一
                喚醒阻塞在設備等待隊列wait上的讀進程  //wake_up_interruptible
                                                                                            // 該隊列上的進程在uio_read中添加
                向異步等待隊列async_queue發(fā)出可讀信號 //kill_fasync             
14.
  函數(shù):static ssize_t uio_write(struct file *filep, const char __user *buf,
            size_t count, loff_t *ppos)
 參數(shù):
 返回值:
 功能: 讀取用戶空間的值,并調用uio_device注冊的irqcontrol函數(shù)
 調用模塊:
 執(zhí)行流程:          
                    從filep->private_data中獲得uio_open中保存的listener指針
                    調用 uio_device類型指針的info字段(uio_info類型)的handler
                    檢驗info字段(uio_info類型)的中斷號irq
                    讀取從用戶空間傳過來的32位的值//copy_from_user
                    調用info字段(uio_info類型)的irqcontrol函數(shù),將用戶空間傳遞過來的32位值
                         作為參數(shù)傳入。
                    
 15.
 函數(shù):static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
 參數(shù):
 返回值:
 功能:
 調用模塊:
 執(zhí)行流程:    
                     從filep->private_data中獲得uio_open中保存的listener指針
                    調用 uio_device類型指針的info字段(uio_info類型)的handler
                    保存uio_device類型指針到 vma 的vm_private_data    
                     返回映射區(qū)域的索引(比如 mapX,的X)//uio_find_mem_index
                     計算實際的頁數(shù)和請求的頁數(shù)
                     如果實際的頁數(shù)小于請求的頁數(shù)那么,返回-EINVAL
                     如果uio設備注冊有mmap函數(shù),那么就調用它
                     當內存區(qū)域的類型為UIO_MEM_PHYS時,
                            //uio_mmap_physical
                     當內存區(qū)域的類型為UIO_MEM_LOGICAL/UIO_MEM_VIRTUAL時,
                            為虛擬內存區(qū)域設置操作,和告訴內存不要將
                            該區(qū)域交換出去,訪問計數(shù)器增一//uio_mmap_logical
     備注:
 
  1. actual_pages = ((idev->info->mem[mi].addr & ~PAGE_MASK)  
  2.      + idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;  
  3.        
  4.      ------------> 地址遞增的方向  
  5.      ---\\------------|--pg--------------\\--|--pg----------------\\------pg---------------\\----------  
  6.           ^           ^                      ^  
  7.           |           |                      |  
  8.           |           |                      |  
  9.           +-addr'-----+-------size-----------|  
  10.           其中  addr' = addr & ~PAGE_MASK  
  11.           \\表示頁  
  12.           這樣可以看出actual_pages為要映射的內存實際跨越的內存頁框數(shù)  


16.
  函數(shù):static int uio_find_mem_index(struct vm_area_struct *vma)
 參數(shù):
 返回值:
 功能: 返回映射區(qū)域的索引(比如 mapX,的X)
 調用模塊:
 執(zhí)行流程:   
            返回虛擬內存區(qū)域在文件中以頁為單位的偏移  //即vma->vm_pgoff

            //  其實 vma->vm_pgoff 被內核自動填充為了用戶空間調用mmap時的最后一個參數(shù)offset>>page_size

            // 而uio用戶空間編程要求mmap最后一個參數(shù)為N*getsizeofpage(),從而 vma->vm_pgoff為映射區(qū)域的索引      

            
17.
  函數(shù):static int uio_mmap_logical(struct vm_area_struct *vma)
 參數(shù):
 返回值:
 功能: 為虛擬內存區(qū)域設置操作,和告訴內存不要將該區(qū)域交換出去,訪問計數(shù)器增一
 調用模塊:
 執(zhí)行流程:        
            設置vma 標志VM_RESERVED告訴內存管理系統(tǒng)不要將VMA交換出去         
            設置vma的vm_ops // 對虛擬內存區(qū)的操作集合的設置
             uio設備的虛擬內存區(qū)域訪問計數(shù)器(vma_count)增一 //  uio_vma_open
                                                                               
18.      
 函數(shù):static void uio_vma_open(struct vm_area_struct *vma)
 參數(shù):
 返回值:
 功能:uio設備的虛擬內存區(qū)域訪問計數(shù)器(vma_count)增一   
 調用模塊:
 執(zhí)行流程:      
                     uio設備的虛擬內存區(qū)域訪問計數(shù)器(vma_count)增一      

19.    
 函數(shù):static void uio_vma_close(struct vm_area_struct *vma)
 參數(shù):
 返回值:
 功能:
 調用模塊:
 執(zhí)行流程:  
            uio設備的虛擬內存區(qū)域訪問計數(shù)器(vma_count)減一
20.
 函數(shù):static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 參數(shù):
 返回值:
 功能: 為失效的虛擬地址查找正確的page結構,并增加它的引用計數(shù)
 調用模塊:
 執(zhí)行流程:
           從虛擬內存區(qū)域結構的私有數(shù)據(jù)字段獲得uio設備描述結構的指針
           返回映射區(qū)域的索引(比如 mapX,的X)//uio_find_mem_index
           如果是UIO_MEM_LOGICAL類型的虛地址
                        由內核邏輯地址得到該頁的描述結構的指針 //virt_to_page
            如果是UIO_MEM_VIRTUAL類型的虛地址
                        有vmalloc得到的虛擬地址得到該頁的描述結構//vmalloc_to_page
            增加內存頁的使用計數(shù) //get_page
            保存頁結構的指針
           
 備注:
     /*
     * We need to subtract mi because userspace uses offset = N*PAGE_SIZE
     * to use mem[N].
     */
    offset = (vmf->pgoff - mi) << PAGE_SHIFT; /
    設備可以有多個內存映射塊,offset為塊內偏移。
    


21.
 函數(shù):static int uio_mmap_physical(struct vm_area_struct *vma)
 參數(shù):
 返回值:
 功能: 把內核空間的物理內存區(qū)域映射到用戶空間
 調用模塊:
 執(zhí)行流程:
            從虛擬內存區(qū)域結構的私有數(shù)據(jù)字段獲得uio設備描述結構的指針
            返回映射區(qū)域的索引(比如 mapX,的X) //uio_find_mem_index
            設置虛擬內存區(qū)域的標志VM_IO ,VM_RESERVED
                                       //VM_IO將該VMA標記為內存映射的IO區(qū)域,VM_IO會阻止系
                                       // 統(tǒng)將該區(qū)域包含在進程的存放轉存(core dump)中,
                                       // VM_RESERVED標志內存區(qū)域不能被換出。
             設置頁的存取權限  //pgprot_nocached禁止了相關頁的CACHE 和寫緩沖(
                                                      //位于處理器和主存之間,將處理器和cache從及
                                                      //較慢的主存寫操作解脫出來的FIFO存儲器)
             把內核空間的內存區(qū)域映射到用戶空間 //remap_pfn_range
22.
 函數(shù):static int uio_get_minor(struct uio_device *idev)
 參數(shù):
 返回值:
 功能:分配id號,并將id號和指針關聯(lián)
 調用模塊:
 執(zhí)行流程:
                獲得保護uio_idr的鎖          //mutex_lock
                為idr分配內存 //idr_pre_get
                分配id號,并將id號和指針關聯(lián) //idr_get_new
                                                                                 // 在uio_open中用到了
                將分配到的id保存到uio設備結構變量的minor字段
                釋放鎖 //mutex_unlock
 23.
  函數(shù):static void uio_free_minor(struct uio_device *idev)
 參數(shù):
 返回值:
 功能:從idr表中刪除id與指針的關聯(lián)
 調用模塊:
 執(zhí)行流程:
                 獲得保護uio_idr的鎖          //mutex_lock        
                 從idr表中刪除id與指針的關聯(lián) //idr_remove
                 釋放uio_idr的鎖 //mutex_unlock
       
24.
  函數(shù):static ssize_t show_name(struct device *dev,
             struct device_attribute *attr, char *buf)
 參數(shù):
 返回值:
 功能:顯示uio設備的名字
 調用模塊:
 執(zhí)行流程:  
                    獲得保存在driver_data中的uio_device指針 //driver_data <-------------<<<<在那里設定???
                    把uio設備的名字字符串寫到buf中,將在用戶空間看到它的值
                    
25.
 函數(shù):static ssize_t show_version(struct device *dev,
                struct device_attribute *attr, char *buf)
 參數(shù):
 返回值:
 功能:顯示 uio設備的版本
 調用模塊:
 執(zhí)行流程:
 
 26.
  函數(shù):static ssize_t show_event(struct device *dev,
              struct device_attribute *attr, char *buf)
 參數(shù):
 返回值:
 功能:顯示uio設備中斷計數(shù)器的值
 調用模塊:
 執(zhí)行流程:
27,28,29,30  //map  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
功能: 顯示kobject對象的屬性
    map_name_show
    map_addr_show
    map_size_show
    map_offset_show      
 31.
  函數(shù):static void map_release(struct kobject *kobj)
 參數(shù):
 返回值:
 功能:釋放uio_map結構
 調用模塊:
 執(zhí)行流程:    
            得到包含kobj的 uio_map 結構的指針 // to_map
            釋放uio_map結構
32.
 函數(shù): static ssize_t map_type_show(struct kobject *kobj, struct attribute *attr,
                 char *buf)    
 參數(shù):
 返回值:
 功能:調用 map_name_show, map_addr_show, map_size_show,map_offset_show方法
                顯示mem map的各種屬性
 調用模塊:
 執(zhí)行流程:   
                 得到包含kobj的 uio_map 結構的指針 // to_map
                 得到uio_map的uio_mem類型成員的指針
                 得到包含attribute 的map_sysfs_entry結構的指針//
                 調用map_sysfs_entry的show函數(shù)
                 
 33, 34, 35, 36
  功能:   顯示 io 區(qū)域的屬性
                   portio_name_show,
                   portio_start_show,
                   portio_size_show,
                   portio_porttype_show
37.    
 函數(shù):static void portio_release(struct kobject *kobj)   
 參數(shù):
 返回值:
 功能: 釋放uio_portio結構
 調用模塊:
 執(zhí)行流程:    
            得到包含kobj的 uio_portio 結構的指針 // to_map
            釋放uio_portio結構      
            
38.
 函數(shù):static ssize_t  portio_type_show(struct kobject *kobj, struct attribute *attr,
                 char *buf)
 參數(shù):
 返回值:

 功能: 調用

                   portio_name_show,
                   portio_start_show,
                   portio_size_show,
                   portio_porttype_show

        顯示 io region 的屬性

 調用模塊:
 執(zhí)行流程:
                得到包含kobj的 uio_portio 結構的指針 // to_map
                得到uio_portio內嵌的uio_port結構體的指針
                得到包含attr 的portio_sysfs_entry類型的指針
                調用show方法
39.
 函數(shù):static int uio_dev_add_attributes(struct uio_device *idev)
 參數(shù):
 返回值:
 功能:在sysfs中注冊 內存映射和端口io區(qū)域 相關的文件和文件夾,以及相關屬性。
 調用模塊:
 執(zhí)行流程:
         內存映射 在sysfs中的注冊:
                create a struct kobject “maps”dynamically and register it with sysfs//kobject_create_and_add
                                                                                                //     "uio/maps" directory created
                 分配uio_map 類型變量map
                 初始化map的obj成員,并為之添加屬性// kobject_init
                 關聯(lián) uio_map類型變量map和uio_mem類型變量mem
                                                     //把mem地址保存在uio_map類型變量的成員中
                                                     //把map地址保存在mem類型變量的成員中
                在uio/uioX/maps下再創(chuàng)建mapX 對象//kobject_create_and_add,"uio/uioX/maps/mapX"
                通知用戶空間"uio/uioX/maps/mapX"可用 //kobject_uevent
          端口io區(qū)域在 sysfs中的注冊:            
                create a struct kobject “portio”dynamically and register it with sysfs//kobject_create_and_add
                                                                                                //     "uio/uioX/portio" directory created
                 分配uio_portio 類型變量portio
                 初始化map的portio成員,并為之添加屬性// kobject_init
                 關聯(lián) uio_portio類型變量portio和uio_port類型變量port
                                                     //把port地址保存在uio_portio類型變量的成員中
                                                     //把portio地址保存在port類型變量的成員中
                在uio/uioX/portio下再創(chuàng)建portX對象//kobject_create_and_add,"uio/uioX/portio/portX"
                通知用戶空間"uio/uioX/portio/portX"可用 //kobject_uevent                          
 40.
  函數(shù):static void uio_dev_del_attributes(struct uio_device *idev)
 參數(shù):
 返回值:
 功能: 刪除在uio_dev_add_attributes中,添加的kobject對象,
                從而刪除在uio目錄下的各個文件和文件夾
 調用模塊:
 執(zhí)行流程:...
                
 41.
 函數(shù):int __uio_register_device(struct module *owner,
              struct device *parent,
              struct uio_info *info)
 參數(shù):owner:  module that creates the new device
                parent: parent device
                info:   UIO device capabilities
 返回值:
 功能:register a new userspace IO device
 調用模塊:
 執(zhí)行流程:          
                檢查 parent,和info的name,和version,確保不為空
                分配uio_device型變量的空間
                初始化uio設備的等待隊列
                初始化uio設備的中斷事件計數(shù)器event為0//atomic_set
                分配id號,并將id號和指針關聯(lián) //uio_get_minor
                creates a device and registers it with sysfs//device_create
                                                                                       //在uio class目錄下創(chuàng)建 uioX,即'uio/uioX'
                在sysfs中注冊 內存映射和端口io區(qū)域 相關的文件和文件夾,
                         以及相關屬性。                       //uio_dev_add_attributes
                將完成初始化的uio_device的指針保存在uio_info類型變量的uio_dev中
                為uio_device注冊中斷函數(shù)uio_interrupt //request_irq
 42.  
 函數(shù):void uio_unregister_device(struct uio_info *info)
 參數(shù):
 返回值:
 功能:卸載uio設備
 調用模塊:
 執(zhí)行流程:
                 從idr表中刪除uio_device 的id 與指針的關聯(lián)//uio_free_minor       
                 刪除在uio_dev_add_attributes中,添加的kobject對象,// uio_dev_del_attributes
                              從而刪除在uio目錄下的各個文件和文件夾
                 刪除設備//device_destroy
                 釋放uio_device 類型結構的空間//kfree               

===================================================================
參考:
            1. Documentation/DocBook/uio-howto.tmpl
            2. drivers/uio/uio.c
            3.  vm_area_struct   http://blog.csdn.net/ganggexiongqi/article/details/6746248
            4. 淺析linux內核中的idr機制 http://blog.csdn.net/ganggexiongqi/article/details/6737389

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多