成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

鴻蒙輕內核A核源碼分析系列之虛實映射(1)基礎概念

開發 前端
虛實映射其實就是一個建立頁表的過程。MMU支持多級頁表,LiteOS-A內核采用二級頁表描述進程空間。首先介紹下一級頁表和二級頁表。

[[437938]]

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

虛實映射是指系統通過內存管理單元(Memory Management Unit,MMU)將進程空間的虛擬地址(VA)與實際的物理地址(PA)做映射,并指定相應的訪問權限、緩存屬性等。程序執行時,CPU訪問的是虛擬內存,通過MMU找到映射的物理內存,并做相應的代碼執行或數據讀寫操作。MMU的映射由頁表(Page Table)來描述,頁表保存虛擬地址和物理地址的映射關系以及訪問權限等。每個進程在創建的時候都會創建一個頁表,頁表由一個個頁表條目(Page Table Entry, PTE)構成,每個頁表條目描述虛擬地址區間與物理地址區間的映射關系。頁表數據在內存區域存儲位置的開始地址叫做轉換表基地址/頁表基地址(Translation Table Base,TTB)。MMU中有一塊頁表緩存,稱為快表(Translation Lookaside Buffers, TLB),它緩存最近查找過的VA對應的頁表項。做地址轉換時,MMU首先在TLB中查找,如果找到對應的頁表項,則可直接進行轉換,否則就要去物理內存中讀取頁表項。TLB緩存可以減少訪問物理內存的次數,提升查詢效率。

本文中所涉及的源碼,以OpenHarmony LiteOS-A內核為例,均可以在開源站點https://gitee.com/openharmony/kernel_liteos_a 獲取。如果涉及開發板,則默認以hispark_taurus為例。MMU相關的操作函數主要在文件arch/arm/arm/src/los_arch_mmu.c中定義。

虛實映射其實就是一個建立頁表的過程。MMU支持多級頁表,LiteOS-A內核采用二級頁表描述進程空間。首先介紹下一級頁表和二級頁表。

1、一級頁表L1和二級頁表L2

1.1 頁表項基礎概念

L1頁表將全部的4GiB虛擬內存地址空間劃分為4096份,每份大小1MiB。每份對應一個32位的頁表項,內容是L2頁表基地址TTB或某個1MiB大小的物理內存的地址。其中高12位記錄頁號,用于對頁表項定位,也就是4096個頁表項的索引;低20位記錄頁內偏移值,虛實地址頁內偏移值相等。使用虛擬地址中的虛擬頁號查詢頁表得到對應的物理頁號,然后與虛擬地址中的頁內位移組成物理地址。每個L1頁表項將1MiB的虛擬內存地址轉換為物理地址。如下圖所示:

鴻蒙輕內核A核源碼分析系列五 虛實映射(1)基礎概念-鴻蒙HarmonyOS技術社區

對于用戶進程,每個一級頁表條目描述符占用4個字節(即32位的L1頁表項),可表示1MiB的內存空間的映射關系,即1GiB用戶空間(LiteOS-A內核中用戶空間占用1GiB)的虛擬內存空間需要1024個L1頁表項。系統創建用戶進程時,在內存中申請一塊4KiB大小(=4byte*1024)的內存塊作為一級頁表項的存儲區域,系統根據當前進程的需要會動態申請內存作為二級頁表的存儲區域?,F在我們就知道,在虛擬內存章節,用戶進程虛擬地址空間初始化函數OsCreateUserVmSpace()申請了4KiB的內存作為頁表存儲區域的依據了:VADDR_T *ttb = LOS_PhysPagesAllocContiguous(1);,這段內存的開始地址就是TTB頁表基地址。每個用戶進程需要申請自己的頁表項存儲區域,對于內核進程,頁表項存儲區域是固定的,即UINT8 g_firstPageTable[0x4000],大小為16KiB。

L1頁表項的低2位用于定義頁表項的類型,頁表項類型有如下3種:

  • Invalid 無效頁表項,虛擬地址沒有映射到物理地址,訪問會產生缺頁異常;
  • Page Table 指向L2頁表的頁表項;
  • Section Section 頁表項對應1MiB大小的內存塊,直接使用頁表項的最高12位替代虛擬地址的高12位即可得到物理地址。

