日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux字符設(shè)備架構(gòu)是如何實(shí)現(xiàn)的

電子設(shè)計(jì) ? 來源:電子設(shè)計(jì) ? 作者:電子設(shè)計(jì) ? 2020-12-24 18:12 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、Linux設(shè)備分類

Linux系統(tǒng)為了管理方便,將設(shè)備分成三種基本類型:

字符設(shè)備塊設(shè)備網(wǎng)絡(luò)設(shè)備字符設(shè)備:

字符(char)設(shè)備是個(gè)能夠像字節(jié)流(類似文件)一樣被訪問的設(shè)備,由字符設(shè)備驅(qū)動(dòng)程序來實(shí)現(xiàn)這種特性。字符設(shè)備驅(qū)動(dòng)程序通常至少要實(shí)現(xiàn)open、close、read和write的系統(tǒng)調(diào)用。

字符終端(/dev/console)和串口(/dev/ttyS0以及類似設(shè)備)就是兩個(gè)字符設(shè)備,它們能很好的說明“流”這種抽象概念。

字符設(shè)備可以通過文件節(jié)點(diǎn)來訪問,比如/dev/tty1和/dev/lp0等。這些設(shè)備文件和普通文件之間的唯一差別在于對(duì)普通文件的訪問可以前后移動(dòng)訪問位置,而大多數(shù)字符設(shè)備是一個(gè)只能順序訪問的數(shù)據(jù)通道。然而,也存在具有數(shù)據(jù)區(qū)特性的字符設(shè)備,訪問它們時(shí)可前后移動(dòng)訪問位置。例如framebuffer就是這樣的一個(gè)設(shè)備,app可以用mmap或lseek訪問抓取的整個(gè)圖像。

在/dev下執(zhí)行l(wèi)s -l ,可以看到很多創(chuàng)建好的設(shè)備節(jié)點(diǎn):

字符設(shè)備文件(類型為c),設(shè)備文件是沒有文件大小的,取而代之的是兩個(gè)號(hào)碼:主設(shè)備號(hào)5 +次設(shè)備號(hào)1 。

塊設(shè)備:

和字符設(shè)備類似,塊設(shè)備也是通過/dev目錄下的文件系統(tǒng)節(jié)點(diǎn)來訪問。塊設(shè)備(例如磁盤)上能夠容納filesystem。在大多數(shù)的Unix系統(tǒng)中,進(jìn)行I/O操作時(shí)塊設(shè)備每次只能傳輸一個(gè)或多個(gè)完整的塊,而每塊包含512字節(jié)(或2的更高次冪字節(jié)的數(shù)據(jù))。

Linux可以讓app像字符設(shè)備一樣地讀寫塊設(shè)備,允許一次傳遞任意多字節(jié)的數(shù)據(jù)。因此,塊設(shè)備和字符設(shè)備的區(qū)別僅僅在于內(nèi)核內(nèi)部管理數(shù)據(jù)的方式,也就是內(nèi)核及驅(qū)動(dòng)程序之間的軟件接口,而這些不同對(duì)用戶來講是透明的。在內(nèi)核中,和字符驅(qū)動(dòng)程序相比,塊驅(qū)動(dòng)程序具有完全不同的接口。

塊設(shè)備文件(類型為b):

網(wǎng)絡(luò)設(shè)備:

任何網(wǎng)絡(luò)事物都需要經(jīng)過一個(gè)網(wǎng)絡(luò)接口形成,網(wǎng)絡(luò)接口是一個(gè)能夠和其他主機(jī)交換數(shù)據(jù)的設(shè)備。接口通常是一個(gè)硬件設(shè)備,但也可能是個(gè)純軟件設(shè)備,比如回環(huán)(loopback)接口。

