mamp把文件內容映射到一段內存上(準確說是虛擬內存空間上), 經過對這段內存的讀取和修改, 實現對文件的讀取和修改,不須要read和write了。函數
頭文件:spa
<unistd.h>指針
<sys/mman.h>orm
原型: void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offsize);進程
返回值: 成功則返回映射區起始地址, 失敗則返回MAP_FAILED(-1).內存
參數:rem
addr: 指定映射的起始地址, 一般設爲NULL, 由系統指定原型
length: 將文件的多大長度映射到內存it
prot: 映射區的保護方式, 能夠是:map
PROT_EXEC: 映射區可被執行.
PROT_READ: 映射區可被讀取.
PROT_WRITE: 映射區可被寫入.
PROT_NONE: 映射區不能存取.
flags: 映射區的特性, 能夠是:
MAP_SHARED: 對映射區域的寫入數據會複製迴文件, 且容許其餘映射該文件的進程共享.
MAP_PRIVATE: 對映射區域的寫入操做會產生一個映射的複製(copy-on-write), 對此區域所作的修改不會寫回原文件.
fd: 由open返回的文件描述符, 表明要映射的文件.
offset: 以文件開始處的偏移量, 必須是分頁大小的整數倍, 一般爲0, 表示從文件頭開始映射.
int munmap(void *start, size_t lenght)關閉內存映射
start 起始地址上面函數返回的地址 lenght 長度 ;成功返回 0
映射步驟
用open系統調用打開文件, 並返回描述符fd.
用mmap創建內存映射, 並返回映射首地址指針start.
對映射(文件)進行各類操做, 顯示(printf), 修改(sprintf).
用munmap(void *start, size_t lenght)關閉內存映射.
用close系統調用關閉文件fd.
注意:memp不能更改文件中字符的長度,當寫入數據長度大於原來長度時,只保存原來長度的寫入值,若是數據小於原來長度,則只替換寫入的數據,原來數據大於寫入數據長度的保留不變。
如源文件值12345 若是寫入 abcdefg 則只能寫入abcde 若是寫入 abc 則值變爲 abc45
想查看的話 地址如何分配指令
vi /proc/2074/maps (到/proc目錄下 查看模塊號 查看2074進程的地址分配狀況)
使用mmap完成頁表的創建
remap_pfn_range 一次創建全部頁表
int remap_pfn_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long pfn, unsigned long size, pgprot_t prot);
wma:虛擬內存區域指針 系統分配
virt_addr:虛擬地址的起始值
pfn:要映射的物理地址所在的物理頁幀號,可將物理地址>>PAGE_SHIFT獲得
size:要映射的區域的大小
prot:vma保護屬性
例子
VM_IO將VMA標記爲一個內存映射的I/O區域
VM_RESERVED標記內存區域不能被換出