加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

Linux內(nèi)存管理:memblock

2022/11/13
2243
閱讀需 7 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

內(nèi)存管理是操作系統(tǒng)內(nèi)核中最復(fù)雜的部分之一, start_kernel函數(shù)在內(nèi)核啟動第一個init進程前初始化了所有的內(nèi)核特性(包括那些依賴于不同架構(gòu)的特性),你也許還記得引導(dǎo)時創(chuàng)立的臨時頁表,但復(fù)雜的內(nèi)存管理部分還沒有開始,當(dāng)start_kernel函數(shù)被調(diào)用時,我們會看到初期內(nèi)存管理到更復(fù)雜的內(nèi)存管理數(shù)據(jù)結(jié)構(gòu)和技術(shù)的轉(zhuǎn)變,為了更好的理解內(nèi)核的初始化過程,我們需要對這些技術(shù)有更清晰的理解,今天我們會著重討論這個過程,主要針對初期的內(nèi)存管理memblock的介紹。

首先我們知道在內(nèi)核啟動后,對于內(nèi)存,分成好幾塊:

內(nèi)存中的某些部分使永久分配給內(nèi)核的,例如代碼段和數(shù)據(jù)段、ramdisk和dtb占用的空間、臨時頁表和設(shè)備數(shù)中的保留區(qū)域等,是系統(tǒng)內(nèi)存的一部分,不能被侵占,也不參與內(nèi)存的分配,稱之為靜態(tài)內(nèi)存;

GPU/camera/多核共享的內(nèi)存都需要預(yù)留大量連續(xù)內(nèi)存,這部分內(nèi)存平時不使用,但是必須為各個應(yīng)用場景預(yù)留,這樣的內(nèi)存稱之為預(yù)留內(nèi)存;

內(nèi)存其余的部分,是需要內(nèi)核管理的內(nèi)存,稱之為動態(tài)內(nèi)存;

那么memblock就是將以上內(nèi)存按功能劃分為若干內(nèi)存區(qū),使用不同的類型存放在memory和reserved的兩個集合中,memory即為動態(tài)內(nèi)存,而resvered包括靜態(tài)內(nèi)存等。

memblock是什么

memblock介紹

memblock即linux啟動后kernel管理內(nèi)存空間抽象出來的結(jié)構(gòu),此時buddy系統(tǒng)和slab分配器等并沒有初始化,當(dāng)需要執(zhí)行一些內(nèi)存管理、內(nèi)存分配的任務(wù),此時就是有初期的管理模塊memblock機制。在mm_init中會建立內(nèi)核的內(nèi)存分配器,停用memblock,釋放內(nèi)存給伙伴系統(tǒng)和slab分配器。memblock是bootmem的升級版本,在config中配置:CONFIG_NO_BOOTMEM=Y。

需要的結(jié)構(gòu)體

第一個結(jié)構(gòu)體的名字就叫做 memblock。它的定義如下:

struct memblock {
         bool bottom_up;
         phys_addr_t current_limit;
         struct memblock_type memory;   --> array of memblock_region
         struct memblock_type reserved; --> array of memblock_region
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
         struct memblock_type physmem;
#endif
};

這個結(jié)構(gòu)體包含五個域。第一個 bottom_up 域置為 true 時允許內(nèi)存以自底向上模式進行分配。下一個域是 current_limit。這個域描述了內(nèi)存塊的尺寸限制。接下來的三個域描述了內(nèi)存塊的類型。內(nèi)存塊的類型可以是:被保留、內(nèi)存和物理內(nèi)存( CONFIG_HAVE_MEMBLOCK_PHYS_MAP 編譯配置選項被開啟)。

接下來我們可以看看下一個數(shù)據(jù)結(jié)構(gòu)memblock_type,定義如下:

struct memblock_type {
 unsigned long cnt;
 unsigned long max;
 phys_addr_t total_size;
 struct memblock_region *regions;
};

memblock_region 提供了內(nèi)存區(qū)域的基址和大小,如果 CONFIG_HAVE_MEMBLOCK_NODE_MAP 編譯配置選項被開啟, memblock_region 結(jié)構(gòu)體也提供了整數(shù)域 - numa 節(jié)點選擇器。flags 域可以是:

/* Definition of memblock flags. */
enum memblock_flags {
 MEMBLOCK_NONE  = 0x0/* No special request */
 MEMBLOCK_HOTPLUG = 0x1/* hotpluggable region */
 MEMBLOCK_MIRROR  = 0x2/* mirrored region */
 MEMBLOCK_NOMAP  = 0x4/* don't add to kernel direct mapping */
};

以上的關(guān)系如圖所示:

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

針對嵌入式人工智能,物聯(lián)網(wǎng)等專業(yè)技術(shù)分享和交流平臺,內(nèi)容涉及arm,linux,android等各方面。