網(wǎng)絡(luò)接口由內(nèi)核中的網(wǎng)絡(luò)子系統(tǒng)驅(qū)動(dòng),負(fù)責(zé)發(fā)送和接收數(shù)據(jù)包。許多網(wǎng)絡(luò)連接(尤其是使用TCP協(xié)議的連接)是面向流的,但網(wǎng)絡(luò)設(shè)備卻圍繞數(shù)據(jù)包的傳送和接收而設(shè)計(jì)。網(wǎng)絡(luò)驅(qū)動(dòng)程序不需要知道各個(gè)連接的相關(guān)信息,它只要處理數(shù)據(jù)包即可。

由于不是面向流的設(shè)備,因此將網(wǎng)絡(luò)接口映射到filesystem中的節(jié)點(diǎn)(比如/dev/tty1)比較困難。

Unix訪問網(wǎng)絡(luò)接口的方法仍然是給它們分配一個(gè)唯一的名字(比如eth0),但這個(gè)名字在filesystem中不存在對(duì)應(yīng)的節(jié)點(diǎn)。內(nèi)核和網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序間的通信,完全不同于內(nèi)核和字符以及塊驅(qū)動(dòng)程序之間的通信,內(nèi)核調(diào)用一套和數(shù)據(jù)包相關(guān)的函數(shù)socket,也叫套接字。

查看網(wǎng)絡(luò)設(shè)備使用命令ifconfig:

二、字符設(shè)備架構(gòu)是如何實(shí)現(xiàn)的?

在Linux的世界里面一切皆文件,所有的硬件設(shè)備操作到應(yīng)用層都會(huì)被抽象成文件的操作。我們知道如果應(yīng)用層要訪問硬件設(shè)備,它必定要調(diào)用到硬件對(duì)應(yīng)的驅(qū)動(dòng)程序。Linux內(nèi)核中有那么多驅(qū)動(dòng)程序,應(yīng)用層怎么才能精確的調(diào)用到底層的驅(qū)動(dòng)程序呢?

在這里我們字符設(shè)備為例,來看一下應(yīng)用程序是如何和底層驅(qū)動(dòng)程序關(guān)聯(lián)起來的。必須知道的基礎(chǔ)知識(shí):

1.在Linux文件系統(tǒng)中,每個(gè)文件都用一個(gè)struct inode結(jié)構(gòu)體來描述,這個(gè)結(jié)構(gòu)體里面記錄了這個(gè)文件的所有信息,例如:文件類型,訪問權(quán)限等。

2.在Linux操作系統(tǒng)中,每個(gè)驅(qū)動(dòng)程序在應(yīng)用層的/dev目錄下都會(huì)有一個(gè)設(shè)備文件和它對(duì)應(yīng),并且該文件會(huì)有對(duì)應(yīng)的主設(shè)備號(hào)和次設(shè)備號(hào)。

3.在Linux操作系統(tǒng)中,每個(gè)驅(qū)動(dòng)程序都要分配一個(gè)主設(shè)備號(hào),字符設(shè)備的設(shè)備號(hào)保存在struct cdev結(jié)構(gòu)體中。

struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;//接口函數(shù)集合
struct list_h(yuǎn)ead list;//內(nèi)核鏈表
dev_t dev; //設(shè)備號(hào)
unsigned int count;//次設(shè)備號(hào)個(gè)數(shù)
};
4.在Linux操作系統(tǒng)中,每打開一次文件,Linux操作系統(tǒng)在VFS層都會(huì)分配一個(gè)struct file結(jié)構(gòu)體來描述打開的這個(gè)文件。該結(jié)構(gòu)體用于維護(hù)文件打開權(quán)限、文件指針偏移值、私有內(nèi)存地址等信息。

注意:

常常我們認(rèn)為struct inode描述的是文件的靜態(tài)信息,即這些信息很少會(huì)改變。而struct file描述的是動(dòng)態(tài)信息,即在對(duì)文件的操作的時(shí)候,struct file里面的信息經(jīng)常會(huì)發(fā)生變化。典型的是struct file結(jié)構(gòu)體里面的f_pos(記錄當(dāng)前文件的位移量),每次讀寫一個(gè)普通文件時(shí)f_ops的值都會(huì)發(fā)生改變。

