首頁  >  文章  >  運維  >  linux字元裝置放在哪

linux字元裝置放在哪

青灯夜游
青灯夜游原創
2023-04-07 16:29:571742瀏覽

linux字元裝置放在「/dev」目錄中。字元設備是指只能一個位元組一個位元組進行讀寫操作的設備,一般每個字元設備或區塊設備都會在“/dev”目錄下對應一個設備文件,並且每個設備文件都必須有主/次設備號,主設備號相同的設備是同類設備,使用同一個驅動程式。

linux字元裝置放在哪

本教學操作環境:linux7.3系統、Dell G3電腦。

1、Linux裝置驅動程式分類

#Linux系統將裝置分為三個類別:字元裝置、區塊裝置、網絡設備,在這三大類中,字元設備相對比較簡單,應用程式透過字元設備檔案來存取字元設備,本講主要介紹字元設備,如果對區塊設備和網路設備感興趣的話,可以參考相關資料,並對其進行深入了解。

linux字元裝置放在哪


2、什麼是字元裝置?

字元設備是指只能一個位元組一個位元組進行讀寫操作的設備,不能隨機讀取設備中的某一資料、讀取資料要按照先後順序。字元設備是面向流的設備,常見的字元設備有滑鼠、鍵盤、串列埠、控制台和LED等。

linux字元裝置放在哪

一般每個字元裝置或區塊裝置都會在/dev目錄下對應一個裝置檔案,而且每個裝置檔案都必須有主/次設備號,主設備號相同的設備是同類設備,使用同一個驅動程式。

Linux用戶層程式透過裝置檔案來使用驅動程式操作字元裝置或區塊裝置。

可以透過

cat /proc/devices

#指令查看目前已載入的裝置驅動程式的主裝置號碼。

linux字元裝置放在哪

透過在/dev目錄下執行指令

ls -l

#可以看到所有裝置檔案的主裝置號碼和次裝置號碼:

linux字元裝置放在哪

對常見裝置檔案作如下說明:

/dev/hd[a-t]:IDE设备

/dev/sd[a-z]:SCSI设备

/dev/fd[0-7]:标准软驱

/dev/md[0-31]:软raid设备

/dev/loop[0-7]:本地回环设备

/dev/mem:内存

/dev/null:无限数据接收设备,相当于黑洞

/dev/zero:无限零资源

/dev/tty[0-63]:虚拟终端

/dev/ttyS[0-3]:串口

/dev/lp[0-3]:并口

/dev/console:控制台

/dev/fb[0-31]:framebuffer

/dev/cdrom => /dev/hdc

/dev/modem => /dev/ttyS[0-9]

/dev/pilot => /dev/ttyS[0-9]

3、如何建立裝置檔案?

建立裝置檔案有兩種方式,一是透過系統呼叫mknod(),程式設計中呼叫函數可以建立一個新的裝置檔名,另外一種是透過mknod指令,指令的第一個參數為設備檔名,第二個參數為設備類型,例如c表示字元設備,第三、四個參數為設備檔案的主設備號和次設備號,如231和0。主設備號和次設備號合起來唯一的確定一個設備,同一個設備不同類型的主設備號是一樣的,次設備號不同,例如一個硬碟的多個分區就有不同的次設備號,透過主設備號就可以把裝置檔案與驅動程式關聯起來。

mknod filename type major minor

  • filename:要建立的裝置檔名;
  • ##type:裝置類型,c代表一個字符設備,b代表一個區塊設備;
  • major:主設備號碼;
  • minor:次設備號碼;

4、如何描述字元設備?

Linux核心中抽像出struct cdev結構體來表示一個字元設備,cdev 定義於 中其中,其中最關鍵的是file_operations結構,它是實作字符設備的操作集。

struct cdev {
        struct kobject kobj;   //  内嵌内核对象
        struct module *owner;  //该字符设备所在的内核模块
        const struct file_operations *ops; //文件操作结构体
        struct list_head list;  //已注册字符设备链表
        dev_t dev; //由主、次设备号构成的设备号
        unsigned int count;//同一主设备号的次设备号的个数
};

Linux使用file_operations結構存取驅動程式的函數,這個結構的每個成員的名字都對應著一個系統呼叫。

