Linux讀寫物理記憶體

2021-06-08 04:25:21 字數 3777 閱讀 1798

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 可...