在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux字符設備架構是如何實現的

電子設計 ? 來源:電子設計 ? 作者:電子設計 ? 2020-12-24 18:12 ? 次閱讀

一、Linux設備分類

Linux系統為了管理方便,將設備分成三種基本類型:

字符設備塊設備網絡設備字符設備:

字符(char)設備是個能夠像字節流(類似文件)一樣被訪問的設備,由字符設備驅動程序來實現這種特性。字符設備驅動程序通常至少要實現open、close、read和write的系統調用。

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

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

在/dev下執行ls -l ,可以看到很多創建好的設備節點:

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

塊設備:

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

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

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

網絡設備:

任何網絡事物都需要經過一個網絡接口形成,網絡接口是一個能夠和其他主機交換數據的設備。接口通常是一個硬件設備,但也可能是個純軟件設備,比如回環(loopback)接口。

網絡接口由內核中的網絡子系統驅動,負責發送和接收數據包。許多網絡連接(尤其是使用TCP協議的連接)是面向流的,但網絡設備卻圍繞數據包的傳送和接收而設計。網絡驅動程序不需要知道各個連接的相關信息,它只要處理數據包即可。

由于不是面向流的設備,因此將網絡接口映射到filesystem中的節點(比如/dev/tty1)比較困難。

Unix訪問網絡接口的方法仍然是給它們分配一個唯一的名字(比如eth0),但這個名字在filesystem中不存在對應的節點。內核和網絡設備驅動程序間的通信,完全不同于內核和字符以及塊驅動程序之間的通信,內核調用一套和數據包相關的函數socket,也叫套接字。

查看網絡設備使用命令ifconfig:

二、字符設備架構是如何實現的?

在Linux的世界里面一切皆文件,所有的硬件設備操作到應用層都會被抽象成文件的操作。我們知道如果應用層要訪問硬件設備,它必定要調用到硬件對應的驅動程序。Linux內核中有那么多驅動程序,應用層怎么才能精確的調用到底層的驅動程序呢?

在這里我們字符設備為例,來看一下應用程序是如何和底層驅動程序關聯起來的。必須知道的基礎知識:

1.在Linux文件系統中,每個文件都用一個struct inode結構體來描述,這個結構體里面記錄了這個文件的所有信息,例如:文件類型,訪問權限等。

2.在Linux操作系統中,每個驅動程序在應用層的/dev目錄下都會有一個設備文件和它對應,并且該文件會有對應的主設備號和次設備號。

3.在Linux操作系統中,每個驅動程序都要分配一個主設備號,字符設備的設備號保存在struct cdev結構體中。

struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;//接口函數集合
struct list_head list;//內核鏈表
dev_t dev; //設備號
unsigned int count;//次設備號個數
};
4.在Linux操作系統中,每打開一次文件,Linux操作系統在VFS層都會分配一個struct file結構體來描述打開的這個文件。該結構體用于維護文件打開權限、文件指針偏移值、私有內存地址等信息。

注意:

常常我們認為struct inode描述的是文件的靜態信息,即這些信息很少會改變。而struct file描述的是動態信息,即在對文件的操作的時候,struct file里面的信息經常會發生變化。典型的是struct file結構體里面的f_pos(記錄當前文件的位移量),每次讀寫一個普通文件時f_ops的值都會發生改變。

這幾個結構體關系如下圖所示:

通過上圖我們可以知道,如果想訪問底層設備,就必須打開對應的設備文件。也就是在這個打開的過程中,Linux內核將應用層和對應的驅動程序關聯起來。

1.當open函數打開設備文件時,可以根據設備文件對應的struct inode結構體描述的信息,可以知道接下來要操作的設備類型(字符設備還是塊設備)。還會分配一個struct file結構體。

2.根據struct inode結構體里面記錄的設備號,可以找到對應的驅動程序。這里以字符設備為例。在Linux操作系統中每個字符設備有一個struct cdev結構體。此結構體描述了字符設備所有的信息,其中最重要一項的就是字符設備的操作函數接口。

