| 屬性 | 普通文件 (磁盤) | 設備文件 (/dev/...) |
| Inode 數據指針 | 指向數據塊指針數組 (直接/間接塊),記錄文件內容物理位置 | 指向 struct cdev (字符設備) 或 struct block_device (塊設備),內含 file_operations 指針 |
| 文件大小 | 有意義 (字節數) | 無意義 (通常為 0) |
| 數據存儲 | 磁盤扇區 | 無數據存儲,僅是通往驅動程序的「門」 |
連接屬性差異
- 普通文件連接:默認帶內核頁緩存 (Page Cache),讀寫經頁緩存,延遲寫回 (
pdflush/writeback),性能優化但數據落盤有延遲。
- 設備文件連接:通常不經頁緩存 (除非驅動實現
mmap 或塊設備請求隊列),數據直接在用戶緩衝區與驅動/硬件間傳輸,強調實時性、確定性。
控制連接屬性:fcntl & open 标志
fcntl 通用接口
#include
int flags = fcntl(fd, F_GETFL); // 獲取狀態標志
flags |= O_SYNC; // 設置同步寫 (數據直達硬件)
fcntl(fd, F_SETFL, flags); // 應用
常用標志:O_NONBLOCK (非阻塞)、O_APPEND (追加)、O_SYNC (同步 I/O)、O_DIRECT (繞過頁緩存)。
open 時預置屬性
int fd = open("/dev/mydev", O_RDWR | O_NONBLOCK | O_SYNC);
推薦在 open 時指定,避免競態窗口。
設備文件創建與權限
// 手動創建 (udev 自動管理現代系統)
mknod /dev/mydev c 250 0 // 主設備號 250, 次設備號 0
chmod 660 /dev/mydev
chown root:dialout /dev/mydev
現代系統由 udev 根據驅動註冊的 class/device 自動創建、設置權限、符號鏈接。
總結:設備文件是「接口」而非「容器」
- 普通文件 = 數據容器 (大小、內容、時間戳)。
- 設備文件 = 內核驅動入口點 (主/次設備號 → 驅動
file_operations → 硬件操作)。
- 讀寫設備文件實質是調用驅動回調函數,驅動負責解析命令、操作硬件寄存器、管理 DMA、處理中斷。