導航:首頁 > 操作系統 > linuxdevmem

linuxdevmem

發布時間:2023-09-01 05:28:32

Ⅰ 寫內存算是訪問內存嗎

當用戶訪問用戶空間的這段地址范圍時,實際是訪問設備內存。
linux上電時,並不會為外設地址空間建立頁表。
但我們知道,linux訪問內存使用的都是虛擬地址,因此如果想訪問外設的寄存器(一般包括數據寄存器、控制寄存器與狀態寄存器),需要在驅動初始化中將外設所處的物理地址映射為虛擬地址,使用ioremap介面可以實現該功能。

ioremap & ioremap_nocache
ioremap和ioremap_nocache實現相同,使用場景為映射device memory類型內存。同時不使用cache(device memory本身就沒有cacheable這個屬性),即CPU的讀寫操作直接操作設備內存。

ioremap_cached
ioremap_cached用來映射memory type為normal memory的設備,同時使用cache,這會提高內存的訪問速度,提高系統的性能。

ioremap_wc & ioremap_wt
ioremap_wc用來映射memory type為normal memory的設備,同時不使用cache。

I/O內存訪問流程
request_mem_region
ioremap
rw
iounmap
release_mem_region
二、設備地址映射到用戶空間
一般情況下,用戶空間是不能夠直接訪高肢問設備的。mmap可實現這個功能。

mmap通過將設備內存映射到用戶空間的一段內存上,這樣,當用戶訪問用戶空間的這段地址范圍時,實際是訪問設備內存。這樣在每次訪問時,節省了用戶空間和內核空間的復制過程。

無論是普通文件還是設備文件,讀寫都是基於系統的虛擬文件系統介面,普通文件為了保護磁碟,避免頻繁讀寫,還引入帶緩沖頁機制,通過read/write/ioctl訪問文件時,都需經歷「用戶到內核」的內存拷貝過程,然後才將文件內容寫入磁碟。

通過mmap方法,將文件(包括設備文件)映射到用戶進程虛擬內存空間,代替read/write/ioctl的訪問方式,此時內存拷貝過程只有「用戶空間到虛擬內存空間」,省去了「用戶到內核」的拷貝過程,在數據量大的情況下能顯著提升讀寫效率。因此,mmap也稱為「零拷貝」(zero )技術。

caddr_t *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

fd為文件描述符,一般由open返回。fd也可指定為-1,並指定flags參數中的MAP_ANON,表示匿名映射。
length指映射的位元組數,從offset開始計算;
prot指定訪問許可權;
start指定文件被映射到用戶空間的起始地址,一般設為NULL,由內核指定改地址;
函數返回值為映射到用戶空間的地址。
1
2
3
4
5
1
2
3
4
5
mmap過程
1、在虛擬內存中查找一塊VMA
2、將這塊VMA進行映射
3、如果設備驅動程序或文件系統的file_operation定義了mmap介面,則調用它;
4、將VMA插入進程的VMA鏈表中
1
2
3
4
1
2
3
4
進程在映射空間的對共享內容的修改不會實時同步寫回到磁碟文件中,只有調用munmap()函數釋放映射後才會執行同步操作。mmap機制提供msync()函數,用於手動同步修改內容到磁碟源文件。

linux內核使用vm_area_struct結構來表示一個獨立的虛擬內存區域,由於每個不同質的虛擬內存區域功能和內部機制都不同,因此一個進程使用多個vm_area_struct結構來分別表示不同滾老類型的虛擬內存區域。各個vm_area_struct結構使用鏈表或者樹形結構鏈接,方便進程快速訪問,如下圖所示:
在這里插入圖片描述
vm_area_struct結構中包含區域起始和終止地址以及其他相關信息,同時也包含一個vm_ops指針,其內部可引出所有針對這個區域可以使用的系統調用函數。這樣,進程對某一虛擬內存區域的任何操作需要用要的信息,都可以從vm_area_struct中獲得。mmap函數就是要創建一個新的vm_area_struct結構,並將其與文件的物理磁碟地址相連。

三、devmem原理
「/dev/mem」設備
「/大念升dev/mem」是linux系統的一個虛擬字元設備,無論是標准linux系統還是嵌入式linux系統,都支持該設備。
「/dev/mem」設備是內核所有物理地址空間的全映像,這些地址包括:

