雖然實際驅動中不常用
,但是閱讀核心比較深層的**經常會遇到
.為什麼存在記憶體屏障呢
?先看一下下面的場景:
編譯器和處理器為了提高效率
,可能對讀和寫操作重新進行了排序,例如
: 在某些處理器上
,以下**:
a = 1;
b = 2;
有可能在
a中存放新值之前就在
b中存放新值.
但是,我們在操作記憶體或者和硬體互動時
,常常需要確保乙個給定的順序
.所有可能重新排序和寫的處理器提供了機器指令來確保順序要求
,同樣也可以提示編譯器不要對給定點周圍的指令序列進行重新排序
.這些確保順序的指令叫做"屏障
". 記憶體屏障的存在意義就是為了解決編譯器和處理器對**的順序訪問問題.
核心中用於記憶體屏障的
api有
:
rmb():
提供"讀
"記憶體屏障
,確保跨越
rmb()
的載入動作不會發生重排序
.就是說
,rmb()
之前的載入操作不會被重新排在
rmb()
之後去;
wmb():
方法提供了"寫
"記憶體屏障
,功能和
rmb()
函式類似
.區別僅僅是針對儲存而非載入
--確保跨越屏障的儲存不發生排序
;
mb():
提供了讀屏障也提供了寫屏障
.相當於上述
rmb()
函式和wmb()
函式的功能和
.
read_barrier_depends():
是
rmb()
的變種,
可以理解成
rmb()
一種優化
.該屏障確保屏障前的讀操作在屏障後的讀操作之前完成
,即那些相互依賴的讀操作.例項
:下面這個例項,其中
a的初始值是
1,b的初始值是
2.
執行緒1 執行緒2
a = 3; -
mb(); -
b = 4; c = b;
- rmb();
- d = a;
如果不使用記憶體屏障
,c可能接受了
b的新值,而
d接收了
a原來的值
.c可能等於
4(我們期望的),而
d可能等於
1(不是我們期望的
).因此
,針對一些有順序要求的暫存器操作的話
,記憶體屏障是必須考慮的
.
核心中與驅動相關的記憶體操作之十一 IO記憶體
裝置通常會提供一組暫存器用於控制裝置 讀定裝置和獲取裝置狀態 即控制暫存器 資料暫存器和狀態暫存器 這些暫存器可能位於 i o空間 也可能位於記憶體空間 當位於 i o空間時 通常被稱為 i o埠 位於記憶體空間時 對應的記憶體空間被稱為 i o記憶體 在嵌入式 linux中,我們接觸最多的就是 i...
核心中與驅動相關的記憶體操作之八 面向頁的記憶體分配
1.概述 當我們在核心驅動 中需要用到大量記憶體時,一般建議採用面向頁的記憶體管理.面向頁的記憶體管理有如下優點 高效利用記憶體,避免記憶體碎片的產生.因為核心都是基於頁為基本單位去管理記憶體的.面向頁的記憶體管理,顧名思義,就是以頁為基本單位來操作記憶體的.它比kmalloc 對記憶體使用上效率會...
Linux核心裝置驅動之核心中煉表的使用筆記整理
核心中煉表的應用 1 介紹 在linux核心中使用了大量的鍊錶結構來組織資料,包括裝置列表以及各種功能模組中的資料組織。這些鍊錶大多採用在include linux list.h實現的乙個相當精彩的鍊錶資料結構。鍊錶資料結構的定義很簡單 struct list head list head結構包含兩...