溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

linux字符設(shè)備放在哪個(gè)目錄中

發(fā)布時(shí)間:2023-04-08 11:16:12 來(lái)源:億速云 閱讀:129 作者:iii 欄目:建站服務(wù)器

今天小編給大家分享一下linux字符設(shè)備放在哪個(gè)目錄中的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

linux字符設(shè)備放在“/dev”目錄中。字符設(shè)備是指只能一個(gè)字節(jié)一個(gè)字節(jié)進(jìn)行讀寫(xiě)操作的設(shè)備,一般每個(gè)字符設(shè)備或者塊設(shè)備都會(huì)在“/dev”目錄下對(duì)應(yīng)一個(gè)設(shè)備文件,并且每個(gè)設(shè)備文件都必須有主/次設(shè)備號(hào),主設(shè)備號(hào)相同的設(shè)備是同類(lèi)設(shè)備,使用同一個(gè)驅(qū)動(dòng)程序。

1、Linux設(shè)備驅(qū)動(dòng)分類(lèi)

Linux系統(tǒng)將設(shè)備分為三個(gè)類(lèi):字符設(shè)備、塊設(shè)備、網(wǎng)絡(luò)設(shè)備,在這三大類(lèi)中,字符設(shè)備相對(duì)比較簡(jiǎn)單,應(yīng)用程序通過(guò)字符設(shè)備文件來(lái)訪問(wèn)字符設(shè)備,本講主要介紹字符設(shè)備,如果對(duì)塊設(shè)備和網(wǎng)絡(luò)設(shè)備感興趣的話,可以參看相關(guān)資料,并對(duì)其進(jìn)行深入了解。

linux字符設(shè)備放在哪個(gè)目錄中


2、什么是字符設(shè)備?

字符設(shè)備是指只能一個(gè)字節(jié)一個(gè)字節(jié)進(jìn)行讀寫(xiě)操作的設(shè)備,不能隨機(jī)讀取設(shè)備中的某一數(shù)據(jù)、讀取數(shù)據(jù)要按照先后順序。字符設(shè)備是面向流的設(shè)備,常見(jiàn)的字符設(shè)備有鼠標(biāo)、鍵盤(pán)、串口、控制臺(tái)和LED等。

linux字符設(shè)備放在哪個(gè)目錄中

一般每個(gè)字符設(shè)備或者塊設(shè)備都會(huì)在/dev目錄下對(duì)應(yīng)一個(gè)設(shè)備文件,并且每個(gè)設(shè)備文件都必須有主/次設(shè)備號(hào),主設(shè)備號(hào)相同的設(shè)備是同類(lèi)設(shè)備,使用同一個(gè)驅(qū)動(dòng)程序。

Linux用戶層程序通過(guò)設(shè)備文件來(lái)使用驅(qū)動(dòng)程序操作字符設(shè)備或塊設(shè)備。

可以通過(guò)

cat /proc/devices

命令查看當(dāng)前已經(jīng)加載的設(shè)備驅(qū)動(dòng)程序的主設(shè)備號(hào)。

linux字符設(shè)備放在哪個(gè)目錄中

通過(guò)在/dev目錄下執(zhí)行命令

ls -l

可以看到所有設(shè)備文件的主設(shè)備號(hào)和次設(shè)備號(hào):

linux字符設(shè)備放在哪個(gè)目錄中

對(duì)常見(jiàn)設(shè)備文件作如下說(shuō)明:

/dev/hd[a-t]:IDE設(shè)備

/dev/sd[a-z]:SCSI設(shè)備

/dev/fd[0-7]:標(biāo)準(zhǔn)軟驅(qū)

/dev/md[0-31]:軟raid設(shè)備

/dev/loop[0-7]:本地回環(huán)設(shè)備

/dev/mem:內(nèi)存

/dev/null:無(wú)限數(shù)據(jù)接收設(shè)備,相當(dāng)于黑洞

/dev/zero:無(wú)限零資源

/dev/tty[0-63]:虛擬終端

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

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

/dev/console:控制臺(tái)

/dev/fb[0-31]:framebuffer

/dev/cdrom => /dev/hdc

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

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

3、如何建立設(shè)備文件?