struct file_operations {
       struct module *owner;
       loff_t (*llseek) (struct file *, loff_t, int);
       ssize_t (*read) (struct file *, char *, size_t, loff_t *);
       ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
       int (*readdir) (struct file *, void *, filldir_t);
       unsigned int (*poll) (struct file *, struct poll_table_struct *);
       int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
       int (*mmap) (struct file *, struct vm_area_struct *);
       int (*open) (struct inode *, struct file *);
       int (*flush) (struct file *);
       int (*release) (struct inode *, struct file *);
       int (*fsync) (struct file *, struct dentry *, int datasync);
       int (*fasync) (int, struct file *, int);
       int (*lock) (struct file *, int, struct file_lock *);
       ssize_t (*readv) (struct file *, const struct iovec *, unsigned long,loff_t *);
       ssize_t (*writev) (struct file *, const struct iovec *, unsigned long,    loff_t *);
    };

用戶進程利用在對設備文件進行諸如read,write操作的時候,系統調用通過設備文件的主設備號找到相應的設備驅動程序,然後讀取這個數據結構相應的函數指針,接著把控制權交給該函數,這是Linux的裝置驅動程式工作的基本原理。

5、字元裝置與檔案系統的介面

linux字元裝置放在哪#

如圖,在Linux核心中,最左邊, 使用cdev結構體來描述字元裝置;透過其成員dev_t來定義裝置號碼(分為主、次裝置號碼)以確定字元裝置的唯一性;透過其成員file_operations來定義字元裝置驅動提供給虛擬檔案系統VFS的介面函數,例如常見的open()、read()、write()等,這些函數真正的操作硬體設備。

linux字元裝置放在哪

在上一個圖的基礎上我們看這個圖,字元裝置驅動程式是以核心模組的形式載入到核心中的,首先模組載入函數按靜態或動態方式取得裝置號碼;然後字元裝置初始化函數建立cdev與file_operations之間的連線, 透過註冊函數為系統新增一個cdev以完成註冊; 模組卸載時與載入對應,要註銷cdev,並釋放裝置號。

在使用者程式中,可以透過系統呼叫open(), read(), write()等呼叫驅動程式在內核中所實現的這些函數。這樣用戶態到核心驅動之間的通路就打通了。

6、寫簡單的字元裝置驅動程式

linux字元裝置放在哪

#如圖,編寫字元裝置驅動分為三大步驟:

  1. 驅動程式的初始化,其中又分為四個步驟,呼叫相關的函數達到。
  2. 實現設備的操作,具體的操作取決於你自己要實現的功能,這裡只列出了基本的操作
  3. 驅動的註銷,註銷就是釋放資源。

其中呼叫的介面函數功能如下:

linux字元裝置放在哪

第1個函數是分配函數,動態申請cdev的內存,給該結構分配內存空間。

第2個函數是初始化函數,初始化cdev的成員,並建立cdev和file_operations之間關聯.

第3個函數註冊cdev設備對象,也就是把字元裝置加入到字符設備表中,就像大家入學時進行註冊一樣。

第4個函數是註銷驅動程式調用,將cdev物件從系統中刪除。

第5個函數釋放cdev資料結構所佔的記憶體。

6.1 裝置號碼的申請與釋放

一個字元裝置或區塊裝置都有一個主裝置號碼和一個次設備號。 主設備號碼用來識別與裝置檔案相連的驅動程序,用來反映裝置類型次設備號碼被驅動程式用來辨別操作的是哪個設備,用來區分同類型的設備。註冊時申請設備號,註銷時釋放設備號,就像大家入學是有學號,畢業離開時就釋放掉這個學號。

linux字元裝置放在哪

6.2 使用者空間與核心空間資料的傳送

##當我們在使用者程式中呼叫read()函數時,陷入核心空間,實際上要透過核心的copy_to_user()函數把核心空間緩衝區中的資料拷貝到使用者空間的緩衝區,反之,當我們呼叫write()函數時,核心透過呼叫copy_from_user()函數把使用者空間的資料拷貝到核心緩衝區。

linux字元裝置放在哪

相關推薦:《

Linux影片教學

以上是linux字元裝置放在哪的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn