vma和page結構 和mmap函式
1.page 主要成員
atomic_t count;
//這個頁的引用數. 當這個 count 掉到 0, 這頁被返回給空閒列表.
void *virtual;
//如果頁被對映,則表示這頁的核心虛擬位址; 否則, null.
unsigned long flags;
//描述頁狀態的一套位標誌. 這些包括 pg_locked, 它指示該頁在記憶體中已被加鎖, 以及 pg_reserved,
//它防止記憶體管理系統使用該頁
2.vm_area_struct 主要成員
unsigned long vm_start;//vma 開始於
unsigned long vm_end; //vma 結束
struct file *vm_file;
//指向和這個區(如果有乙個)關聯的 struct file 結構的指標.
unsigned long vm_pgoff;
//檔案中區的偏移, 以頁計. 當乙個檔案和裝置被對映, 這是對映在這個區的第一頁的檔案位置.?????
unsigned long vm_flags;
// 裝置驅動常用的標誌是 vm_io 和 vm_reservued.
//vm_io 標誌乙個 vma 作為記憶體對映的 i/o 區,阻止這個區被包含在程序核轉儲???中.
//vm_reserved 告知記憶體管理系統不要試圖交換出這個 vma;
struct vm_operations_struct *vm_ops;
//操作
//void (*open)(struct vm_area_struct *vma); vma剛剛產生時,此函式被呼叫來初始化vma
//void (*close)(struct vm_area_struct *vma); 當乙個區被銷毀, 核心呼叫它的關閉操作
//struct page *(*nopage)(struct vm_area_struct *vma, unsigned long address, int *type);
//如果 nopage 方法沒有定義,核心分配乙個空頁.程序訪問不在記憶體中有效 vma 的頁時,nopage 方法被呼叫(如果它被定義)
//int (*populate)(struct vm_area_struct *vm, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int
nonblock);
//在它們被使用者空間訪問之前,允許核心"預錯"頁到記憶體. 驅動通常沒有必要實現這個填充方法
void *vm_private_data;
//驅動可以用來儲存它的自身資訊的成員.
3.mmap使用者空間呼叫與核心空間呼叫
void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset);
//start 指向欲對應的記憶體起始位址,通常設為null,代表讓系統自動選定位址,對應成功後該位址會返回
//引數length代表將檔案中多大的部分對應到記憶體。
//引數prot代表對映區域的保護方式
//fd檔案描述符
//引數offset為檔案對映的偏移量,通常設定為0,代表從檔案最前方開始對應,offset必須是分頁大小
//的整數倍,對映檔案的起動位移量受系統虛存頁長度的限制,那麼如果對映區的長度不是頁長度的整數
//倍時,將如何呢?假定檔案長12位元組,系統頁長為512位元組,則系統通常提供512位元組的對映區,其中
//後500位元組被設為0。可以修改這500位元組,但任何變動都不會在檔案中反映出來
//若對映成功則返回對映區的記憶體起始位址,否則返回map_failed(-1)
核心空間呼叫
int (*mmap) (struct file *filp, struct vm_area_struct *vma);
4.mmap執行的順序
a.在使用者程序建立乙個vma區域
b.驅動程式獲得頁
c.將獲得的頁分配給vma區域
四、如何給vma分配頁
1.一次完成全部
int remap_pfn_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long pfn, unsigned long size, pgprot_t prot);
//vma 使用者程序建立乙個vma區域
//virt_addr 重新對映應當開始的使用者虛擬位址. 這個函式建立頁表為這個虛擬位址範圍從 virt_addr 到 virt_addr_size.
//pfn 頁幀號, 對應虛擬位址應當被對映的實體地址. 這個頁幀號簡單地是實體地址右移 page_shift 位. 對大部分使用, vma 結構的 vm_paoff 成員正好包含你需要的值. 這個函式影響實體地址從 (pfn
//返回的值常常是 0 或者乙個負的錯誤值
int io_remap_page_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long phys_addr, unsigned long size, pgprot_t prot);
//當用在 phys_addr 指向 i/o 記憶體時返回的值常常是 0 或者乙個負的錯誤值???
2.一頁一頁的分配
struct page *(*nopage)(struct vm_area_struct *vma, unsigned long address, int *type);
//address 代表從使用者空間傳過來的使用者空間虛擬位址
//返回乙個有效對映頁
3.限制:
remap_pfn_range不能對映常規記憶體,只訪問保留頁和在物理記憶體頂之上的實體地址。因為保留頁和在物理
記憶體頂之上的實體地址記憶體管理系統的各個子模組管理不到。640 kb 和 1mb 是保留頁可能對映,裝置i/o
記憶體也可以對映。如果想把kmalloc()申請的記憶體對映到使用者空間,則可以通過mem_map_reserve()把相應
的記憶體設定為保留後就可以。
remap_pfn_range常用於裝置記憶體對映,而nopage()常用於ram對映
Linux記憶體對映 mmap
linux提供了記憶體對映函式mmap,它把檔案內容對映到一段記憶體上 準確說是虛擬記憶體上 通過對這段記憶體的讀取和修改,實現對檔案的讀取和修改,先來看一下mmap的函式宣告 原型 void mmap void addr,size t length,int prot,int flags,int f...
Linux記憶體管理 mmap
mmap munmap是常用的乙個系統呼叫,使用場景是 分配記憶體 讀寫大檔案 連線動態庫檔案 多程序間共享記憶體。mmap munmap函式宣告如下 include void mmap void addr,size t length,int prot,int flags,int fd,off t ...
mmap操作思考題
父子程序共享什麼?共享檔案,和mmap的對映區 但是要用map share 1.men 後mmap能否成功?不可以。位址必須相同 2.如果open時o rdonly,mmap時prot引數指定prot read prot write會怎樣?許可權不夠。原因 建立對映區的許可權 開啟檔案的許可權 但是...