建立設(shè)備文件有兩種方式,一是通過(guò)系統(tǒng)調(diào)用mknod(),編程中調(diào)用該函數(shù)可以建立一個(gè)新的設(shè)備文件名,另外一種就是通過(guò)mknod命令,命令的第一個(gè)參數(shù)為設(shè)備文件名,第二個(gè)參數(shù)為設(shè)備類(lèi)型,比如c表示字符設(shè)備,第三、四個(gè)參數(shù)為設(shè)備文件的主設(shè)備號(hào)和次設(shè)備號(hào),比如231和0。主設(shè)備號(hào)和次設(shè)備號(hào)合起來(lái)唯一的確定一個(gè)設(shè)備,同一個(gè)設(shè)備不同類(lèi)型的主設(shè)備號(hào)是一樣的,次設(shè)備號(hào)不同,比如一個(gè)硬盤(pán)的多個(gè)分區(qū)就有不同的次設(shè)備號(hào),通過(guò)主設(shè)備號(hào)就可以把設(shè)備文件與驅(qū)動(dòng)程序關(guān)聯(lián)起來(lái)。

mknod filename type major minor

  • filename:要?jiǎng)?chuàng)建的設(shè)備文件名;

  • type:設(shè)備類(lèi)型,c代表一個(gè)字符設(shè)備,b代表一個(gè)塊設(shè)備;

  • major:主設(shè)備號(hào);

  • minor:次設(shè)備號(hào);

4、如何描述字符設(shè)備?

Linux內(nèi)核中抽象出struct cdev結(jié)構(gòu)體來(lái)表示一個(gè)字符設(shè)備,cdev 定義于 <linux/cdev.h> 中其中,其中最關(guān)鍵的是file_operations結(jié)構(gòu),它是實(shí)現(xiàn)字符設(shè)備的操作集。

struct cdev {
        struct kobject kobj;   //  內(nèi)嵌內(nèi)核對(duì)象
        struct module *owner;  //該字符設(shè)備所在的內(nèi)核模塊
        const struct file_operations *ops; //文件操作結(jié)構(gòu)體
        struct list_head list;  //已注冊(cè)字符設(shè)備鏈表
        dev_t dev; //由主、次設(shè)備號(hào)構(gòu)成的設(shè)備號(hào)
        unsigned int count;//同一主設(shè)備號(hào)的次設(shè)備號(hào)的個(gè)數(shù)
};

Linux使用file_operations結(jié)構(gòu)訪問(wèn)驅(qū)動(dòng)程序的函數(shù),這個(gè)結(jié)構(gòu)的每一個(gè)成員的名字都對(duì)應(yīng)著一個(gè)系統(tǒng)調(diào)用。

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 *);
    };

用戶進(jìn)程利用在對(duì)設(shè)備文件進(jìn)行諸如read,write操作的時(shí)候,系統(tǒng)調(diào)用通過(guò)設(shè)備文件的主設(shè)備號(hào)找到相應(yīng)的設(shè)備驅(qū)動(dòng)程序,然后讀取這個(gè)數(shù)據(jù)結(jié)構(gòu)相應(yīng)的函數(shù)指針,接著把控制權(quán)交給該函數(shù),這是Linux的設(shè)備驅(qū)動(dòng)程序工作的基本原理。

5、字符設(shè)備與文件系統(tǒng)的接口

linux字符設(shè)備放在哪個(gè)目錄中

如圖,在Linux內(nèi)核中,最左邊, 使用cdev結(jié)構(gòu)體來(lái)描述字符設(shè)備;通過(guò)其成員dev_t來(lái)定義設(shè)備號(hào)(分為主、次設(shè)備號(hào))以確定字符設(shè)備的唯一性;通過(guò)其成員file_operations來(lái)定義字符設(shè)備驅(qū)動(dòng)提供給虛擬文件系統(tǒng)VFS的接口函數(shù),如常見(jiàn)的open()、read()、write()等,這些函數(shù)真正的操作硬件設(shè)備。

linux字符設(shè)備放在哪個(gè)目錄中

