Linux 字元設備驅動—— ioremap() 函數解析

来源:https://www.cnblogs.com/kazuki/archive/2018/07/20/9341414.html
-Advertisement-
Play Games

一、 ioremap() 函數基礎概念 幾乎每一種外設都是通過讀寫設備上的相關寄存器來進行的,通常包括控制寄存器、狀態寄存器和數據寄存器三大類,外設的寄存器通常被連續地編址。根據CPU體繫結構的不同,CPU對IO埠的編址方式有兩種: a -- I/O 映射方式(I/O-mapped) 典型地,如X ...


一、 ioremap() 函數基礎概念

       幾乎每一種外設都是通過讀寫設備上的相關寄存器來進行的,通常包括控制寄存器、狀態寄存器和數據寄存器三大類,外設的寄存器通常被連續地編址。根據CPU體繫結構的不同,CPU對IO埠的編址方式有兩種:

a -- I/O 映射方式(I/O-mapped)

       典型地,如X86處理器為外設專門實現了一個單獨的地址空間,稱為"I/O地址空間"或者"I/O埠空間",CPU通過專門的I/O指令(如X86的IN和OUT指令)來訪問這一空間中的地址單元。

b -- 記憶體映射方式(Memory-mapped)

RISC指令系統的CPU(如ARM、PowerPC等)通常只實現一個物理地址空間,外設I/O埠成為記憶體的一部分。此時,CPU可以象訪問一個記憶體單元那樣訪問外設I/O埠,而不需要設立專門的外設I/O指令。

但是,這兩者在硬體實現上的差異對於軟體來說是完全透明的,驅動程式開發人員可以將記憶體映射方式的I/O埠和外設記憶體統一看作是"I/O記憶體"資源。

一般來說,在系統運行時,外設的I/O記憶體資源的物理地址是已知的,由硬體的設計決定。但是CPU通常並沒有為這些已知的外設I/O記憶體資源的物理地址預定義虛擬地址範圍,驅動程式並不能直接通過物理地址訪問I/O記憶體資源,

而必須將它們映射到核心虛地址空間內(通過頁表),然後才能根據映射所得到的核心虛地址範圍,通過訪內指令訪問這些I/O記憶體資源。

Linux在io.h頭文件中聲明瞭函數ioremap(),用來將I/O記憶體資源的物理地址映射到核心虛地址空間(3GB-4GB)中(這裡是內核空間),原型如下:

1、ioremap函數

ioremap巨集定義在asm/io.h內:

#define ioremap(cookie,size)           __ioremap(cookie,size,0)

__ioremap函數原型為(arm/mm/ioremap.c):

void __iomem * __ioremap(unsigned long phys_addr, size_t size, unsigned long flags);

參數:

phys_addr:要映射的起始的IO地址

size:要映射的空間的大小

flags:要映射的IO空間和許可權有關的標誌

該函數返回映射後的內核虛擬地址(3G-4G). 接著便可以通過讀寫該返回的內核虛擬地址去訪問之這段I/O記憶體資源。

2、iounmap函數

iounmap函數用於取消ioremap()所做的映射,原型如下:

void iounmap(void * addr);

二、 ioremap() 相關函數解析

        在將I/O記憶體資源的物理地址映射成核心虛地址後,理論上講我們就可以象讀寫RAM那樣直接讀寫I/O記憶體資源了。為了保證驅動程式的跨平臺的可移植性,我們應該使用Linux中特定的函數來訪問I/O記憶體資源,而不應該通過指向核心虛地址的指針來訪問

讀寫I/O的函數如下所示:

a -- writel()

writel()往記憶體映射的 I/O 空間上寫數據,wirtel()  I/O 上寫入 32 位數據 (4位元組)。

 原型:void writel (unsigned char data , unsigned int addr )

b -- readl()

readl() 從記憶體映射的 I/O 空間上讀數據,readl 從 I/O 讀取 32 位數據 ( 4 位元組 )。
原型:unsigned char readl (unsigned int addr )