這幾個(gè)結(jié)構(gòu)體關(guān)系如下圖所示:

通過上圖我們可以知道,如果想訪問底層設(shè)備,就必須打開對(duì)應(yīng)的設(shè)備文件。也就是在這個(gè)打開的過程中,Linux內(nèi)核將應(yīng)用層和對(duì)應(yīng)的驅(qū)動(dòng)程序關(guān)聯(lián)起來。

1.當(dāng)open函數(shù)打開設(shè)備文件時(shí),可以根據(jù)設(shè)備文件對(duì)應(yīng)的struct inode結(jié)構(gòu)體描述的信息,可以知道接下來要操作的設(shè)備類型(字符設(shè)備還是塊設(shè)備)。還會(huì)分配一個(gè)struct file結(jié)構(gòu)體。

2.根據(jù)struct inode結(jié)構(gòu)體里面記錄的設(shè)備號(hào),可以找到對(duì)應(yīng)的驅(qū)動(dòng)程序。這里以字符設(shè)備為例。在Linux操作系統(tǒng)中每個(gè)字符設(shè)備有一個(gè)struct cdev結(jié)構(gòu)體。此結(jié)構(gòu)體描述了字符設(shè)備所有的信息,其中最重要一項(xiàng)的就是字符設(shè)備的操作函數(shù)接口。

3.找到struct cdev結(jié)構(gòu)體后,Linux內(nèi)核就會(huì)將struct cdev結(jié)構(gòu)體所在的內(nèi)存空間首地記錄在struct inode結(jié)構(gòu)體的i_cdev成員中。將struct cdev結(jié)構(gòu)體的中記錄的函數(shù)操作接口地址記錄在struct file結(jié)構(gòu)體的f_op成員中。

4.任務(wù)完成,VFS層會(huì)給應(yīng)用層返回一個(gè)文件描述符(fd)。這個(gè)fd是和struct file結(jié)構(gòu)體對(duì)應(yīng)的。接下來上層的應(yīng)用程序就可以通過fd來找到strut file,然后在由struct file找到操作字符設(shè)備的函數(shù)接口了。

三、字符驅(qū)動(dòng)相關(guān)函數(shù)分析*

* cdev_init() - initialize a cdev structure
* @cdev: the structure to initialize
* @fops: the file_operations for this device

* Initializes @cdev, remembering @fops, making it ready to add to the
* system with cdev_add().

void cdev_init(struct cdev *cdev, const struct file_operations *fops)
功能:
初始化cdev結(jié)構(gòu)體
參數(shù):
@cdev cdev結(jié)構(gòu)體地址
@fops 操作字符設(shè)備的函數(shù)接口地址
返回值:


* register_chrdev_region() - register a range of device numbers
* @from: the first in the desired range of device numbers; must include
* the major number.
* @count: the number of consecutive device numbers required
* @name: the name of the device or driver.

* Return value is zero on success, a negative error code on failure.

int register_chrdev_region(dev_t from, unsigned count, const char *name)
功能:
注冊(cè)一個(gè)范圍()的設(shè)備號(hào)
參數(shù):
@from 設(shè)備號(hào)
@count 注冊(cè)的設(shè)備個(gè)數(shù)
@name 設(shè)備的名字
返回值:
成功返回0,失敗返回錯(cuò)誤碼(負(fù)數(shù))

* cdev_add() - add a char device to the system
* @p: the cdev structure for the device
* @dev: the first device number for which this device is responsible
* @count: the number of consecutive minor numbers corresponding to this
* device

* cdev_add() adds the device represented by @p to the system, making it
* live immediately. A negative error code is returned on failure.

int cdev_add(struct cdev *p, dev_t dev, unsigned count)
功能:
添加一個(gè)字符設(shè)備到操作系統(tǒng)
參數(shù):
@p cdev結(jié)構(gòu)體地址
@dev 設(shè)備號(hào)
@count 次設(shè)備號(hào)個(gè)數(shù)
返回值:
成功返回0,失敗返回錯(cuò)誤碼(負(fù)數(shù))

* cdev_del() - remove a cdev from the system
* @p: the cdev structure to be removed

* cdev_del() removes @p from the system, possibly freeing the structure
* itself.

void cdev_del(struct cdev *p)
功能:
從系統(tǒng)中刪除一個(gè)字符設(shè)備
參數(shù):
@p cdev結(jié)構(gòu)體地址
返回值:

static inline int register_chrdev(unsigned int major, const char *name,
const struct file_operations *fops)
功能:
注冊(cè)或者分配設(shè)備號(hào),并注冊(cè)fops到cdev結(jié)構(gòu)體,
如果major>0,功能為注冊(cè)該主設(shè)備號(hào),
如果major=0,功能為動(dòng)態(tài)分配主設(shè)備號(hào)。
參數(shù):
@m(xù)ajor : 主設(shè)備號(hào)
@name : 設(shè)備名稱,執(zhí)行 cat /proc/devices顯示的名稱
@fops : 文件系統(tǒng)的接口指針
返回值
如果major>0 成功返回0,失敗返回負(fù)的錯(cuò)誤碼
如果major=0 成功返回主設(shè)備號(hào),失敗返回負(fù)的錯(cuò)誤碼

該函數(shù)實(shí)現(xiàn)了對(duì)cdev的初始化和注冊(cè)的封裝,所以調(diào)用該函數(shù)之后就不需要自己操作cdev了。

相對(duì)的注銷函數(shù)為unregister_chrdev

static inline void unregister_chrdev(unsigned int major, const char *name)