在上一個(gè)圖的基礎(chǔ)上我們看這個(gè)圖,字符設(shè)備驅(qū)動(dòng)程序是以內(nèi)核模塊的形式加載到內(nèi)核中的,首先模塊加載函數(shù)按靜態(tài)或者動(dòng)態(tài)方式獲取設(shè)備號(hào);然后字符設(shè)備初始化函數(shù)建立cdev與 file_operations之間的連接, 通過(guò)注冊(cè)函數(shù)向系統(tǒng)添加一個(gè)cdev以完成注冊(cè); 模塊卸載時(shí)與加載對(duì)應(yīng),要注銷(xiāo)cdev,并釋放設(shè)備號(hào)。

在用戶程序中,可以通過(guò)系統(tǒng)調(diào)用open(), read(), write()等調(diào)用驅(qū)動(dòng)程序在內(nèi)核中所實(shí)現(xiàn)的這些函數(shù)。這樣用戶態(tài)到內(nèi)核驅(qū)動(dòng)之間的通路就打通了。

6、編寫(xiě)簡(jiǎn)單的字符設(shè)備驅(qū)動(dòng)程序

linux字符設(shè)備放在哪個(gè)目錄中

如圖,編寫(xiě)字符設(shè)備驅(qū)動(dòng)分為三大步驟:

  1. 驅(qū)動(dòng)的初始化,其中又分為四個(gè)步驟,調(diào)用相關(guān)的函數(shù)達(dá)到。

  2. 實(shí)現(xiàn)設(shè)備的操作,具體的操作取決于你自己所要實(shí)現(xiàn)的功能,這里只列出了基本的操作

  3. 驅(qū)動(dòng)的注銷(xiāo),注銷(xiāo)就是釋放資源。

其中調(diào)用的接口函數(shù)功能如下:

linux字符設(shè)備放在哪個(gè)目錄中

第1個(gè)函數(shù)是分配函數(shù),動(dòng)態(tài)申請(qǐng)cdev的內(nèi)存,給該結(jié)構(gòu)分配內(nèi)存空間。

第2個(gè)函數(shù)是初始化函數(shù),初始化cdev的成員,并建立cdev和file_operations之間關(guān)聯(lián).

第3個(gè)函數(shù)注冊(cè)cdev設(shè)備對(duì)象,也就是把字符設(shè)備添加到字符設(shè)備表中,就像大家入學(xué)時(shí)進(jìn)行注冊(cè)一樣。

第4個(gè)函數(shù)是注銷(xiāo)驅(qū)動(dòng)程序調(diào)用,將cdev對(duì)象從系統(tǒng)中刪除。

第5個(gè)函數(shù)釋放cdev數(shù)據(jù)結(jié)構(gòu)所占的內(nèi)存。

6.1 設(shè)備號(hào)的申請(qǐng)和釋放

一個(gè)字符設(shè)備或塊設(shè)備都有一個(gè)主設(shè)備號(hào)和一個(gè)次設(shè)備號(hào)。主設(shè)備號(hào)用來(lái)標(biāo)識(shí)與設(shè)備文件相連的驅(qū)動(dòng)程序,用來(lái)反映設(shè)備類(lèi)型次設(shè)備號(hào)被驅(qū)動(dòng)程序用來(lái)辨別操作的是哪個(gè)設(shè)備,用來(lái)區(qū)分同類(lèi)型的設(shè)備。注冊(cè)時(shí)申請(qǐng)?jiān)O(shè)備號(hào),注銷(xiāo)時(shí)釋放設(shè)備號(hào),就像大家入學(xué)是有一個(gè)學(xué)號(hào),畢業(yè)離開(kāi)時(shí)就釋放掉這個(gè)學(xué)號(hào)。

linux字符設(shè)備放在哪個(gè)目錄中

6.2 用戶空間與內(nèi)核空間數(shù)據(jù)的傳送

當(dāng)我們?cè)谟脩舫绦蛑姓{(diào)用read()函數(shù)時(shí),陷入內(nèi)核空間,實(shí)際上要通過(guò)內(nèi)核的copy_to_user()函數(shù)把內(nèi)核空間緩沖區(qū)中的數(shù)據(jù)拷貝到用戶空間的緩沖區(qū),反之,當(dāng)我們調(diào)用write()函數(shù)時(shí),內(nèi)核通過(guò)調(diào)用copy_from_user()函數(shù)把用戶空間的數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū)。

linux字符設(shè)備放在哪個(gè)目錄中

以上就是“l(fā)inux字符設(shè)備放在哪個(gè)目錄中”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI