學習linux基礎入門教程,Linux把設備納入文件系統的范疇來管理。每個設備在Linux系統上看起來都像一個文件,它們存放在/dev目錄中,稱為"設備節點"或“設備文件”。
每當用戶程序要訪問某個設備時,通過系統調用,內核根據設備結點的信息調用相應的驅動程序。當驅動程序執行完后,又返回至用戶進程。
應用層與驅動層層次結構框圖
每一個字符設備都有自己的底層操作函數;也就是說每一個設備都對應著自己的file_operations結構體;
那么打開的文件file->f_op指針應該指向那一個file_operations結構體呢?或者說 file->f_op怎樣找到對應的file_operations呢?
這跟打開的設備文件里面的信息有關。
通過分析字符設備的代碼來了解其核心過程
-字符設備的源碼在文件 fs/char_dev.c中,包括設備號申請函數,cdev注冊函數都在這個文件里面實現。
申請設備號的過程分析
-設備號的注冊或自動分配函數是下面兩個
alloc_chrdev_region()
register_chrdev_region()
-兩個函數都會調用__register_chrdev_region()函數;這個函數完成如下操作:
如果是自動分配設備號
在全局數組chrdevs[ ]中找到一個空位,這個空位的數組下標就是主設備號;設置這個空位。
如果是直接注冊設備號
以主設備號為下標,找到數組chrdevs[ ]中的成員,設置這個成員;
-全局數組chrdevs[]當前的成員數為255,下標從0-254,也就是說,當前內核的字符設備主設備號范圍 0-254.
注冊cdev分析
-cdev結構的注冊分兩步,步是初始化cdev結構;第二步是注冊。cdev_add()函數分析如下:
內核使用一個數據結構cdev_map來記錄系統中所有的字符設備(cdev);
而設備號的維護是由全局chrdevs[]來完成的;
在驅動模塊入口函數中:
-申請設備號:就是在數組chrdevs[]中找一個空位;
-注冊字符設備:就是將cdev添加到cdev_map中;
字符設備注冊過程如下圖:
linux基礎入門教程:open系統調用分析
-open系統調用的實現在fs/open.c文件中
do_filp_open()函數經過重重調用,會調用vfs_select_inode 和do_dentry_open
do_filp_open()
path_openat
do_last
vfs_open
inode = vfs_select_inode //獲取文件的inode信息
do_dentry_open
//將inode->i_fop拷貝給f->f_op
f->f_op = fops_get(inode->i_fop);
//調用inode->i_fop->open
open = f->f_op->open;
open(inode, f);
inode對應一個文件;我們在創建一個設備文件時,就是創建一個inode;
在用戶空間創建設備文件時,對應的inode->i_fop指向fs/char_dev.c中的def_chr_fops,def_chr_fops的成員open指向chrdev_open()函數。
open系統調用的層次如下
chrdev_open函數分析
open系統調用的總體過程如下圖:
從上面分析字符設備的框架我們可以得出以下結論:
編寫字符設備驅動程序的流程如下:
編寫底層操作函數
在全局數據結構chr_devs中找到一個空位;(申請設備號)
將底層操作函數的集合填到cdev_map結構中;(注冊cdev)
以上就是粵嵌linux基礎入門教程之字符設備驅動框架分析,歡迎大家來粵嵌一起學習交流。