具體定義如下:

 1 #define readb __raw_readb
 2 #define readw(addr) __le16_to_cpu(__raw_readw(addr))
 3 #define readl(addr) __le32_to_cpu(__raw_readl(addr))
 4 #ifndef __raw_readb
 5 static inline u8 __raw_readb(const volatile void __iomem *addr)
 6 {
 7     return *(const volatile u8 __force *) addr;
 8 }
 9 #endif
10  
11 #ifndef __raw_readw
12 static inline u16 __raw_readw(const volatile void __iomem *addr)
13 {
14     return *(const volatile u16 __force *) addr;
15 }
16 #endif
17  
18 #ifndef __raw_readl
19 static inline u32 __raw_readl(const volatile void __iomem *addr)
20 {
21     return *(const volatile u32 __force *) addr;
22 }
23 #endif
24  
25 #define writeb __raw_writeb
26 #define writew(b,addr) __raw_writew(__cpu_to_le16(b),addr)
27 #define writel(b,addr) __raw_writel(__cpu_to_le32(b),addr)

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 非阻塞方式獲得輸入 scanf函數是以阻塞方式獲得輸入,沒有輸入時會一直等待,直到有輸入,scanf函數才執行完成。支持多方法多輸入的電子書希望以非阻塞形式獲得輸入。網上搜索stdin nonblock就能得到函數: 初始化就執行if語句: 退出非阻塞標準輸入,執行if else 語句: 初始 ...
  • grep及正則表達式 正則表達式 (REGular EXPression,REGEXP)是對字元串和特殊字元(元字元)操作的一種邏輯公式,使用事先定義好的一些特定字元、及這些特定字元的組合,組成一個“規則字元串”,這個“規則字元串”用來表達對字元串的一種過濾邏輯。通常被用來 檢索、替換 那些符合某個 ...
  • 在 "使用OpenVPN搭建VPN服務" 中介紹瞭如何使用 _OpenVPN_ 搭建最基本的VPN服務, 可以實現單個客戶端與服務端的網路互通, 但是客戶端之間, 以及服務端和客戶端所在的區域網還不能互聯. 本文介紹如何在前文的基礎上, 實現客戶端之間, 以及服務端和客戶端所在的區域網的互聯. 註意 ...
  • 1、在centos7終端以root許可權安裝jexus5.8.3的獨立版 命令:curl https://jexus.org/release/x64/install.sh|sh 2、跳轉到目錄/usr/jexus/siteconf 命令:cd /usr/jexus/siteconf 3、複製項目部署配 ...
  • python程式及其依賴包打包成rpm包部署 項目中要求將一個python腳本打包成rpm包,方便yum安裝,研究了一遍,把其中的過程記錄一下。 1.首先一個簡單測試腳本 /usr/bin/env python coding=utf 8 print 'this is test' 這個腳本運行結果一目 ...
  • 管道符"|" 管道符"|":前一個命令的輸出,作為後一個命令的輸入 I/O重定向 簡單的解釋就是捕捉一個文件, 命令, 程式, 腳本, 或者甚至是腳本中的代碼塊的輸出, 然後將這些輸出作為輸入發送到另一個文件, 命令, 程式, 或腳本中。 標準輸入輸出 執行一個shell命令行時通常會自動打開三個標 ...
  • 1、cd命令 cd:及Change Directory改變目錄的意思,用於更改到指定的目錄 用法:cd [目錄] 其中 "."代表當前目錄,".."代表當前目錄的父級目錄,"-"代表上一次使用的目錄,"~"當前用戶的主目錄 如: cd .. 進入父級目錄 cd - 進入上一次所在的目錄(改變後之前的 ...
  • ls:即列表List的意思,用來列出目錄下的文件用來列出給定目錄下的文件,參數為空預設列出當前目錄下的文件。 用法是:ls [選項] [目錄] 常用的選項有 -a, –all 列出目錄下的所有文件,包括以 . 開頭的隱含文件 -A 列出除了"."和".."以外的文件。 -l 列出文件的詳細信息,如創 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...