小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Linux內(nèi)核源碼分析之setup_arch (二)

 小樣樣樣樣樣樣 2022-05-21 發(fā)布于北京

1. 概述

接著上一篇《Linux內(nèi)核源碼分析之setup_arch (一)》繼續(xù)分析,本文首先分析arm_memblock_init函數(shù),然后分析內(nèi)核啟動階段的是如何進行內(nèi)存管理的。

2. arm_memblock_init

該函數(shù)的功能比較簡單,主要就是把meminfo中記錄的內(nèi)存條信息添加到memblock.memory中,然后把內(nèi)核鏡像所在內(nèi)存區(qū)域添加到memblock.reserved中,arm_mm_memblock_reserve把頁表所在內(nèi)存區(qū)域添加到memblock.reserved中;如果使用了設(shè)備樹,則使用arm_dt_memblock_reserve來保留所占用的內(nèi)存,最后則是調(diào)用CPU相關(guān)的mdesc->reserve,其對應(yīng)的調(diào)用為cpu_mem_reserve,該函數(shù)定義在cpu.c中。

/* arch/arm/mm/init.c */
void __init arm_memblock_init(...) {
  for (i = 0; i < mi->nr_banks; i++)
    memblock_add(mi->bank[i].start, mi->bank[i].size);

  memblock_reserve(__pa(_stext), _end - _stext);
  arm_mm_memblock_reserve();
  arm_dt_memblock_reserve();

  if (mdesc->reserve)
    mdesc->reserve();

  arm_memblock_steal_permitted = false;
  memblock_allow_resize();
  memblock_dump_all();
}
/* include/kernel/memblock.h */
struct memblock {
 phys_addr_t current_limit;
 struct memblock_type memory;
 struct memblock_type reserved;
};

3. memblock_alloc

接下來就該執(zhí)行paging_init函數(shù)了,在分析paging_init之前先來點內(nèi)核啟動階段的內(nèi)存管理相關(guān)的內(nèi)容。從arm_memblock_init開始引入memblock數(shù)據(jù)結(jié)構(gòu),其作用是實現(xiàn)內(nèi)核啟動初期的內(nèi)存管理功能,嚴格來說,其生命周期到paging_init::bootmem_init為止,memblock_alloc調(diào)用流程如下。

實際查找空閑內(nèi)存的函數(shù)為memblock_find_in_range_node,而該函數(shù)中真正實現(xiàn)空閑內(nèi)存查找的是for_each_free_mem_range_reverse這個宏定義。

/* mm/memblock.c */
phys_addr_t memblock_find_in_range_node(...)
{
 ...
 for_each_free_mem_range_reverse(i, nid, &this_start, &this_end, NULL) {
      ...
      if (cand >= this_start)
        return cand;
 }
 return 0;
}

該宏定義如下,然而其中又嵌套了一個函數(shù)Orz...

/* include/linux/memblock.h */
#define for_each_free_mem_range_reverse(i, nid, p_start, p_end, p_nid)  for (i = (u64)ULLONG_MAX,                                                   __next_free_mem_range_rev(&i, nid, p_start, p_end, p_nid);             i != (u64)ULLONG_MAX;                                                  __next_free_mem_range_rev(&i, nid, p_start, p_end, p_nid))

首先需要說明的是,memblock.reserved標(biāo)識的區(qū)域表示的是已被占用的內(nèi)存區(qū)域,memblock.memory中記錄的是內(nèi)存條信息?,F(xiàn)在回到__next_free_mem_range_rev函數(shù),代碼段(1)(2)的目的是找出內(nèi)存條上兩個reserved區(qū)域之間的內(nèi)存區(qū)域,即空閑區(qū)域。找到之后再經(jīng)過代碼段(3)對空閑區(qū)域的起始地址和結(jié)束地址進行修正,因為代碼段(1)(2)只能保證空閑區(qū)與當(dāng)前內(nèi)存條存在交集,并不能保證該空閑區(qū)域完全處于當(dāng)前內(nèi)存條之中,主要原因在于無法保證這兩個reserved區(qū)域都在當(dāng)前內(nèi)存條上。

/* mm/memblock.c */
void __init_memblock __next_free_mem_range_rev(...)
{
 struct memblock_type *mem = &memblock.memory;
 struct memblock_type *rsv = &memblock.reserved;
 ...
 /* (1) */
 for ( ; mi >= 0; mi--) {
  struct memblock_region *m = &mem->regions[mi];
  phys_addr_t m_start = m->base;
  phys_addr_t m_end = m->base + m->size;
  ...
  /* (2) */
  for ( ; ri >= 0; ri--) {
   struct memblock_region *r = &rsv->regions[ri];
   phys_addr_t r_start = ri ? r[-1].base + r[-1].size : 0;
   phys_addr_t r_end = ri < rsv->cnt ? r->base : ULLONG_MAX;
   ...
   /* (3) */
   if (m_end > r_start) {
    if (out_start)
     *out_start = max(m_start, r_start);
    if (out_end)
     *out_end = min(m_end, r_end);
    if (out_nid)
     *out_nid = memblock_get_region_node(m);

    ...
    return;
   }
  }
 }

 *idx = ULLONG_MAX;
}

至此,空閑區(qū)域的查找基本就結(jié)束了,回到memblock_find_in_range_node函數(shù)中,再檢查一下該區(qū)域的起始地址和結(jié)束地址是否合法等等,最終就申請到了所請求大小的內(nèi)存區(qū)域,最后只需要將這塊內(nèi)存區(qū)域標(biāo)記為reserved狀態(tài)就結(jié)束了內(nèi)存分配的整個過程了。

/* mm/memblock.c */
int memblock_reserve(phys_addr_t base, phys_addr_t size)
{
 struct memblock_type *_rgn = &memblock.reserved;
 return memblock_add_region(_rgn, base, size, MAX_NUMNODES);
}

4. 總結(jié)

  • arm_memblock_init函數(shù)首先把記錄在meminfo記錄的內(nèi)存條信息轉(zhuǎn)移到memblock.memory中,然后把已經(jīng)使用的內(nèi)存區(qū)域記錄到memblock.reserved中,主要包括內(nèi)核鏡像所占用區(qū)域、頁表區(qū)域以及設(shè)備樹;
  • memblock_alloc通過memblock中的memory和reserved中記錄的信息進行內(nèi)存管理,每次申請到內(nèi)存之后都在memblock.reserved中進行記錄。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多