審核編輯:符乾江


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11822

    瀏覽量

    219600
  • 應(yīng)用層
    +關(guān)注

    關(guān)注

    0

    文章

    51

    瀏覽量

    11835
  • Struct
    +關(guān)注

    關(guān)注

    0

    文章

    31

    瀏覽量

    11298
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    如何理解Linux內(nèi)核中的PCIe驅(qū)動(dòng)

    我們習(xí)慣了用 Verilog 去死磕 PCIe 的底層協(xié)議狀態(tài)機(jī)。但一旦越過硬件邊界來到操作系統(tǒng)層面,Linux 內(nèi)核是如何接管并驅(qū)動(dòng)這些 PCI/PCIe 設(shè)備的呢?由于不同的 CPU 架構(gòu)
    的頭像 發(fā)表于 04-11 17:22 ?1289次閱讀

    架構(gòu)到驅(qū)動(dòng):這三本經(jīng)典書,承包了我的嵌入式Linux入門與進(jìn)階

    私房菜(基礎(chǔ)學(xué)習(xí)篇 第四版)》《Linux 設(shè)備驅(qū)動(dòng)開發(fā)(第 2 版)》,這三本書恰好構(gòu)成了從 “底層架構(gòu)” 到 “系統(tǒng)基礎(chǔ)” 再到 “驅(qū)動(dòng)開發(fā)” 的完整學(xué)習(xí)鏈路。
    的頭像 發(fā)表于 02-09 17:02 ?1387次閱讀

    Linux設(shè)備樹到底是啥?一張圖看懂硬件適配的「翻譯官」

    你有沒有想過:同一份 Linux 內(nèi)核鏡像,為啥能在不同型號(hào)的開發(fā)板上跑起來?比如一塊 ARM 架構(gòu)的開發(fā)板,今天換個(gè)顯示屏、明天加個(gè)傳感器,內(nèi)核不用重新編譯就能識(shí)別新硬件 —— 這背后,設(shè)備樹(Devicetree) 功不可沒
    的頭像 發(fā)表于 02-09 17:01 ?1330次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>設(shè)備</b>樹到底是啥?一張圖看懂硬件適配的「翻譯官」

    深度解析ES8389/ES8390/音頻芯片Linux驅(qū)動(dòng)(Linux6.1內(nèi)核)

    基于 Linux6.1 內(nèi)核,從驅(qū)動(dòng)架構(gòu)、寄存器配置、核心函數(shù)、數(shù)據(jù)流走向四個(gè)維度,完整拆解 ES8389 的 Linux 驅(qū)動(dòng)實(shí)現(xiàn),幫你吃透這款芯片的驅(qū)動(dòng)邏輯。 ? ? 注意:在講解
    的頭像 發(fā)表于 02-02 11:37 ?2545次閱讀
    深度解析ES8389/ES8390/音頻芯片<b class='flag-5'>Linux</b>驅(qū)動(dòng)(<b class='flag-5'>Linux</b>6.1內(nèi)核)

    【「Linux 設(shè)備驅(qū)動(dòng)開發(fā)(第 2 版)」閱讀體驗(yàn)】Linux內(nèi)核開發(fā)基礎(chǔ)

    感謝電子發(fā)燒友論壇提供的《Linux設(shè)備驅(qū)動(dòng)開發(fā)(第2版)》閱讀機(jī)會(huì),測(cè)評(píng)將從Linux內(nèi)核開發(fā)基礎(chǔ)、Linux內(nèi)核平臺(tái)抽象和設(shè)備驅(qū)動(dòng)程序、
    發(fā)表于 01-12 22:45

    Linux下怎么讓中文字符串按照拼音排序?

    求教 Linux 下怎么讓中文字符串按照拼音排序?
    發(fā)表于 01-06 07:40

    如何在Linux中列出USB設(shè)備

    Linux操作系統(tǒng)提供了許多命令來列出系統(tǒng)中連接的USB設(shè)備,這些命令非常有用,無論是查看已連接設(shè)備的信息,還是進(jìn)行系統(tǒng)調(diào)試。 在本文中,我們將介紹一些常用的命令以及它們的使用方法,幫助大家了解
    發(fā)表于 12-24 08:19

    米爾RK3506核心板SDK重磅升級(jí),解鎖三核A7實(shí)時(shí)控制新架構(gòu)

    出來,獨(dú)立運(yùn)行實(shí)時(shí)操作系統(tǒng)RT-Thread。此架構(gòu)實(shí)現(xiàn)了完美的任務(wù)隔離:兩顆A7核運(yùn)行通用Linux,處理網(wǎng)絡(luò)、存儲(chǔ)等復(fù)雜業(yè)務(wù);被隔離的A7核則專司硬實(shí)時(shí)任務(wù),確保微秒級(jí)響應(yīng)。這為傳統(tǒng)PLC、遠(yuǎn)程I
    發(fā)表于 12-19 20:35

    使用TFTP實(shí)現(xiàn)IAP的方法

    使用 TFTP 實(shí)現(xiàn) IAP 的方法廣泛應(yīng)用于需要具有固件升級(jí)功能的嵌入式應(yīng)用中(例如,嵌入式 Linux bootloader 中)。TFTP 是一種在 UDP 傳輸層上執(zhí)行的簡(jiǎn)單文件傳輸協(xié)議。此
    發(fā)表于 12-10 07:21

    飛凌嵌入式ElfBoard-Linux系統(tǒng)中的文件分類

    二進(jìn)制數(shù)字,作為二進(jìn)制文件來說,里面都是二進(jìn)制數(shù)字,并非ASCII碼。2.目錄文件:目錄文件用于組織和存儲(chǔ)其他文件。在Linux系統(tǒng)中就是為例更好的管理和維護(hù)系統(tǒng)。3.字符設(shè)備文件:字符
    發(fā)表于 12-09 08:59

    Linux驅(qū)動(dòng)開發(fā)的必備知識(shí)

    內(nèi)核基礎(chǔ)知識(shí): 1、熟悉 Linux 內(nèi)核的架構(gòu)、模塊系統(tǒng)、進(jìn)程管理、內(nèi)存管理等。 了解內(nèi)核的編譯和加載過程。 2、C編程技能: 精通 C 語言編程,包括指針操作、內(nèi)存管理、結(jié)構(gòu)體等
    發(fā)表于 12-04 07:58

    【免費(fèi)送書】成為硬核Linux開發(fā)者:《Linux 設(shè)備驅(qū)動(dòng)開發(fā)(第 2 版)》

    Linux系統(tǒng)的設(shè)備驅(qū)動(dòng)開發(fā),一直給人門檻較高的印象,主要因內(nèi)核機(jī)制抽象、需深度理解硬件原理、開發(fā)調(diào)試難度大所致。2021年,一本講解驅(qū)動(dòng)開發(fā)的專著問世即獲市場(chǎng)青睞,暢銷近萬冊(cè)——這便是《Linux
    的頭像 發(fā)表于 11-18 08:06 ?1872次閱讀
    【免費(fèi)送書】成為硬核<b class='flag-5'>Linux</b>開發(fā)者:《<b class='flag-5'>Linux</b> <b class='flag-5'>設(shè)備</b>驅(qū)動(dòng)開發(fā)(第 2 版)》

    【書籍評(píng)測(cè)活動(dòng)NO.67】成為硬核Linux開發(fā)者:《Linux 設(shè)備驅(qū)動(dòng)開發(fā)(第 2 版)》

    案例與API詳解。通過本書,讀者可以實(shí)現(xiàn)從內(nèi)核到驅(qū)動(dòng)的一站式學(xué)習(xí):精通內(nèi)核配置與編譯、字符設(shè)備及I2C/SPI驅(qū)動(dòng)開發(fā),構(gòu)建完整知識(shí)體系。全書在章節(jié)結(jié)構(gòu)上也做了調(diào)整,方便讀者循序漸進(jìn)地學(xué)習(xí)內(nèi)容。學(xué)習(xí)
    發(fā)表于 11-17 17:52

    linux系統(tǒng)awk特殊字符命令詳解

    Linux系統(tǒng)中,awk?是一種非常強(qiáng)大的文本處理工具,能夠?qū)ξ谋緮?shù)據(jù)進(jìn)行分析、格式化和篩選。利用其內(nèi)置的特殊字符和操作符,用戶可以實(shí)現(xiàn)復(fù)雜的數(shù)據(jù)處理任務(wù)。以下對(duì)一些常見的awk特殊字符
    的頭像 發(fā)表于 07-28 16:38 ?758次閱讀

    凡億Allegro Skill字符功能-添加中文字符

    、產(chǎn)品型號(hào)、或者是PCB設(shè)計(jì)文件的版本號(hào)等信息。由于無法直接使用Allegro軟件內(nèi)“Add”菜單欄中的放置“Text”功能來實(shí)現(xiàn)這一需求,因此,我們不得不尋找其他的解決方案。凡億開發(fā)的FanySkill腳本提供了一個(gè)非常實(shí)用的功能,即“添加中文字符”功能。通過這
    的頭像 發(fā)表于 07-01 11:52 ?2811次閱讀
    凡億Allegro Skill<b class='flag-5'>字符</b>功能-添加中文<b class='flag-5'>字符</b>
    武夷山市| 富平县| 花莲市| 集贤县| 麻阳| 肥西县| 丰城市| 繁峙县| 仁布县| 门头沟区| 隆回县| 青海省| 颍上县| 新昌县| 拜泉县| 日喀则市| 林周县| 桓台县| 梨树县| 林西县| 瑞丽市| 祁东县| 会理县| 沙河市| 苍梧县| 嘉禾县| 嘉义县| 安塞县| 鸡东县| 扬州市| 上虞市| 阿克陶县| 鹿泉市| 赤壁市| 高密市| 阿坝| 西藏| 屏山县| 凉城县| 金堂县| 津南区|