1.開啟裝置檔案:mem是乙個字元裝置檔案,是計算機主存的乙個映像。通常只有root使用者對其有讀寫許可權。因此只有root使用者能進行這些操作。如果要開啟裝置檔案/dev/mem,需要系統呼叫open()函式,作用是開啟乙個檔案或裝置,其函式原型為:
int open(const char *path, int flags);
返回值:如果操作成功則返回乙個檔案描述符,否則返回-1
形 參:
path 被開啟檔案的路徑即檔名描述。
flags 檔案的訪問模式描述,可常用的選項見下:
o_rdonly 唯讀方式
o_wronly 只寫方式
o_rdwr 可讀寫方式
說 明:此函式用於開啟檔案或者裝置
標頭檔案:#include #include 定義在/usr/include/fcntl.h中2.讀取記憶體映像:記憶體映像其實在記憶體中建立乙個與外存中檔案完全相同的映像。使用者可以將整個檔案對映到記憶體中,也可以將檔案的一部分對映到記憶體中。
使用操作記憶體的方法對檔案進行操作。系統會將記憶體映像檔案所做的改動反映到真實檔案中去。
在記憶體映像i/o的實現過程中需要用到一些系統呼叫:
首先是建立記憶體映像檔案的系統呼叫mmap()函式,其函式原型為:
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
形 參:
start 乙個void指標,表示希望將檔案對映到此指標指向的位置,通常為null。
length 定義記憶體映像檔案所占用的記憶體空間大小,以位元組計。
prot 記憶體映像檔案的安全屬性,注意和open函式中的flags屬性保持一致。它的可使用的選項如下:
flags 含義
prot_exec 被映像記憶體可能含義機器碼,可被執行
prot_none 映像記憶體不允許訪問
prot_read 映像記憶體可讀
prot_write 映像記憶體可寫
flags 記憶體映像的標誌,選項如下:
flags 含義
map_fixed 指定對映起始位址,如果由start和len指定的記憶體區重疊於現存的對映空間,重疊部分將會被丟棄。
如果指定的起始位址不可用,操作將會失敗。並且起始位址必須落在頁的邊界上。
map_shared 與其它所有對映這個物件的程序共享對映空間。對共享區的寫入,相當於輸出到檔案。
直到msync()或者munmap()被呼叫,檔案實際上不會被更新。
map_private 建立乙個寫入時拷貝的私有對映。記憶體區域的寫入不會影響到原檔案。
這個標誌和以上標誌是互斥的,只能使用其中乙個。
map_noreserve 不要為這個對映保留交換空間。當交換空間被保留,對對映區修改的可能會得到保證。
當交換空間不被保留,同時記憶體不足,對對映區的修改會引起段違例訊號。
map_locked 鎖定對映區的頁面,從而防止頁面被交換出記憶體。
map_growsdown 用於堆疊,告訴核心vm系統,對映區可以向下擴充套件。
map_anonymous 匿名對映,對映區不與任何檔案關聯。
map_anon map_anonymous的別稱,不再被使用。
map_file 相容標誌,被忽略。
map_32bit 將對映區放在程序位址空間的低2gb,map_fixed指定時會被忽略。
當前這個標誌只在x86-64平台上得到支援。
map_populate 為檔案對映通過預讀的方式準備好頁表。隨後對對映區的訪問不會被頁違例阻塞。
map_nonblock 僅和map_populate一起使用時才有意義。不執行預讀,只為已存在於記憶體中的頁面建立頁表入口。
fd 要對映的檔案的描述符。
offset 所對映的資料內容 距離檔案頭的偏移量。
說 明:此函式用於將乙個檔案或它的一部分對映到記憶體中。
標頭檔案:#include #include 函式定義在/usr/include/sys/mman.h3.撤銷記憶體映像的修改另外我們使用完記憶體映像檔案後,要用系統呼叫函式munmap()函式來撤銷,其函式原型為:
int munmap(void *start, size_t length);
返回值:成功時,返回值為0;呼叫失敗時返回值為 -1,並將errno設定為相應值。
形 參:
start 要撤銷的記憶體映像檔案的起始位址。
length 要撤銷的記憶體映像檔案的大小。
標頭檔案:#include4.將記憶體映像的改動儲存到外存中最後,如果我們要將記憶體映像的改動儲存到外存中,還需要系統呼叫msync()函式,其函式原型為:
int msync(const void *start,size_t length,int flags);
返回值:成功時,返回值為0;呼叫失敗時返回值為 -1,並將errno設定為相應值。
形 參:
start 要儲存到外存的那些原始檔的起始位址。
length 表示記憶體映像檔案的大小。
flags 設定了函式的相應操作,其具體選項如下:
flags 含義
ms_async 呼叫乙個寫操作並返回
ms_invalidate 映像到相同檔案的記憶體映像資料更新
ms_sync 完成寫操作後函式返回
說 明:程序在對映空間的對共享內容的改變並不直接寫回到磁碟檔案中,往往在呼叫munmap()後才執行該操作。
可以通過呼叫msync()函式來實現磁碟檔案內容與共享記憶體區中的內容一致,即同步操作。
標頭檔案:#include5.通過/dev/mem裝置檔案和mmap系統呼叫,可以將線性位址描述的物理記憶體對映到程序的位址空間,然後就可以直接訪問這段記憶體了。
#include #include #include #include #include #include int main (int args, char* arg)
//map physical memory 0-10 bytes
mem = mmap (0, 10, prot_read | prot_write, map_shared, fd, 0);
if (mem == map_failed)
//read old value
for (i = 0; i < 5; i++)
printf(the value is 0x%x\n, *((int *)mem));
//write memory
memcpy(mem, buff, 5);
//read new value
for (i = 0; i<5 ; i++)
printf("\n");
munmap (mem, 10); //destroy map memory
close (fd); //close file
return 0;
}
linux清理物理記憶體
當在linux下頻繁訪問檔案後,物理記憶體會很快被用光,當程式結束後,記憶體不會被正常釋放,而是一直作為caching 因此我們很有必要手動清理系統快取釋放記憶體。我們在清理快取前應該先 sync下 因為系統在操作的過程當中,會把你的操作到的檔案資料先儲存到buffer中去,因為怕你在操作的過程中因...
linux 物理記憶體和虛擬記憶體
vmstat是virtual memory statistics虛擬記憶體統計縮寫 物理記憶體是計算機記憶體的大小,從物理記憶體中讀寫資料比硬碟中讀寫資料要快很多,而記憶體是有限的,所以就有了物理記憶體和虛擬記憶體的概念。物理記憶體就是硬體的記憶體,是真正的記憶體。虛擬記憶體是為了滿足物理記憶體不足...
Linux 記憶體管理 線性空間與物理記憶體
linux 記憶體管理 線性空間與物理記憶體 收藏 上圖反映了如下資訊 1 程序的4g 線性空間被劃分成三個部分 程序空間 0 3g 核心直接對映空間 3g high memory 核心動態對映空間 vmalloc start vmalloc end 2 三個空間使用同一張頁目錄表,通過 cr3 可...