歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux下的內存映射函數mmap詳解及示例代碼

Linux下的內存映射函數mmap詳解及示例代碼

日期:2017/2/28 16:28:27   编辑:Linux教程

Linux的mmap文件內存映射機制
mmap: memory map

在講述文件映射的概念時, 不可避免的要牽涉到虛存(SVR 4的VM). 實際上, 文件映射是虛存的中心概念, 文件映射一方面給用戶提供了一組措施, 好似用戶將文件映射到自己地址空間的某個部分, 使用簡單的內存訪問指令讀寫文件;另一方面, 它也可以用於內核的基本組織模式, 在這種模式種, 內核將整個地址空間視為諸如文件之類的一組不同對象的映射. 中的傳統文件訪問方式是, 首先用open系統調用打開文件, 然後使用read, write以及lseek等調用進行順序或者隨即的I/O. 這種方式是非常低效的, 每一次I/O操作都需要一次系統調用. 另外, 如果若干個進程訪問同一個文件, 每個進程都要在自己的地址空間維護一個副本, 浪費了內存空間. 而如果能夠通過一定的機制將頁面映射到進程的地址空間中, 也就是說首先通過簡單的產生某些內存管理數據結構完成映射的創建. 當進程訪問頁面時產生一個缺頁中斷, 內核將頁面讀入內存並且更新頁表指向該頁面. 而且這種方式非常方便於同一副本的共享.

VM是面向對象的方法設計的, 這裡的對象是指內存對象: 內存對象是一個軟件抽象的概念, 它描述內存區與後備存儲之間的映射. 系統可以使用多種類型的後備存儲, 比如交換空間, 本地或者遠程文件以及幀緩存等等. VM系統對它們統一處理, 采用同一操作集操作, 比如讀取頁面或者回寫頁面等. 每種不同的後備存儲都可以用不同的方法實現這些操作. 這樣, 系統定義了一套統一的接口, 每種後備存儲給出自己的實現方法. 這樣, 進程的地址空間就被視為一組映射到不同數據對象上的的映射組成. 所有的有效地址就是那些映射到數據對象上的地址. 這些對象為映射它的頁面提供了持久性的後備存儲. 映射使得用戶可以直接尋址這些對象.

值得提出的是, VM體系結構獨立於Unix系統, 所有的Unix系統語義, 如正文, 數據及堆棧區都可以建構在基本VM系統之上. 同時, VM體系結構也是獨立於存儲管理的, 存儲管理是由操作系統實施的, 如: 究竟采取什麼樣的對換和請求調頁算法, 究竟是采取分段還是分頁機制進行存儲管理, 究竟是如何將虛擬地址轉換成為物理地址等等(Linux中是一種叫Three Level Page Table的機制), 這些都與內存對象的概念無關.

下面介紹Linux中VM的實現.

一個進程應該包括一個mm_struct(memory manage struct), 該結構是進程虛擬地址空間的抽象描述, 裡面包括了進程虛擬空間的一些管理信息: start_code, end_code, start_data, end_data, start_brk, end_brk等等信息. 另外, 也有一個指向進程虛存區表(vm_area_struct: virtual memory area)的指針, 該鏈是按照虛擬地址的增長順序排列的. 在Linux進程的地址空間被分作許多區(vma), 每個區(vma)都對應虛擬地址空間上一段連續的區域, vma是可以被共享和保護的獨立實體, 這裡的vma就是前面提到的內存對象. 下面是vm_area_struct的結構, 其中, www.linuxidc.com前半部分是公共的, 與類型無關的一些數據成員, 如: 指向mm_struct的指針, 地址范圍等等, 後半部分則是與類型相關的成員, 其中最重要的是一個指向vm_operation_struct向量表的指針vm_ops, vm_pos向量表是一組虛函數, 定義了與vma類型無關的接口. 每一個特定的子類, 即每種vma類型都必須在向量表中實現這些操作. 這裡包括了: open, close, unmap, protect, sync, nopage, wppage, swapout這些操作.

struct vm_area_struct {

/*公共的, 與vma類型無關的 */

struct mm_struct * vm_mm;
unsigned long vm_start;
unsigned long vm_end;
struct vm_area_struct *vm_next;
pgprot_t vm_page_prot;
unsigned long vm_flags;
short vm_avl_height;
struct vm_area_struct * vm_avl_left;
struct vm_area_struct * vm_avl_right;
struct vm_area_struct *vm_next_share;
struct vm_area_struct **vm_pprev_share;

/* 與類型相關的 */

struct vm_operations_struct * vm_ops;
unsigned long vm_pgoff;
struct file * vm_file;
unsigned long vm_raend;
void * vm_private_data;
};
vm_ops: open, close, no_page, swapin, swapout……

Copyright © Linux教程網 All Rights Reserved