摘要:本文介紹了OpenHarmony鴻蒙輕內核LiteOS-A的虛擬地址空間編號知識,詳細分析進程空間編號的申請與釋放操作。

?

本文分享自華為云社區??《鴻蒙輕內核A核源碼分析系列四 (1) 虛擬內存進程空間編號》??,作者: zhushy 。

?

在熟悉下OpenHarmony鴻蒙輕內核提供的虛擬內存(Virtual memory)管理模塊之前,作為預備基礎知識,我們先了解下虛擬內存進程空間編號,進程空間編號功能相對獨立,源代碼文件多帶帶維護。涉及的頭文件和C源代碼文件分別為arch/arm/arm/include/los_asid.h和arch/arm/arm/src/los_asid.c。本文先介紹OpenHarmony鴻蒙輕內核LiteOS-A的虛擬地址空間編號知識,然后詳細分析進程空間編號的申請與釋放操作。

1. 地址空間編號數組

虛擬內存地址空間編號取值范圍為[0,255],256個編號對應8位數值。為了記錄256個進程地址空間編號的使用狀態需要256個比特位來維護。下述代碼中位圖字數BITMAP_NUM_WORDS(1UL<< MMU_ARM_ASID_BITS)等于8,即地址空間編號數組的大小為8,每個位圖字32位,正好對應256個比特位。


#define MMU_ARM_ASID_BITS           8
......
STATIC UINTPTR g_asidPool[BITMAP_NUM_WORDS(1UL << MMU_ARM_ASID_BITS)];

2. 函數OsAllocAsid()

函數OsAllocAsid()用于分配一個地址空間編號,輸出參數UINT32*asid記錄獲取的地址空間編號,獲取失敗時返回值為-1;獲取地址空間編號成功時返回LOS_OK。⑴處語句獲取g_asidPool數組元素中二進制位數值從左到右第一處為0的位數。⑵處如果獲取的位數大于等于0,小于256,沒有越界,說明獲取地址空間編號成功。執行⑶把該bit位設置為1,標記為已使用。⑷處設置獲取的地址空間編號。


status_t OsAllocAsid(UINT32 *asid)
{
UINT32 flags;
LOS_SpinLockSave(&g_cpuAsidLock, &flags);
⑴ UINT32 firstZeroBit = LOS_BitmapFfz(g_asidPool, 1UL << MMU_ARM_ASID_BITS);
⑵ if (firstZeroBit >= 0 && firstZeroBit < (1UL << MMU_ARM_ASID_BITS)) {
⑶ LOS_BitmapSetNBits(g_asidPool, firstZeroBit, 1);
⑷ *asid = firstZeroBit;
LOS_SpinUnlockRestore(&g_cpuAsidLock, flags);
return LOS_OK;
}

LOS_SpinUnlockRestore(&g_cpuAsidLock, flags);
return firstZeroBit;
}

3. 函數OsFreeAsid

函數OsFreeAsid釋放地址空間編號,代碼比較簡單調用LOS_BitmapClrNBits()把地址編號所在的bit位清0即可。


VOID OsFreeAsid(UINT32 asid)
{
UINT32 flags;
LOS_SpinLockSave(&g_cpuAsidLock, &flags);
LOS_BitmapClrNBits(g_asidPool, asid, 1);
LOS_SpinUnlockRestore(&g_cpuAsidLock, flags);
}

4.總結

本文首先介紹了OpenHarmony鴻蒙輕內核LiteOS-A的虛擬地址空間編號知識,然后詳細分析進程空間編號的申請與釋放操作。


??點擊關注,第一時間了解華為云新鮮技術~??