inode 裝置檔案

2021-05-24 13:27:40 字數 3386 閱讀 1397

裝置並不是通過其檔名來標識,而是通過檔案的主、次裝置號標識(檔名和檔案的主次裝置號在裝置檔案的父目錄的inode的資料區中表現出來的,這是fs層的東東)。

裝置檔案和普通檔案的區別:

檢視裝置檔案的命令為:ls -l /dev/

1:訪問許可權前面的字母b/c,分別表示塊裝置和字元裝置。

2:裝置檔案沒有檔案長度,而增加了另外兩個值,分別為主裝置號和次裝置號。二者共同形成乙個唯一的號碼,核心由此可以查詢到對應的裝置驅動程式。

由於引入了udev機制,/dev不再放置到基於磁碟的檔案系統中,而是使用tmpfs,這是ram磁碟檔案系統ramfs的一種輕型變體。這意味著裝置結點不是永續性的,系統關機/重啟後就會消失。

ioctl:輸入輸出控制介面,是用於配置和修改特定裝置屬性的通用介面。

核心如果能了解到系統中有哪些字元裝置和塊裝置可用,那自然是很有利的,因而需要維護乙個資料庫,此外必須提供乙個介面,以便驅動程式開發者能夠將新項新增到資料庫中。

資料結構:

1、裝置資料庫

儘管塊裝置和字元裝置彼此的行為有很大的不同,但用於跟蹤所有可用裝置的資料庫是相同的。因為字元裝置和塊裝置都是通過唯一的裝置號標識。但是,資料庫會根據塊裝置/字元裝置來跟蹤不同的物件。

。每個字元裝置都表示為乙個struct cdev的例項

。struct genhd用於管理塊裝置的分割槽,作用類似於字元裝置的cdev.

有兩個全域性陣列(bdev_map用於塊裝置,cdev_map用於字元裝置)用來實現雜湊表,使用主裝置號作為雜湊鍵。cdev_map和bdev_map都是同一資料結構struct kobj_map的例項。雜湊的方法很簡單:major%255.

struct kobj_map *probes[255];

struct mutex *lock;

};互斥量lock實現了對雜湊表訪問的序列化.struct probe的成員如下:

next:將所有雜湊表鏈結在乙個單鏈表中。(沒有搞明白這個單鏈表中的裝置的主裝置號都是相同的否?

dev: 表示裝置號,包括主次裝置號

rang:從裝置號的連續範圍儲存在range中。那麼與裝置關聯的各個從裝置號的範圍是[minors(dev), minors(dev)+range-1].

owner:指向提供裝置驅動程式的模組。

get:指向乙個函式,可以返回與裝置關聯的kobject例項。

data:字元裝置和塊裝置的區別就在於data.對於字元裝置,他指向struct cdev的乙個例項,而對於塊裝置,則指向struct genhd的例項。

2、字元裝置範圍資料庫

第二類資料庫只是用於字元裝置。他是用於管理為驅動程式分配的裝置號範圍。驅動程式可以請求乙個動態的裝置號(用register_chrdev_region()函式註冊裝置號),或者指定乙個範圍,從中獲取(用alloc_chrdev_region()函式分配裝置號)。

再次使用雜湊表來跟蹤已經分配的裝置號範圍,並同樣使用主裝置號作為雜湊鍵。資料結構如下:

static struct char_device_struct *chrdevs[chrdev_major_hash_size];

next:鏈結同一雜湊行中的所有雜湊元素

major:主裝置號

baseminor是包含minorct個從裝置號的連續範圍的最小的從裝置

name為裝置提供了乙個識別符號

與檔案系統關聯

inode中裝置檔案成員

只列出與驅動有關的成員

struct inode else if (s_isblk(mode)) else if (s_isfifo(mode))

inode->i_fop = &def_fifo_fops;

else if (s_issock(mode))

inode->i_fop = &bad_sock_fops;

else

printk(kern_debug "init_special_inode: bogus i_mode (%o)/n", mode);

}用於字元裝置的標準操作

fs/device.c

const struct file_operations def_chr_fops = ;

chrdev_open()函式的主要任務是向該結構(其實不明白"該結構"指的是什麼結構,似乎有點像struct file)填入已開啟裝置的函式指標(file_operation),使得能夠在裝置檔案上執行有意義的操作,並最終能夠操作裝置本身。

chrdev_open()函式的框圖:

假定表示裝置檔案的inode此前沒有開啟過,根據裝置號,kobject_lookup查詢字元裝置的資料庫(cdev_map),並返回與該驅動程式向關聯的kobject例項。該返回值可用於獲取cdev例項

獲取了對應於裝置的cdev例項,核心通過cdev->ops還可以訪問特定於裝置的file_operations.接下來設定各種資料結構之間的關聯

inode->i_cdev指向所選擇的cdev例項。在下一次開啟該inode時,就不必再查詢字元裝置的資料庫,因為可以使用快取的值。

該inode將新增到cdev->list

file->f_ops是用於struct file新的file_operations,設定為指向struct cdev給出的file_operations例項。         

接下來呼叫struct file新的file_operations中的open函式(現在是用於特定的裝置,我們針對特定的裝置在驅動層實現的open函式),在裝置上執行所需的初始化任務。    

用於塊裝置的標準操作

fs/block_dev.c

const struct file_operations def_blk_fops = ;

儘管file_operations與block_device_operations的結構類似,但兩者不能混淆。file_operations由vfs層用來與使用者空間通訊的,他裡面的函式是有使用者層來呼叫的。其中的函式會呼叫block_device_operations中的函式,以實現與塊裝置的通訊。block_device_operations必須針對各種具體的塊裝置分別實現,對裝置的屬性加以抽象,而在此基礎上建立file_operations,是使用者可以使用相同的操作(file_operations提供的函式)即可處理所有的塊裝置。

如何根據檔案的inode號查詢inode資料

1.根據ls i 檢視檔案的inode號 2.使用debugfs命令檢視檔案所在磁碟分割槽的超級塊資訊 debugfs dev sda2 debugfs stats inode count 5152768 block count 20590080 block size 4096 inode size...

Linux 檔案鎖與 inode

1.程序 a 排他鎖住某檔案之後,程序 b 可以修改該檔案,但不能鎖住該檔案。2.程序 a 排他鎖住某檔案之後,程序 b 修改該檔案之後,因為檔案 inode 沒有改變,所以依然不能鎖住該檔案。3.程序 a 排他鎖住某檔案之後,程序 b 可以刪除該檔案,並建立同名檔案,此時程序 b 可以鎖住該檔案。...

檔案系統 inode節點

檔案儲存在硬碟上,硬碟的最小儲存單位叫做 扇區 sector 每個扇區儲存512位元組 相當於0.5kb 扇區是磁碟上儲存的最小單位 作業系統讀取硬碟的時候,不會乙個個扇區地讀取,這樣效率太低,而是一次性連續讀取多個扇區,即一次性讀取乙個 塊 block 這種由多個扇區組成的 塊 是檔案訪問的最小單...