磁盤與記憶體的映射就是檔案映射,說這個問題之前我們先說下swap,因為
這個問題讓我很容易想起swap,linux swap 是交換分區的意思,在記憶體不
夠的情況下,作業系統先把記憶體與磁盤的swap區進行一個“映射”,然後把
這些記憶體解放出來放入記憶體中,為之後的程序的騰出一塊記憶體空間,等到自
己的程序再次被喚醒時候,再把磁盤裡面的記憶體換進來。這裡有檔案和記憶體之間
的映射奧,可是mmap與swap設計思想上是完全不同的,一個針對的實體記憶體
一個針對的是虛拟記憶體。
在說mmap之前我們先說一下普通的讀寫檔案的原理,程序調用read或是write
後會陷入核心,因為這兩個函數都是系統調用,進入系統調用後,核心開始讀寫
檔案,假設核心在讀取檔案,核心首先把檔案讀入自己的核心空間,讀完之後
程序在核心回歸使用者态,核心把讀入核心記憶體的資料再copy進入程序的使用者态内
存空間。實際上我們同一份檔案内容相當于讀了兩次,先讀入核心空間,再從核心
空間讀入使用者空間。
mmap是系統調用,mmap的作用是将程序的虛拟位址空間和檔案在磁盤的位置做一一
映射,做映射之後,讀寫檔案雖然同樣是調用read和write但是觸發的機制已經不一
樣了(mmap是file_operations中的成員這麼一說是不是了然了),實際上我們這麼
說是不太合理的因為一一映射并不是mmap一開始就全部完成映射的。
mmap隻會傳回來一個指針,指向程序邏輯位址空間的一個位置。這個時候的過程是這
樣的,首先read會改寫為讀記憶體操作,讀記憶體的時候,系統發現該位址對應的實體記憶體
是空的,觸發缺頁機制,缺頁機制先在swap尋找對應的頁面,發現沒有然後再去通過mmap
建立的映射關系,從硬碟上将檔案讀入實體記憶體。也就是說mmap把檔案直接映射到了使用者
空間,沒有經曆核心空間。
mmap可以映射檔案進入使用者的虛拟記憶體,實際上,他也可以把裝置的記憶體映射入使用者的
虛拟記憶體,因為我們一般都需要核心去讀寫裝置,如果把裝置的實體記憶體直接映射入空間
就跟上述一樣,省去一次的核心copy。
作者:柒月