物理內存(RAM)空間
物理存儲(ROM)空間
cpu匯流排地址
cpu寄存器地址
外設寄存器地址,GPIO、定時器、ADC
1
2
3
4
5
1
2
3
4
5
「/dev/mem」設備通常與「mmap」結合使用,可將指定內存映射到用戶空間。
類似的還有/dev/kmem設備,kernel看到的虛擬內存的全鏡像。可以用來訪問kernel的內容。

devmem命令原理
應用程序通過mmap函數實現對/dev/mem驅動中mmap方法的使用,映射了設備的內存到用戶空間,實現對這些物理地址的讀寫操作。
類似的有devkmem命令,通過mmap函數實現對/dev/kmem驅動中mmap方法的使用,映射了設備的內核空間到用戶空間,實現對這些物理地址的讀寫操作。

四、malloc原理
malloc的工作原理
可執行文件載入到內存中的時候,就給棧和堆劃分了固定大小的空間。使用vm_area_struct結構體指明了一個連續區域的頭地址和尾地址。

malloc函數分配內存主要是使用brk和mmap系統調用

brk(): 小於128k
在堆段分配malloc的內存,將堆頂的指針brk往上推;
mmap(): 大於128k
是在堆和棧之間(文件映射區域)找分配一塊空閑的虛擬內存,
1
2
3
4
1
2
3
4
malloc系統調用後,並沒有實際分配物理內存。
這時候讀虛擬內存地址,返回值是0;
第一次寫的時候,發生缺頁中斷,才會實際分配物理內存,建立虛擬內存與物理內存的映射關系。

缺頁中斷
malloc的空間沒有實際分配的情況下,在寫的時候會報缺頁中斷。實際上:
進程線性地址空間里的頁面不必常駐內存,在執行一條指令時,如果發現他要訪問的頁沒有在內存中(即存在位為0),那麼停止該指令的執行,並產生一個頁不存在的異常,對應的故障處理程序可通過從外存載入該頁的方法來排除故障,之後,原先引起的異常的指令就可以繼續執行,而不再產生異常。

當一個進程發生缺頁中斷的時候,進程會陷入內核態,執行以下操作:

1、檢查要訪問的虛擬地址是否合法
2、查找/分配一個物理頁
3、填充物理頁內容(讀取磁碟,或者直接置0,或者啥也不幹)
4、建立映射關系(虛擬地址到物理地址)
1
2
3
4
1
2
3
4
重新執行發生缺頁中斷的那條指令
如果第3步,需要讀取磁碟,那麼這次缺頁中斷就是majflt,否則就是minflt。

如何查看進程發生缺頁中斷的次數:
ps -o majflt,minflt -C program

majflt代表major fault,中文名叫大錯誤,minflt代表minor fault,中文名叫小錯誤。
這兩個數值表示一個進程自啟動以來所發生的缺頁中斷的次數。

malloc的free
前面知道,通過移動brk申請的內存,存放在進程的堆區域中。
free是由運行庫實現,它只是在已分配的堆塊前面加一個可用標志,並不實際釋放內存,不論是物理內存還是進程的堆空間。
在下次的malloc時,這塊空間可能被重用。
如果進程的堆空間出現較多的碎片(這是邏輯地址中的碎片),運行庫的堆管理常式會移動/合並碎片,此時可能會出現物理內存的釋放/重新分配。
而對於brk指針,只有它指向的那片內存被free的時候才會下移。比如先malloc了一個A,然後malloc了一個B。free掉A之後,brk是不會下移的;free掉B的時候brk才會下移。

閱讀全文

與linuxdevmem相關的資料

熱點內容
雲看地是什麼APP 瀏覽:883
數學指南pdf 瀏覽:856
phpcurldll64位 瀏覽:976
程序員脫產一年半 瀏覽:849
hr招程序員有什麼條件 瀏覽:587
android開源集合 瀏覽:867
華為雲伺服器登錄密碼和賬號 瀏覽:154
中世紀java程序員 瀏覽:786
什麼開發引擎使用python 瀏覽:176
sh腳本運行命令 瀏覽:316
廣聯達加密鎖怎麼看到期 瀏覽:172
cad軌跡命令 瀏覽:979
同事刷到女程序員自媒體視頻 瀏覽:571
校驗演算法的缺點是什麼 瀏覽:717
PHP商品分類功能實現 瀏覽:330
php取字元串中間 瀏覽:432
程序員經常用工具 瀏覽:837
降服主力指標源碼主圖 瀏覽:502
python實用庫 瀏覽:694
電腦默認7個文件夾 瀏覽:13