LDD3原始碼分析之vmalloc

2021-08-01 15:39:25 字數 2166 閱讀 4307

部落格:

編譯環境:ubuntu 10.10

核心版本:2.6.32-38-generic-pae

ldd3原始碼路徑:examples/scullv

一、scullv編譯
本文分析ldd3第8章中與vmalloc函式相關**,對應原始碼是examples/scullv目錄下的相關檔案。
這裡首先說明一下,scullv的**有兩部分,一是main.c,另一部分是mmap.c,其中mmap.c主要實現了記憶體對映相關函式。因為本文主要分析vmalloc的用法,並且mmap.c涉及的記憶體對映在新的核心中有了很大變化。在本文中,我們不討論mmap.c,並且為避免編譯時出現的錯誤,編譯時也不編譯mmap.c。
要想在編譯scullv模組時不編譯mmap.c,只要做如下修改:
將makefile第18行改為: scullp-objs := main.o
將main.c的第475行遮蔽掉: //.mmap =      scullp_mmap,
這樣就不會編譯mmap.c了。
即使不編譯mmap.c,scullv在2.6.32-38-generic-pae核心下編譯也會遇到很多問題,但是遇到的問題和解決方法和我在《ldd3原始碼分析之slab快取記憶體》中討論的是一樣的,這裡不詳細說明了。
二、vmalloc及其相關函式
vmalloc函式分配的內存在虛擬位址空間是連續的,在實體地址上可能不連續。
我們在這裡介紹vmalloc函式的原因是,它是linux記憶體分配機制的基礎。但是,在大多數情況下,我們並不鼓勵使用vmalloc,通過vmalloc函式獲得的記憶體使用效率不高,而且在某些體系架構上,用於vmalloc的位址空間總量相對較小。只要可能,應該直接和單個頁面打交道,而不是使用vmalloc。
[cpp]view plain

copy

void *vmalloc(unsigned long size);  

void vfree(void * addr);  

void *ioremap(unsigned long offset, unsigned long size);  

void iounmap(void * addr);  

需要強調的是,由kmalloc和__get_free_pages返回的記憶體位址也是虛擬位址,其實際值仍然需要由mmu處理才能轉換為物理記憶體位址。vmalloc在如何使用硬體上沒有區別,區別在於核心如何執行分配任務上。

kmalloc和__get_free_pages返回的虛擬位址範圍和物理記憶體是一一對應的,可能會有基於常量page_offset的乙個偏移。這兩個函式不需要為該位址段修改頁表。但是,vmalloc和ioremap使用的位址範圍是完全虛擬的,每次分配都要通過對頁表的適當設定來建立(虛擬)記憶體區域。
與vmalloc一樣,ioremap也建立新的頁表,但是和vmalloc不同的是,ioremap並不實際分配記憶體。ioremap的返回值是乙個特殊的虛擬位址,可以用來訪問指定的物理記憶體區域,這個虛擬位址最後要呼叫iounmap來釋放掉。
三、scullv分析
scullv中分配記憶體的**在scullv_write函式中:
[cpp]view plain

copy

244    /* allocate a quantum using virtual addresses */

245    if (!dptr->data[s_pos])   

scullv中釋放記憶體的**在scullv_trim函式中:

[cpp]view plain

copy

493    /* release the quantum-set */

494    for (i = 0; i 

495        if (dptr->data[i])  

496            vfree(dptr->data[i]);  

測試vmalloc模組的過程如下圖所示:

LDD3原始碼分析之llseek分析

分類 ldd3原始碼分析 2012 03 28 14 36 201人閱讀收藏 舉報部落格 編譯環境 ubuntu 10.10 核心版本 2.6.32 38 generic pae ldd3原始碼路徑 examples scull main.c 本文分析ldd3第6章的llseek函式。一 使用者空間...

LDD3原始碼分析之llseek分析

部落格 編譯環境 ubuntu 10.10 核心版本 2.6.32 38 generic pae ldd3原始碼路徑 examples scull main.c 本文分析ldd3第6章的llseek函式。一 使用者空間的lseek函式要理解驅動中llseek函式的實現,必須先清楚對應的使用者空間中l...

LDD3原始碼學習筆記之scull pipe轉

pipe.c 驅動功能分析 本驅動使用環形緩衝作為scull裝置的的具體實現,類似於pipe.其中實現了阻塞的i o讀寫和非同步通知.主函式流程分析 1.定義scull pipe裝置機構體 2.初始化模組module init scull p init 3.退出並登出模組module exit sc...