<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > linux下內存管理學習心得(一)

          linux下內存管理學習心得(一)

          作者: 時間:2016-11-23 來源:網絡 收藏
          最近在學習內存管理的時候,發(fā)現(xiàn)對linux下的所謂內存如何管理如何分配都不熟悉,通過最近的查閱資料可總結如下,如有不妥之處歡迎大家批評與指正。

          總的的來說linux的內存管理其實主要難理解的是以下幾個部分:

          本文引用地址:http://www.ex-cimer.com/article/201611/320404.htm

          1、虛擬地址、物理地址、線性地址、邏輯地址之間的區(qū)別。

          2、用戶地址空間與內核地址空間區(qū)別。

          3、內核如何分配所謂的地址。

          4、一個可執(zhí)行程序的地址分布以及運行地址分配。

          目前我也大概總結這幾個,其實這方面的知識肯定很多,但限于能力只能如何,也盡最大努力詳細分析其中原委。注:很多是參考了網上的大??偨Y的。

          一、各地址之間區(qū)別

          1、虛擬地址

          其中各種地址的概念大家都可查閱到,我也就不多說了,虛擬地址就是為了給用戶一個更大的使用空間(當然這個使用空間肯定是虛擬了的),然后32位下面用戶地址空間也就是虛擬地址空間范圍就是0--4GB。其中這個范圍又可以劃為0--3GB-1用戶空間和3GB--4GB-1的內核空間。其中進程都各自有各自的0--3GB-1地址范圍而共享3GB--4GB-1的內核空間。更詳細的請往下此處不講為了大家先有個宏觀的認識。

          1、分頁單元中,頁目錄的地址放在CUP的CR3寄存器中,是進行抵制轉換的開始點。

          2、每個進程,都有其獨立的虛擬地址空間,運行一個進程,首先需要將它的頁目錄地址放在CR3寄存器中,其他的進程的保存下來。

          3、每一個32位的線性地址被劃分為三部分:頁目錄索引(10位):頁表索引(10位):偏移12位。

          裝換:

          1、先裝入進程的頁目錄地址(調度程序把這個地址裝入CR3中);

          2、根據線性地址前10位,在頁目錄中找到對應的索引項,頁目錄中的項是一個頁表的地址;

          3、根據線性地址的中間10位,在頁表中找到頁的起始地址;

          4、將頁的起始地址與線性地址的最后12為偏移地址相加最后為物理地址。

          二、用戶地址與內核地址

          Linux 操作系統(tǒng)和驅動程序運行在內核空間,應用程序運行在用戶空間,兩者不能簡單地使用指針傳遞數(shù)據,因為Linux使用的虛擬內存機制,用戶空間的數(shù)據可能被換出,當內核空間使用用戶空間指針時,對應的數(shù)據可能不在內存中。

          其中內核地址空間是由內核負責映射,它并不會跟著進程改變,是固定的。其中內核空間分布如下:

          (1)直接內存映射區(qū)

          從3G開始,最大896M的線性地址區(qū)間,我們稱作直接內存映射區(qū),這是因為該區(qū)域的線性地址和物理地址之間存在線性裝換關系:線性地址=3G+物理地址

          (2)動態(tài)內存映射區(qū)

          又內核函數(shù)vmalloc來進行分配,其特點是線性空間連續(xù),但物理地址空間不一定連續(xù)。

          (3)永久內存映射區(qū)

          使用kmap函數(shù)將分配到得896M以上的高端內存映射到該區(qū)

          (4)固定映射區(qū)

          特殊用途

          用戶空間

          用戶空間是0-3GB-1的空間范圍。這里就提前說一下程序鏡像加載到運行的過程。

          首先二進制程序是放在外部存儲器中的,當啟動一個進程的時候先分配自己進程的虛擬空間,這個時候將程序鏡像加載到內存(具體內核過程下面介紹),如何鏡像很大的話先加載一部分(這部分是多大?我還不清楚有待研究),然后這個時候進程的空間就會映射(一定注意是映射,因為根本就沒有這樣的地址,這只是個虛的),此時該進程好像有了這個鏡像了,那么進程執(zhí)行的時候根據線性地址找到物理地址(內存)中的代碼執(zhí)行。就是這么簡單。

          三、內核分配內存

          在linux操作系統(tǒng)中,每個進程都通過一個task_struct的結構體描敘,每個進程的地址空間都通過一個mm_struct描敘,c語言中的每個段空間都通過vm_area_struct表示,他們關系如下 :

            當運行一個程序時,操作系統(tǒng)需要創(chuàng)建一個進程,這個進程和程序之間都干了些什么呢?

            當一個程序被執(zhí)行時,該程序的內容必須被放到進程的虛擬地址空間,對于可執(zhí)行程序的共享庫也是如此。可執(zhí)行程序并非真正讀到物理內存中,而只是鏈接到進程的虛擬內存中。

            當一個可執(zhí)行程序映射到進程虛擬地址空間時,一組vm_area_struct數(shù)據結構將被產生。每個vm_area_struct數(shù)據結構表示可執(zhí)行印象的一部分;是可執(zhí)行代碼,或是初始化的數(shù)據,以及未初始化的數(shù)據等。

            linux操作系統(tǒng)是通過sys_exec對可執(zhí)行文件進行映射以及讀取的,有如下幾步:

            1.創(chuàng)建一組vm_area_struct

            2.圈定一個虛擬用戶空間,將其起始結束地址(elf段中已設置好)保存到vm_start和vm_end中。

            3.將磁盤file句柄保存在vm_file中

            4.將對應段在磁盤file中的偏移值(elf段中已設置好)保存在vm_pgoff中;

            5.將操作該磁盤file的磁盤操作函數(shù)保存在vm_ops中

            注意:這里沒有對應 的頁目錄表項創(chuàng)建頁表,更不存在設置頁表項了。

            假設現(xiàn)在程序中有一條指令需要讀取上面vm_start--vm_end之間的某內容

            例如:mov [0x08000011],%eax,那么將會執(zhí)行如下序列:

            1.cpu依據CR3(current->pgd)找到0x08000011地址對應的pgd[i],由于該pgd[i]內容保持為初始化狀態(tài)即為0,導致cpu異常.

            2.do_page_fault被調用,在該函數(shù)中,為pgd[i]在內存中分配一個頁表,并讓該表項指向它,如下圖所示:

            注意:這里i為0x08000011高10位,j為其中間10位,此時pt表項全部為0(pte[j]也為0);

            3.為pte[j]分配一個真正的物理內存頁面,依據vm_area_struct中的vm_file、vm_pgoff和vm_ops,調用filemap_nopage將磁盤file中vm_pgoff偏移處的內容讀入到該物理頁面中,如下圖所示:

           ?、?。分配物理內存頁面;

           ?、?。從磁盤文件中將內容讀取到物理內存頁面中

            從上面我們可以知道,在進程創(chuàng)建的過程中,程序內容被映射到進程的虛擬內存空間,為了讓一個很大的程序在有限的物理內存空間運行,我們可以把這個程序的開始部分先加載到物理內存空間運行,因為操作系統(tǒng)處理的是進程的虛擬地址,如果在進行虛擬到物理地址的轉換工程中,發(fā)現(xiàn)物理地址不存在時,這個時候就會發(fā)生缺頁異常(nopage),接著操作系統(tǒng)就會把磁盤上還沒有加載到內存中的數(shù)據加載到物理內存中,對應的進程頁表進行更新。也許你會問,如果此時物理內存滿了,操作系統(tǒng)將如何處理?

            下面我們看看linux操作系統(tǒng)是如何處理的:

            如果一個進程想將一個虛擬頁裝入物理內存,而又沒有可使用的空閑物理頁,操作系統(tǒng)就必須淘汰物理內存中的其他頁來為此頁騰出空間。

            在linux操作系統(tǒng)中,物理頁的描敘如下:

            struct mem_map

            {

            1.本頁使用計數(shù),當該頁被許多進程共享時計數(shù)將大于1.

            2.age描敘本頁的年齡,用來判斷該頁是否為淘汰或交換的好候選

            3.map_nr描敘物理頁的頁幀號

            }

            如果從物理內存中被淘汰的頁來自于一個映像或數(shù)據文件,并且還沒有被寫過,則該頁不必保存,它可以丟掉。如果有進程在需要該頁時就可以把它從映像或數(shù)據文件中取回內存。


          上一頁 1 2 下一頁

          關鍵詞: linux內存管理學習心

          評論


          相關推薦

          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();