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

?

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

?

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

1. 地址空間編號數(shù)組

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


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

2. 函數(shù)OsAllocAsid()

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


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. 函數(shù)OsFreeAsid

函數(shù)OsFreeAsid釋放地址空間編號,代碼比較簡單調(diào)用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.總結(jié)

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


??點擊關(guān)注,第一時間了解華為云新鮮技術(shù)~??