L2頁表把1MiB的地址范圍按4KiB的內存頁大小繼續分成256個小頁。內存的高20位記錄頁號,用于對頁表項定位;低12位記錄頁內偏移值,虛實地址頁內偏移值相等。使用虛擬地址中的虛擬頁號查詢頁表得到對應的物理頁號,然后與虛擬地址中的頁內位移組成物理地址。每個L2頁表項將4KiB的虛擬內存地址轉換為物理地址。如下圖所示:

鴻蒙輕內核A核源碼分析系列五 虛實映射(1)基礎概念-鴻蒙HarmonyOS技術社區

L2頁表項的低2位用于識別頁表項的類型,類型有如下4種:

Invalid 無效頁表項,虛擬地址沒有映射到物理地址,訪問會產生缺頁異常;

Large Page 大頁表項,支持64KiB大頁,暫不支持;

Small Page 小頁表項,支持4KiB小頁的二級頁表映射;

Small Page XN 小頁表項擴展。

在文件arch/arm/arm/include/los_mmu_descriptor_v6.h中定義了頁表項類型,代碼如下:

  1. /* L1 descriptor type */ 
  2. #define MMU_DESCRIPTOR_L1_TYPE_INVALID                          (0x0 << 0) 
  3. #define MMU_DESCRIPTOR_L1_TYPE_PAGE_TABLE                       (0x1 << 0) 
  4. #define MMU_DESCRIPTOR_L1_TYPE_SECTION                          (0x2 << 0) 
  5. #define MMU_DESCRIPTOR_L1_TYPE_MASK                             (0x3 << 0) 
  6.  
  7. /* L2 descriptor type */ 
  8. #define MMU_DESCRIPTOR_L2_TYPE_INVALID                          (0x0 << 0) 
  9. #define MMU_DESCRIPTOR_L2_TYPE_LARGE_PAGE                       (0x1 << 0) 
  10. #define MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE                       (0x2 << 0) 
  11. #define MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN                    (0x3 << 0) 
  12. #define MMU_DESCRIPTOR_L2_TYPE_MASK                             (0x3 << 0)     

1.2 頁表項操作

在文件arch/arm/arm/include/los_pte_ops.h定義了頁表項相關的操作。

1.2.1 函數OsGetPte1獲取虛擬地址的L1頁表項

⑴處的OsGetPte1Index()內聯函數獲取虛擬地址的高12位作為頁表號。

⑵處的OsGetPte1Ptr()內聯函數根據頁表項基地址和虛擬地址獲取對應的L1頁表項地址。

⑶處的函數OsGetPte1()用于獲取指定虛擬地址對應的L1頁表項數據。該L1頁表項地址由頁表項基地址pte1BasePtr加上虛擬地址va對應的頁表項索引(頁表號)組成,其中頁表項索引等于虛擬地址的高12位。

需要注意函數OsGetPte1Index()和OsGetPte1()的區別,前者是頁表項內存地址,后者是頁表項地址上保持的頁表項數據。

  1.    STATIC INLINE UINT32 OsGetPte1Index(vaddr_t va) 
  2.     { 
  3. ⑴      return va >> MMU_DESCRIPTOR_L1_SMALL_SHIFT; 
  4.     } 
  5.  
  6.     STATIC INLINE PTE_T *OsGetPte1Ptr(PTE_T *pte1BasePtr, vaddr_t va) 
  7.     { 
  8. ⑵      return (pte1BasePtr + OsGetPte1Index(va)); 
  9.     } 
  10.  
  11.     STATIC INLINE PTE_T OsGetPte1(PTE_T *pte1BasePtr, vaddr_t va) 
  12.     { 
  13. ⑶      return *OsGetPte1Ptr(pte1BasePtr, va); 
  14.     } 

1.2.2 函數OsGetPte2獲取虛擬地址的L2頁表項

⑴處OsGetPte2Index()函數根據虛擬地址獲取對應頁表項的頁表號,計算方式是把虛擬地址對1MiB取余,然后取高20位。因為L2頁表項細分的是1MiB內存塊,這里把虛擬地址對1MiB取余。

⑵處的函數OsGetPte2()用于獲取指定虛擬地址對應的L2頁表項地址。L2頁表項地址由頁表項基地pte2BasePtr址加上頁表項索引組成,其中頁表項索引等于虛擬地址對1MiB取余后的高20位。

  1.  STATIC INLINE UINT32 OsGetPte2Index(vaddr_t va) 
  2.     { 
  3. ⑴      return (va % MMU_DESCRIPTOR_L1_SMALL_SIZE) >> MMU_DESCRIPTOR_L2_SMALL_SHIFT; 
  4.     } 
  5.  
  6.     STATIC INLINE PTE_T OsGetPte2(PTE_T *pte2BasePtr, vaddr_t va) 
  7.     { 
  8. ⑵      return *(pte2BasePtr + OsGetPte2Index(va)); 
  9.     } 

1.2.3 頁表項類型判斷函數

從上文已經可知,每一個L1頁表項的低2位標記頁表項的類型,OsIsPte1PageTable、OsIsPte1Invalid、OsIsPte1Section等函數分別判斷L1頁表項是否是頁表、無效、Section段類型。

  1. STATIC INLINE BOOL OsIsPte1PageTable(PTE_T pte1) 
  2.  { 
  3.      return (pte1 & MMU_DESCRIPTOR_L1_TYPE_MASK) == MMU_DESCRIPTOR_L1_TYPE_PAGE_TABLE; 
  4.  } 
  5.  
  6.  STATIC INLINE BOOL OsIsPte1Invalid(PTE_T pte1) 
  7.  { 
  8.      return (pte1 & MMU_DESCRIPTOR_L1_TYPE_MASK) == MMU_DESCRIPTOR_L1_TYPE_INVALID; 
  9.  } 
  10.  
  11.  STATIC INLINE BOOL OsIsPte1Section(PTE_T pte1) 
  12.  { 
  13.      return (pte1 & MMU_DESCRIPTOR_L1_TYPE_MASK) == MMU_DESCRIPTOR_L1_TYPE_SECTION; 
  14.  } 

同樣,下面4個函數用于判斷L2頁表項的類型。

  1. STATIC INLINE BOOL OsIsPte2SmallPage(PTE_T pte2) 
  2.     return (pte2 & MMU_DESCRIPTOR_L2_TYPE_MASK) == MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE; 
  3.  
  4. STATIC INLINE BOOL OsIsPte2SmallPageXN(PTE_T pte2) 
  5.     return (pte2 & MMU_DESCRIPTOR_L2_TYPE_MASK) == MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN; 
  6.  
  7. STATIC INLINE BOOL OsIsPte2LargePage(PTE_T pte2) 
  8.     return (pte2 & MMU_DESCRIPTOR_L2_TYPE_MASK) == MMU_DESCRIPTOR_L2_TYPE_LARGE_PAGE; 
  9.  
  10. STATIC INLINE BOOL OsIsPte2Invalid(PTE_T pte2) 
  11.     return (pte2 & MMU_DESCRIPTOR_L2_TYPE_MASK) == MMU_DESCRIPTOR_L2_TYPE_INVALID; 

1.2.4 OsTruncPte1函數截取物理地址的高12位

下面代碼的宏定義在文件arch\arm\arm\include\los_mmu_descriptor_v6.h中定義。其中MMU_DESCRIPTOR_L1_SMALL_FRAME等于~(0x100000-1)=0xFFF00000即取高12位。所以函數OsTruncPte1截取物理內存地址的高12位。

  1. #define MMU_DESCRIPTOR_L1_SMALL_SIZE                            0x100000 
  2.    #define MMU_DESCRIPTOR_L1_SMALL_MASK                            (MMU_DESCRIPTOR_L1_SMALL_SIZE - 1) 
  3.    #define MMU_DESCRIPTOR_L1_SMALL_FRAME                           (~MMU_DESCRIPTOR_L1_SMALL_MASK) 
  4.    #define MMU_DESCRIPTOR_L1_SMALL_SHIFT                           20 
  5.    #define MMU_DESCRIPTOR_L1_SECTION_ADDR(x)                       ((x) & MMU_DESCRIPTOR_L1_SMALL_FRAME) 
  6.    ...... 
  7.    STATIC INLINE ADDR_T OsTruncPte1(ADDR_T addr) 
  8.    { 
  9.        return MMU_DESCRIPTOR_L1_SECTION_ADDR(addr); 
  10.    } 

1.2.5 L2頁表項連續操作函數

⑴處的函數OsSavePte2設置L2頁表項數據,頁表項指針地址pte2Ptr指向的內存保存的數據寫入頁表項數據pte2。OsSavePte2Continuous函數用于連續設置L2頁表項數據,需要的參數分別有pte2BasePtr頁表基地址,index虛擬地址對應的頁號作為開始索引,頁表項地址pte2和連續的頁表項數量count。⑵處設置頁表項基地址,然后頁表號增加1,頁表項數量減1。⑶處更新頁表項地址,增加的大小為MMU_DESCRIPTOR_L2_SMALL_SIZE,即4KiB大小,然后統計保存成功的數量加1。⑷處的while循環的條件中的MMU_DESCRIPTOR_L2_NUMBERS_PER_L1等于256(即每1MiB對應的L2頁表項的數量)。

