快速上手Linux裝置驅動 之一切皆是檔案思想

2021-06-07 23:54:16 字數 4322 閱讀 1948

只要用過linux的筒子,或者保守點說接觸到一些linux思想的同志肯定聽說過這樣一句話,在linux下,「一切皆是檔案」!

不錯,今天walfred將在快速上手linux裝置驅動這一塊,談談linux的裝置也符合「一切皆是檔案」的思想在linux裝置驅動模型應用。如果你不理解linux裝置模型,請看下面:

1.[快速上手linux裝置驅動]之我看linux裝置模型(匯流排篇)

2.[快速上手linux裝置驅動]之我看linux裝置模型(裝置篇)

3.[快速上手linux裝置驅動]之我看linux裝置模型(裝置驅動篇)

4.[快速上手linux裝置驅動]之我看linux裝置模型(類子系統篇)

「一切皆是檔案」是 unix/linux 的基本哲學之一。不僅普通的檔案,目錄、字元裝置、塊裝置、 套接字等在 unix/linux 中都是以檔案被對待;它們雖然型別不同,但是對其提供的卻是同一套操作介面。

當然,在這裡我先給大家上一道預備知識的大菜,不過這邊我先暫時小打小鬧下,稍微說下,日後詳述之。

有請vfs上場--

虛擬檔案系統(virtual file system, 簡稱 vfs), 是 linux 核心中的乙個軟體層,用於給使用者空間的程式提供檔案系統介面;同時,它也提供了核心中的乙個抽象功能,允許不同的檔案系統共存。系統中所有的檔案系統不但依賴 vfs 共存,而且也依靠 vfs 協同工作。

為了能夠支援各種實際檔案系統,vfs 定義了所有檔案系統都支援的基本的、概念上的介面和資料 結構;同時實際檔案系統也提供 vfs 所期望的抽象介面和資料結構,將自身的諸如檔案、目錄等概念在形式 上與vfs的定義保持一致。換句話說,乙個實際的檔案系統想要被 linux 支援,就必須提供乙個符合vfs標準 的介面,才能與 vfs 協同工作。實際檔案系統在統一的介面和資料結構下隱藏了具體的實現細節,所以在vfs 層和核心的其他部分看來,所有檔案系統都是相同的。下圖顯示了vfs在核心中與實際的檔案系統的協同關係。

正文

從上圖,我們可以簡單的看出乙個在user space的應用程式通過系統呼叫,經過vfs層面,在和裝置驅動打交道,最後裝置驅動驅動對應裝置,這是乙個比較簡單的描述,如果分析起來也就不難得到:user space的應用程式與vfs的介面就是系統呼叫,vfs與驅動程式的介面就是file_operations。

關於file_operations

從之前打過交道的字元裝置驅動,我們就知道存在了這麼一種file_operations結構體,我現在可以說在描述乙個裝置,我們使用者最接近的方法是file_operations,linux每類裝置都定義了檔案操作方法,例如,字元裝置的操作方法為def_chr_fops,塊裝置為def_blk_fops,網路裝置為bad_sock_fops。每種裝置型別底層操作方法是不一樣的,但是通過file_operations方法將裝置型別的差異化遮蔽了,這就是linux能夠將所有裝置都理解為檔案的緣由。這裡因為我這幾天在搞塊裝置,所以先看下def_blk_fops。

struct file_operations def_blk_fops = {

open:           blkdev_open,

release:        blkdev_close,

llseek:         block_llseek,

read:           generic_file_read,

write:          generic_file_write,

mmap:           generic_file_mmap,

fsync:          block_fsync,

ioctl:          blkdev_ioctl,

裝置差異性

到這裡,又提出乙個問題:既然這樣,那裝置的差異化又該如何體現呢?在檔案系統層定義了檔案系統訪問裝置的方法,該方法就是address_space_operations,檔案系統通過該方法可以訪問具體的裝置。對於字元裝置而言,沒有實現address_space_operations方法,也沒有必要,因為字元裝置的介面與檔案系統的介面是一樣的,在字元裝置open操作的過程中,將inode所指向的file_operations替換成cdev所指向的file_operations就可以了。這樣使用者層讀寫字元裝置可以直接呼叫cdev中file_operations方法了。 

[linux/fs.h]

*linux頁快取記憶體實用化address_space結構體描述頁快取記憶體中的頁面

*定義檔案在linux/fs.h中

struct address_space {

struct inode            *host;              /* 擁有節點 */

struct radix_tree_root  page_tree;          /* 包含全部頁面的radix樹 */

spinlock_t              tree_lock;          /* 保護page_tree的自旋鎖 */

unsigned int            i_mmap_writable;    /* vm_shared記數 */

struct prio_tree_root   i_mmap;             /* 似有對映鍊錶 */

struct list_head        i_mmap_nonlinear;   /* vm_nonlinear鍊錶 */

spinlock_t              i_mmap_lock;        /* 保護i_mmap的自旋鎖 */

atomic_t                truncate_count;     /* 截斷記數 */

unsigned long           nrpages;            /* 頁總數 */

pgoff_t                 writeback_index;    /* 回寫的起始偏移 */

struct address_space_operations   *a_ops;   /* 操作表*/

unsigned long           flags;              /* gfp_mask掩碼與錯誤標識 */

struct backing_dev_info *backing_dev_info;  /* 預讀資訊 */

spinlock_t              private_lock;       /* 私有address_space鎖 */

struct list_head        private_list;       /* 私有address_space鍊錶 */

struct address_space_operations {

int (*writepage)(struct page *, struct writeback_control *);

int (*readpage) (struct file *, struct page *);

int (*sync_page) (struct page *);

int (*writepages) (struct address_space *, struct writeback_control *);

int (*set_page_dirty) (struct page *);

int (*readpages) (struct file *, struct address_space *,

struct list_head *, unsigned);

int (*prepare_write) (struct file *, struct page *, unsigned, unsigned);

int (*commit_write) (struct file *, struct page *, unsigned, unsigned);

sector_t (*bmap)(struct address_space *, sector_t);

int (*invalidatepage) (struct page *, unsigned long);

int (*releasepage) (struct page *, int);

int (*direct_io) (int, struct kiocb *, const struct iovec *,

loff_t, unsigned long);

到這裡,是不是明白了linux的「裝置」也是檔案了呢?

塊裝置驅動程式之一

linux支援的兩種重要的裝置型別分別是字元裝置和塊裝置,塊裝置可以隨機地以固定大小的塊傳送資料。與字元裝置相比,塊裝置有以下幾個特殊之處 塊裝置可以從資料的任何位置進行訪問 塊資料總是以固定長度進行傳輸,即便請求的這是乙個位元組 對塊裝置的訪問有大量的快取。當進行讀時,如果已經快取了,就直接使用快...

Linux課堂筆記之一簡單上手

a 登陸centos 1 首次登陸的時候選擇語言,選擇中文 2 為了安全使用用兩個賬號,乙個管理者的賬號,乙個普通賬號 3 linux有圖形介面和文字介面,預設登陸的是gnome b gnome 1 控制面板 2 桌面 3 下方工作列 4 資源管理器 鸚鵡螺 5 切換中文輸入法 ctrl space...

Linux字元裝置驅動 一

inux字元裝置驅動之概述篇 一.概述 1.在linux中有一句哲學 linux下皆檔案 裝置驅動程式為應用程式遮蔽了硬體的細節,這樣在應用程式看來,硬體裝置只是乙個裝置檔案,應用程式可以像操作普通檔案一樣對硬體裝置進行操作。但是裝置檔案和普通檔案還是又差別的。那麼裝置和普通檔案之間又有什麼區分呢?...