3.找到struct cdev結構體后,Linux內核就會將struct cdev結構體所在的內存空間首地記錄在struct inode結構體的i_cdev成員中。將struct cdev結構體的中記錄的函數操作接口地址記錄在struct file結構體的f_op成員中。

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

三、字符驅動相關函數分析*

* 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結構體
參數:
@cdev cdev結構體地址
@fops 操作字符設備的函數接口地址
返回值:


* 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)
功能:
注冊一個范圍()的設備號
參數:
@from 設備號
@count 注冊的設備個數
@name 設備的名字
返回值:
成功返回0,失敗返回錯誤碼(負數)

* 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)
功能:
添加一個字符設備到操作系統
參數:
@p cdev結構體地址
@dev 設備號
@count 次設備號個數
返回值:
成功返回0,失敗返回錯誤碼(負數)

* 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)
功能:
從系統中刪除一個字符設備
參數:
@p cdev結構體地址
返回值:

static inline int register_chrdev(unsigned int major, const char *name,
const struct file_operations *fops)
功能:
注冊或者分配設備號,并注冊fops到cdev結構體,
如果major>0,功能為注冊該主設備號,
如果major=0,功能為動態分配主設備號。
參數:
@major : 主設備號
@name : 設備名稱,執行 cat /proc/devices顯示的名稱
@fops : 文件系統的接口指針
返回值
如果major>0 成功返回0,失敗返回負的錯誤碼
如果major=0 成功返回主設備號,失敗返回負的錯誤碼

該函數實現了對cdev的初始化和注冊的封裝,所以調用該函數之后就不需要自己操作cdev了。

相對的注銷函數為unregister_chrdev

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