函數OsClearPte2Continuous用于清理頁表項基地址。

  1. STATIC INLINE VOID OsSavePte2(PTE_T *pte2Ptr, PTE_T pte2) 
  2.     DMB; 
  3. ⑴  *pte2Ptr = pte2; 
  4.     DSB; 
  5.  
  6. STATIC INLINE UINT32 OsSavePte2Continuous(PTE_T *pte2BasePtr, UINT32 index, PTE_T pte2, UINT32 count
  7.     UINT32 saveCounts = 0; 
  8.     if (count == 0) { 
  9.         return 0; 
  10.     } 
  11.  
  12.     DMB; 
  13.     do { 
  14. ⑵      pte2BasePtr[index++] = pte2; 
  15.         count--; 
  16. ⑶      pte2 += MMU_DESCRIPTOR_L2_SMALL_SIZE; 
  17.         saveCounts++; 
  18. ⑷  } while ((count != 0) && (index != MMU_DESCRIPTOR_L2_NUMBERS_PER_L1)); 
  19.     DSB; 
  20.  
  21.     return saveCounts; 
  22.  
  23. STATIC INLINE VOID OsClearPte2Continuous(PTE_T *pte2Ptr, UINT32 count
  24.     UINT32 index = 0; 
  25.  
  26.     DMB; 
  27.     while (count > 0) { 
  28.         pte2Ptr[index++] = 0; 
  29.         count--; 
  30.     } 
  31.     DSB; 

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2021-12-03 16:22:05

鴻蒙HarmonyOS應用

2021-12-02 15:08:23

鴻蒙HarmonyOS應用

2021-12-03 16:20:26

鴻蒙HarmonyOS應用

2022-03-11 20:23:14

鴻蒙源碼分析進程管理

2022-01-10 15:31:44

鴻蒙HarmonyOS應用

2022-01-12 10:50:23

鴻蒙HarmonyOS應用

2022-04-13 11:02:12

鴻蒙事件模塊事件Event

2022-03-03 18:28:28

Harmony進程任務管理模塊

2021-06-04 09:57:49

鴻蒙HarmonyOS應用

2021-11-05 15:00:33

鴻蒙HarmonyOS應用

2021-05-17 09:28:59

鴻蒙HarmonyOS應用

2021-06-04 14:15:10

鴻蒙HarmonyOS應用

2021-05-08 15:14:50

鴻蒙HarmonyOS應用

2021-11-08 15:06:15

鴻蒙HarmonyOS應用

2021-05-25 09:28:34

鴻蒙HarmonyOS應用

2022-04-13 11:12:43

鴻蒙輕內核信號量模塊操作系統

2021-10-20 16:08:57

鴻蒙HarmonyOS應用

2022-01-14 08:39:47

鴻蒙HarmonyOS應用

2021-05-13 09:47:08

鴻蒙HarmonyOS應用

2021-05-31 20:30:55

鴻蒙HarmonyOS應用
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美 视频 | 91大神在线资源观看无广告 | 农村妇女毛片精品久久久 | 国产一区在线免费 | 亚av在线 | 一区二区三区四区在线 | 国产精品片aa在线观看 | 免费成人av网站 | 台湾佬成人网 | 亚洲精品国产一区 | 一区二区三区高清 | 久久精品国产亚洲一区二区 | 精品国产不卡一区二区三区 | 天天拍天天草 | 亚洲国产激情 | 午夜免费视频 | 国产精品178页| 在线观看av免费 | 涩涩视频在线观看 | 日本小电影在线 | 日韩免费毛片视频 | 手机av免费在线 | 精品欧美 | 一区二区三区欧美大片 | 成人3d动漫一区二区三区91 | 天天综合网天天综合色 | 中文字幕免费在线观看 | 亚洲免费在线 | 综合久久av | 91精品福利| 亚洲成av人影片在线观看 | 男女精品久久 | 伊人伊人 | 亚洲欧美在线观看 | 久久久美女 | 黄色成人免费看 | 亚洲一区二区三区免费视频 | 国产丝袜av | 中文在线a在线 | 久久精品一区 | 狠狠的操|