linux核心記憶體管理(zone_dma zone_normal zone_highmem)__linux

來源:互聯網
上載者:User

Linux 作業系統和驅動程式運行在核心空間,應用程式運行在使用者空間,兩者不能簡單地使用指標傳遞資料,因為Linux使用的虛擬記憶體機制,使用者空間的資料可能被換出,當核心空間使用使用者空間指標時,對應的資料可能不在記憶體中。

   Linux核心地址空間劃分

通常32位Linux核心地址空間劃分0~3G為使用者空間,3~4G為核心空間。注意這裡是32位核心地址空間劃分,64位核心地址空間劃分是不同的。


1、x86的物理地址空間布局:



  物理地址空間的頂部以下一段空間,被PCI裝置的I/O記憶體映射佔據,它們的大小和布局由PCI規範所決定。640K~1M這段地址空間被BIOS和VGA適配器所佔據。

  Linux系統在初始化時,會根據實際的實體記憶體的大小,為每個物理頁面建立一個page對象,所有的page對象構成一個mem_map數組。

進一步,針對不同的用途,Linux核心將所有的物理頁面劃分到3類記憶體管理區中,如圖,分別為ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM。

  ZONE_DMA的範圍是0~16M,該地區的物理頁面專門供I/O裝置的DMA使用。之所以需要單獨管理DMA的物理頁面,是因為DMA使用物理地址訪問記憶體,不經過MMU,並且需要連續的緩衝區,所以為了能夠提供物理上連續的緩衝區,必須從物理地址空間專門劃分一段地區用於DMA。

  ZONE_NORMAL的範圍是16M~896M,該地區的物理頁面是核心能夠直接使用的。

  ZONE_HIGHMEM的範圍是896M~結束,該地區即為高端記憶體,核心不能直接使用。


2、linux虛擬位址核心空間分布

  在kernel image下面有16M的核心空間用於DMA操作。位於核心空間高端的128M地址主要由3部分組成,分別為vmalloc area,持久化核心映射區,臨時核心映射區。

  由於ZONE_NORMAL和核心線性空間存在直接映射關係,所以核心會將頻繁使用的資料如kernel代碼、GDT、IDT、PGD、mem_map數組等放在ZONE_NORMAL裡。而將使用者資料、頁表(PT)等不常用資料放在ZONE_ HIGHMEM裡,只在要訪問這些資料時才建立映射關係(kmap())。比如,當核心要訪問I/O裝置儲存空間時,就使用ioremap()將位於物理地址高端的mmio區記憶體映射到核心空間的vmalloc area中,在使用完之後便斷開映射關係。


3、linux虛擬位址使用者空間分布

  使用者進程的代碼區一般從虛擬位址空間的0x08048000開始,這是為了便於檢查null 指標。代碼區之上便是資料區,未初始化資料區,堆區,棧區,以及參數、全域環境變數。

4、linux虛擬位址與物理地址映射的關係


  Linux將4G的線性地址空間分為2部分,0~3G為user space,3G~4G為kernel space。

  由於開啟了分頁機制,核心想要訪問物理地址空間的話,必須先建立映射關係,然後通過虛擬位址來訪問。為了能夠訪問所有的物理地址空間,就要將全部物理地址空間映射到1G的核心線性空間中,這顯然不可能。於是,核心將0~896M的物理地址空間一對一映射到自己的線性地址空間中,這樣它便可以隨時訪問ZONE_DMA和ZONE_NORMAL裡的物理頁面;此時核心剩下的128M線性地址空間不足以完全映射所有的ZONE_HIGHMEM,Linux採取了動態映射的方法,即按需的將ZONE_HIGHMEM裡的物理頁面映射到kernel space的最後128M線性地址空間裡,使用完之後釋放映射關係,以供其它物理頁面映射。雖然這樣存在效率的問題,但是核心畢竟可以正常的訪問所有的物理地址空間了。


5、buddyinfo的理解

cat /proc/buddyinfo 顯示如下:

Node 0, zone      DMA       0      4      5      4      4      3 ...

Node 0, zone   Normal      1      0      0      1    101     8 ...

Node 0, zone  HighMem    2      0      0      1      1       0 ...

其中,Node表示在NUMA環境下的節點號,這裡只有一個節點0;zone表示每一個節點下的地區,一般有DMA、Normal和HignMem三個地區;後面的列表示,夥伴系統中每一個order對應的空閑頁面塊。例如,對於zone DMA的第二列(從0開始算起),空閑頁面數為5*2^4,可用記憶體為5*2^4*PAGE_SIZE。


計算方法就是:

                     當前列的數字*2^列數*PAGE_SIZE 其中列數是從0開始計算的,即第一列是 當前列的數字*2^0*PAGE_SIZE



常見問題:

1、使用者空間(進程)是否有高端記憶體概念。

使用者進程沒有高端記憶體概念。只有在核心空間才存在高端記憶體。使用者進程最多隻可以訪問3G實體記憶體,而核心進程可以訪問所有實體記憶體。


2、64位核心中有高端記憶體嗎。

目前現實中,64位Linux核心不存在高端記憶體,因為64位核心可以支援超過512GB記憶體。若機器安裝的實體記憶體超過核心地址空間範圍,就會存在高端記憶體。


3、使用者進程能訪問多少實體記憶體。核心代碼能訪問多少實體記憶體。

32位系統使用者進程最大可以訪問3GB,核心代碼可以訪問所有實體記憶體。

64位系統使用者進程最大可以訪問超過512GB,核心代碼可以訪問所有實體記憶體。


4、高端記憶體和物理地址、邏輯地址、線性地址的關係。

高端記憶體只和邏輯地址有關係,和邏輯地址、物理地址沒有直接關係。


5、為什麼不把所有的地址空間都分配給核心。

若把所有地址空間都給記憶體,那麼使用者進程怎麼使用記憶體。怎麼保證核心使用記憶體和使用者進程不起衝突。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.