審核編輯:符乾江


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11479

    瀏覽量

    213073
  • 應用層
    +關注

    關注

    0

    文章

    46

    瀏覽量

    11677
  • Struct
    +關注

    關注

    0

    文章

    31

    瀏覽量

    11053
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    飛凌嵌入式ElfBoard ELF 1板卡-字符驅動之字符驅動描述

    字符驅動是一種在Linux內核中實現設備驅動程序,用于管理和操作字符設備
    發表于 03-14 09:51

    飛凌嵌入式ElfBoard ELF 1板卡-字符驅動之字符驅動描述

    字符驅動是一種在Linux內核中實現設備驅動程序,用于管理和操作字符設備
    發表于 03-13 09:49

    嵌入式學習-飛凌嵌入式ElfBoard ELF 1板卡-Linux設備驅動的分類

    設備和塊設備都映射到了虛擬文件系統目錄下。應用程序可以通過系統調用接口open、close、write、read等相關API進行訪問字符設備和塊設備
    發表于 03-12 10:20

    飛凌嵌入式ElfBoard ELF 1板卡-Linux設備驅動的分類

    設備和塊設備都映射到了虛擬文件系統目錄下。應用程序可以通過系統調用接口open、close、write、read等相關API進行訪問字符設備和塊設備
    發表于 03-10 17:00

    基于OpenSBI的linux nommu實現

    Linux內核6.10提供了對沒有mmu的riscv處理器工作在S模式下的內核的支持,本文介紹基于OpenSBI的linuxnommu的實現,供大家參考。1、OpenSBI介紹SBI
    的頭像 發表于 02-08 13:43 ?578次閱讀
    基于OpenSBI的<b class='flag-5'>linux</b> nommu<b class='flag-5'>實現</b>

    字符串與字符數組的區別

    在編程語言中,字符串和字符數組是兩種基本的數據結構,它們都用于存儲和處理文本數據。盡管它們在功能上有一定的重疊,但在內部表示、操作方式和使用場景上存在顯著差異。 1. 內部表示 字符字符
    的頭像 發表于 01-07 15:29 ?1052次閱讀

    字符串反轉的實現方式

    在編程中,字符串反轉是一個基礎而重要的操作,它涉及到將一個字符串中的字符順序顛倒過來。這個操作在多種編程語言中都有不同的實現方式,本文將探討幾種常見的
    的頭像 發表于 01-07 15:27 ?762次閱讀

    字符串處理方法 字符串轉數字的實現

    在編程中,將字符串轉換為數字是一個常見的需求。不同的編程語言有不同的方法來實現這一功能。以下是一些常見編程語言中的字符串轉數字的實現方法: Python 在Python中,可以使用內置
    的頭像 發表于 01-07 15:26 ?809次閱讀

    基于risc-v架構的芯片與linux系統兼容性討論

    一定的兼容性挑戰,但并非不可克服。通過針對RISC-V架構進行編譯和優化Linux內核、確保硬件接口兼容、支持平臺特性、提供適用的編譯工具鏈和二進制格式以及構建完整的生態系統等措施,可以實現
    發表于 11-30 17:20

    Linux網絡協議棧的實現

    請求并與底層的網絡硬件進行交互。本文將深入探討 Linux 網絡協議棧的架構實現,涵蓋數據包處理流程、關鍵模塊、協議棧層次以及性能優化等方面。
    的頭像 發表于 09-10 09:51 ?631次閱讀
    <b class='flag-5'>Linux</b>網絡協議棧的<b class='flag-5'>實現</b>

    labview中如何實現字符串換行

    1. 字符串換行的基本概念 在LabVIEW中,字符串換行通常指的是在字符串中插入換行符,使得字符串在顯示或輸出時能夠自動換行。這在創建用戶界面或處理文本數據時非常有用。 2.
    的頭像 發表于 09-04 15:47 ?3647次閱讀

    labview中如何實現字符串選擇輸出

    在LabVIEW中實現字符串選擇輸出是一項常見的任務,它涉及到字符串處理、條件判斷和用戶界面設計等多個方面。由于LabVIEW是一種圖形化編程語言,其編程方式與傳統的文本編程語言有所不同,因此
    的頭像 發表于 09-04 15:44 ?2094次閱讀

    linux系統的設備驅動一般分幾類

    Linux系統的設備驅動是操作系統與硬件設備之間的橋梁,負責實現操作系統與硬件設備之間的通信和控制。Li
    的頭像 發表于 08-30 15:13 ?935次閱讀

    Linux設備驅動程序分類有哪些

    Linux設備驅動程序是操作系統與硬件設備之間的橋梁,負責實現硬件設備與操作系統之間的通信和控制。Lin
    的頭像 發表于 08-30 15:11 ?1160次閱讀

    linux驅動程序如何加載進內核

    Linux系統中,驅動程序是內核與硬件設備之間的橋梁。它們允許內核與硬件設備進行通信,從而實現對硬件設備的控制和管理。 驅動程序的編寫 驅
    的頭像 發表于 08-30 15:02 ?1030次閱讀
    主站蜘蛛池模板: 人与禽一级一级毛片 | 国产黄色网| 免费人成网站在线高清 | 特级全黄大片 | 黄色网址你懂得 | 老师喂我吃她的奶水脱她胸罩 | 免费观看片 | 人人狠狠综合88综合久久 | www.毛片.com| 激情福利网 | 唐人社电亚洲一区二区三区 | 日本不卡在线视频高清免费 | 亚洲成a人片在线观看www | 正在播放亚洲一区 | 久久婷婷激情综合色综合也去 | 亚洲最新黄色网址 | 狼色网| 4438x色| 免费在线一区二区三区 | 我被黑人巨大开嫩苞在线观看 | 国产h在线| 5252欧美在线观看 | 最新版资源在线天堂 | 国产免费好大好硬视频 | 色欧美色 | 亚洲成人激情电影 | 欧美日韩一区二区三区视视频 | 男操女视频在线观看 | 久久久精品波多野结衣 | 九色视频在线播放 | 日本大片网 | 色月| 日韩毛片大全免费高清 | 久久99精品久久久久久久野外 | 91大神在线精品网址 | 国产一区二区高清 | 国产成人在线播放视频 | 全是肉的高h短篇列车 | 中文字幕日本一区波多野不卡 | 欧美人交性视频在线香蕉 | 四虎国产永久免费久久 |