|
至于一些基礎(chǔ)性的知識就不說了,很多書都有,說得很精彩。這里主要談?wù)剝?nèi)核對于內(nèi)存管理的一些比較沒人提到的部分。
我們都知道,內(nèi)核把線性地址(大多數(shù)情況也叫虛擬地址)分為三個部分:物理內(nèi)存映射區(qū),VMALLOC映射區(qū)以及固定映射地址區(qū)。這里主要討論前兩種。
所謂的物理內(nèi)存映射區(qū)是指與物理內(nèi)存一一映射的區(qū)域。舉個例子來說,如果系統(tǒng)有物理內(nèi)存512M,那么從0xc0000000至 0xc00000000+512M的線性地址就屬于物理內(nèi)存映射區(qū)。這塊線性地址在系統(tǒng)初始化時就與物理內(nèi)存建立起一一對應(yīng)的關(guān)系。這里的一一映射是指物 理地址和線性地址就差一個偏移量0xc0000000,函數(shù)__pa()就是直接把線性地址減去0xc0000000得到物理地址。所以該函數(shù)應(yīng)用范圍也 就局限于物理地址映射區(qū)。對另兩個地址區(qū)進行__pa()是錯誤的。道理很簡單,物理地址都沒那么大。
VMALLOC映射區(qū)的特點是 連續(xù)的線性地址,其物理地址不一定連續(xù)。這種映射特點和用戶地址空間的映射方式是一樣的。而前面講的物理內(nèi)存映射區(qū),線性地址和物理地址顯然都是連續(xù)的。 當(dāng)然了,最后的映射肯定是指線性地址和物理地址之間的映射。所以這部分的線性地址最終也需映射到物理內(nèi)存中。這就會和物理內(nèi)存映射區(qū)產(chǎn)生沖突:因為所有的 物理內(nèi)存在物理內(nèi)存映射區(qū)已經(jīng)有了一個線性地址了。但是我們知道,物理內(nèi)存并不是每時每刻都在使用的,也就是說雖然它已經(jīng)映射了,但是還沒有人使用它。那 么我們可以在VMALLOC映射區(qū)中先映射到那些沒使用的內(nèi)存并鎖住。這樣這些內(nèi)存就不會再被分配作為其他用途。所以雖然映射有沖突,但是沒有兩個線性地 址在同時使用。
因為VMALLOC映射區(qū)的線性地址和物理地址沒有固定的映射關(guān)系,我們只能通過查找頁表來找到對應(yīng)的物理頁框。值得 一提的是,物理頁框(struct page結(jié)構(gòu)體)的vitual字段仍然存放的是物理內(nèi)存映射區(qū)的線性地址,也就是說如果對該物理地址進行__page_to_vir()運算后,所得的 線性地址不是VMALLOC映射區(qū)的線性地址。
以上就是我對linux內(nèi)存管理的一些理解。歡迎大家討論