Linux記憶體管理 9 mmap

2021-09-12 06:31:03 字數 3732 閱讀 5904

專題:linux記憶體管理專題

mmap/munmap是常用的乙個系統呼叫,使用場景是:分配記憶體、讀寫大檔案、連線動態庫檔案、多程序間共享記憶體

更詳細解讀參考《linux記憶體管理 (9)mmap(補充)》。

mmap/munmap函式宣告如下:

#include void *mmap(void *addr, size_t length, int prot, int flags,

int fd, off_t offset);

int munmap(void *addr, size_t length);

prot:記憶體區域的讀/寫/執行屬性。

flags:記憶體對映的屬性,共享、私有、匿名、檔案等。

fd:表示這是乙個檔案對映,fd是開啟檔案的控制代碼。

下面是prot對應的引數組合:

複製**

#define prot_read    0x1        /* page can be read */

#define prot_write 0x2 /* page can be written */

#define prot_exec 0x4 /* page can be executed */

#define prot_sem 0x8 /* page may be used for atomic ops */

#define prot_none 0x0 /* page can not be accessed */

#define prot_growsdown 0x01000000 /* mprotect flag: extend change to start of growsdown vma */

#define prot_growsup 0x02000000 /* mprotect flag: extend change to end of growsup vma */

複製**

flags引數組合有:

複製**

#define map_shared    0x01        /* share changes */---------建立乙個共享對映的區域,多個程序可以對映到乙個檔案,掐程序可以看到對映內容的改變,修改後內容會同步到磁碟中。

#define map_private 0x02 /* changes are private */--建立乙個私有的寫時複製的對映,其他程序看不到對映內容的改變,也不會同步到磁碟中。

#define map_fixed 0x10 /* interpret addr exactly */-使用指定的對映起始位址,如果有start和len引數指定的記憶體區重疊於現存的對映空間,重疊部分將會被丟棄。如果指定起始位址不可用,操作將會失敗。並且起始位址必須落在頁的邊界上。

#define map_anonymous 0x20 /* don't use a file */---匿名對映,對映區不與任何檔案關聯。此時fd應設定為-1。

#ifdef config_mmap_allow_uninitialized

# define map_uninitialized 0x4000000 /* for anonymous mmap, memory could be uninitialized */

#else

# define map_uninitialized 0x0 /* don't support this flag */

#endif

#define map_growsdown 0x0100 /* stack-like segment */--------------告訴核心vm系統,對映區可以向下擴充套件。

#define map_denywrite 0x0800 /* etxtbsy */

#define map_executable 0x1000 /* mark it as an executable */

#define map_locked 0x2000 /* pages are locked */-------------------鎖定對映區頁面,從而防止頁面被交換出記憶體。

#define map_noreserve 0x4000 /* don't check for reservations */

#define map_populate 0x8000 /* populate (prefault) pagetables */---對檔案對映來說,會提前預讀檔案內容到對映區域,只支援私有對映。

#define map_nonblock 0x10000 /* do not block on io */--------------和map_populate一起使用時才有意義。不執行預讀,只為已存在與記憶體中的頁面建立頁表入口。

#define map_stack 0x20000 /* give out an address that is best suited for process/thread stacks */

複製**

根據mmap是否對映到檔案、是共享還是私有對映,將對映型別分成四類,使用場景如下:

使用者空間的mmap,在核心中的起點是mmap_pgoff。

#include #include void main(void)

複製**

在ubuntu上執行strace ./mmap結果如下:

...

mmap(0x20000000, 10240, prot_read, map_private|map_fixed|map_anonymous, -1, 0) = 0x20000000

mmap(0x20000000, 1024, prot_read, map_private|map_fixed|map_anonymous, -1, 0) = 0x20000000

...

如果將第二個mmap的map_fixed去掉呢?結果如下:

...

mmap(0x20000000, 10240, prot_read, map_private|map_fixed|map_anonymous, -1, 0) = 0x20000000

mmap(0x20000000, 1024, prot_read, map_private|map_anonymous, -1, 0) = 0x7fcb336e1000

...

可以看出如果對映區屬性包含map_fixed,則會覆蓋原來區域;如果沒有map_fixed,核心會找到乙個區域。複製**

unsigned long mmap_region(struct file *file, unsigned long addr,

unsigned long len, vm_flags_t vm_flags, unsigned long pgoff)

...}

複製**

****:[email protected]

Linux記憶體管理 mmap

mmap munmap是常用的乙個系統呼叫,使用場景是 分配記憶體 讀寫大檔案 連線動態庫檔案 多程序間共享記憶體。mmap munmap函式宣告如下 include void mmap void addr,size t length,int prot,int flags,int fd,off t ...

Linux 記憶體管理之 mmap 解析(二)

1 mmap 系統呼叫形式 void mmap void addr size t len int prot int flags int fd off t offset mmap的作用是對映檔案描述符fd指定檔案的 off,off len 區域至呼叫程序的 addr,addr len 的記憶體區域,如...

Linux記憶體對映 mmap

linux提供了記憶體對映函式mmap,它把檔案內容對映到一段記憶體上 準確說是虛擬記憶體上 通過對這段記憶體的讀取和修改,實現對檔案的讀取和修改,先來看一下mmap的函式宣告 原型 void mmap void addr,size t length,int prot,int flags,int f...