提交 542126e0 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析

CPU硬件上下文 及其各种寄存器,异常处理函数的注释

鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki
项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.
上级 f2d53dd8
......@@ -6,7 +6,7 @@
# **[kernel\_liteos\_a_note](https://gitee.com/weharmony/kernel_liteos_a_note): 鸿蒙内核源码注释中文版**
[![star](https://gitee.com/weharmony/kernel_liteos_a_note/badge/star.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note/stargazers)[![Fork me on Gitee](https://gitee.com/oschina/git-osc/widgets/widget_3.svg)](https://gitee.com/oschina/git-osc)[![fork](https://gitee.com/weharmony/kernel_liteos_a_note/badge/fork.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note/members)
[![star](https://gitee.com/weharmony/kernel_liteos_a_note/badge/star.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)[![下载源码](https://gitee.com/oschina/git-osc/widgets/widget_3.svg)](https://gitee.com/weharmony/kernel_liteos_a_note)[![fork](https://gitee.com/weharmony/kernel_liteos_a_note/badge/fork.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)
每个码农,职业生涯,都应精读一遍内核源码. 鸿蒙内核源码就是很好的精读项目.一旦熟悉内核代码级实现,将迅速拔高对计算机整体理解,从此高屋建瓴看问题.
......
......@@ -31,30 +31,30 @@
#ifndef _ARCH_CONFIG_H
#define _ARCH_CONFIG_H
//ARM处理器一共有7种工作模式
#include "menuconfig.h"
#define CPSR_INT_DISABLE 0xC0 /* Disable both FIQ and IRQ */
#define CPSR_IRQ_DISABLE 0x80 /* IRQ disabled when =1 */
#define CPSR_FIQ_DISABLE 0x40 /* FIQ disabled when =1 */
#define CPSR_THUMB_ENABLE 0x20 /* Thumb mode when =1 */
#define CPSR_USER_MODE 0x10
#define CPSR_FIQ_MODE 0x11
#define CPSR_IRQ_MODE 0x12
#define CPSR_SVC_MODE 0x13
#define CPSR_ABT_MODE 0x17
#define CPSR_UNDEF_MODE 0x1B
//CPSR为当前程序的状态寄存器
#define CPSR_INT_DISABLE 0xC0 /* Disable both FIQ and IRQ */ //禁止中断
#define CPSR_IRQ_DISABLE 0x80 /* IRQ disabled when =1 */ //只禁止IRQ 中断
#define CPSR_FIQ_DISABLE 0x40 /* FIQ disabled when =1 */ //禁止 FIQ中断
#define CPSR_THUMB_ENABLE 0x20 /* Thumb mode when =1 */ //模式 1:CPU处于Thumb状态, 0:CPU处于ARM状态
#define CPSR_USER_MODE 0x10 //用户模式,除了用户模式,其余模式也叫特权模式,特权模式中除了系统模式以外的其余5种模式称为异常模式;
#define CPSR_FIQ_MODE 0x11 //快中断模式 用于高速数据传输或通道处理
#define CPSR_IRQ_MODE 0x12 //中断模式 用于通用的中断处理
#define CPSR_SVC_MODE 0x13 //管理模式 操作系统使用的保护模式
#define CPSR_ABT_MODE 0x17 //ABT模式 当数据或指令预取终止时进入该模式,用于虚拟存储及存储保护
#define CPSR_UNDEF_MODE 0x1B //未定义模式(其他模式)当未定义的指令执行时进入该模式,用于支持硬件协处理器的软件仿真
#define CPSR_MASK_MODE 0x1F
/* Define exception type ID */
#define OS_EXCEPT_RESET 0x00
#define OS_EXCEPT_UNDEF_INSTR 0x01
#define OS_EXCEPT_SWI 0x02
#define OS_EXCEPT_PREFETCH_ABORT 0x03
#define OS_EXCEPT_DATA_ABORT 0x04
#define OS_EXCEPT_FIQ 0x05
#define OS_EXCEPT_ADDR_ABORT 0x06
#define OS_EXCEPT_IRQ 0x07
/* Define exception type ID */ //ARM处理器一共有7种工作模式,除了用户和系统模式其余都叫异常工作模式
#define OS_EXCEPT_RESET 0x00 //重置功能,例如:开机就进入CPSR_SVC_MODE模式
#define OS_EXCEPT_UNDEF_INSTR 0x01 //未定义的异常,就是others
#define OS_EXCEPT_SWI 0x02 //软件定时器中断
#define OS_EXCEPT_PREFETCH_ABORT 0x03 //预取异常
#define OS_EXCEPT_DATA_ABORT 0x04 //数据异常
#define OS_EXCEPT_FIQ 0x05 //快中断
#define OS_EXCEPT_ADDR_ABORT 0x06 //地址异常
#define OS_EXCEPT_IRQ 0x07 //普通中断
/* Define core num */
#ifdef LOSCFG_KERNEL_SMP
......
......@@ -77,9 +77,9 @@ STATIC UINTPTR g_minAddr;
STATIC UINTPTR g_maxAddr;
STATIC UINT32 g_currHandleExcCpuID = INVALID_CPUID;
VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr);
UINT32 g_curNestCount[LOSCFG_KERNEL_CORE_NUM] = { 0 };
BOOL g_excFromUserMode[LOSCFG_KERNEL_CORE_NUM];
STATIC EXC_PROC_FUNC g_excHook = (EXC_PROC_FUNC)OsExcHook;
UINT32 g_curNestCount[LOSCFG_KERNEL_CORE_NUM] = { 0 };//
BOOL g_excFromUserMode[LOSCFG_KERNEL_CORE_NUM];//记录CPU core 是否在用户态运行
STATIC EXC_PROC_FUNC g_excHook = (EXC_PROC_FUNC)OsExcHook;//函数指针 ->hook
#if (LOSCFG_KERNEL_SMP == YES)
STATIC SPIN_LOCK_INIT(g_excSerializerSpin);
STATIC UINT32 g_currHandleExcPID = OS_INVALID_VALUE;
......@@ -254,11 +254,11 @@ STATIC const CHAR *g_excTypeString[] = {
"address abort",
"irq"
};
//打印系统信息
STATIC VOID OsExcSysInfo(UINT32 excType, const ExcContext *excBufAddr)
{
LosTaskCB *runTask = OsCurrTaskGet();
LosProcessCB *runProcess = OsCurrProcessGet();
LosTaskCB *runTask = OsCurrTaskGet();//获取当前任务
LosProcessCB *runProcess = OsCurrProcessGet();//获取当前进程
LosVmMapRegion *region = NULL;
PrintExcInfo("excType: %s\n"
......@@ -284,30 +284,30 @@ STATIC VOID OsExcSysInfo(UINT32 excType, const ExcContext *excBufAddr)
}
PrintExcInfo("pc = 0x%x ", excBufAddr->PC);
if (g_excFromUserMode[ArchCurrCpuid()] == TRUE) {
if (LOS_IsUserAddress((vaddr_t)excBufAddr->PC)) {
region = LOS_RegionFind(runProcess->vmSpace, (VADDR_T)excBufAddr->PC);
if (g_excFromUserMode[ArchCurrCpuid()] == TRUE) {//当前CPU处于用户模式
if (LOS_IsUserAddress((vaddr_t)excBufAddr->PC)) {//pc寄存器处于用户空间
region = LOS_RegionFind(runProcess->vmSpace, (VADDR_T)excBufAddr->PC);//找到所在线性区
if (region != NULL) {
PrintExcInfo("in %s ---> 0x%x", OsGetRegionNameOrFilePath(region),
(VADDR_T)excBufAddr->PC - region->range.base);
PrintExcInfo("in %s ---> 0x%x", OsGetRegionNameOrFilePath(region),//获取线性区标识
(VADDR_T)excBufAddr->PC - region->range.base);//得到线性区的偏移地址
}
}
PrintExcInfo("\nulr = 0x%x ", excBufAddr->ULR);
region = LOS_RegionFind(runProcess->vmSpace, (VADDR_T)excBufAddr->ULR);
PrintExcInfo("\nulr = 0x%x ", excBufAddr->ULR);//打印用户模式下程序的返回地址
region = LOS_RegionFind(runProcess->vmSpace, (VADDR_T)excBufAddr->ULR);//通过返回地址找到线性区
if (region != NULL) {
PrintExcInfo("in %s ---> 0x%x", OsGetRegionNameOrFilePath(region),
(VADDR_T)excBufAddr->ULR - region->range.base);
PrintExcInfo("in %s ---> 0x%x", OsGetRegionNameOrFilePath(region),//获取线性区标识
(VADDR_T)excBufAddr->ULR - region->range.base);//得到线性区的偏移地址
}
PrintExcInfo("\nusp = 0x%x", excBufAddr->USP);
} else {
PrintExcInfo("\nklr = 0x%x\n"
"ksp = 0x%x\n",
excBufAddr->LR,
excBufAddr->SP);
PrintExcInfo("\nusp = 0x%x", excBufAddr->USP);//打印用户模式下栈指针
} else {//非用户模式下
PrintExcInfo("\nklr = 0x%x\n" //注意:只有一个内核空间和内核堆空间,而每个用户进程就有自己独立的用户空间。
"ksp = 0x%x\n", //用户空间的虚拟地址范围是一样的,只是映射到不同的物理内存页。
excBufAddr->LR, //直接打印程序的返回地址
excBufAddr->SP); //直接打印栈空间
}
PrintExcInfo("fp = 0x%x\n", excBufAddr->R11);
PrintExcInfo("fp = 0x%x\n", excBufAddr->R11);//FP(frame pointer)栈帧寄存器R11
}
STATIC VOID OsExcRegsInfo(const ExcContext *excBufAddr)
......@@ -335,7 +335,7 @@ STATIC VOID OsExcRegsInfo(const ExcContext *excBufAddr)
excBufAddr->R7, excBufAddr->R8, excBufAddr->R9, excBufAddr->R10,
excBufAddr->R11, excBufAddr->R12, excBufAddr->regCPSR);
}
//注册hook
LITE_OS_SEC_TEXT_INIT UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook)
{
UINT32 intSave;
......@@ -346,7 +346,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook)
return LOS_OK;
}
//获取hook函数
EXC_PROC_FUNC OsExcRegHookGet(VOID)
{
return g_excHook;
......@@ -550,7 +550,7 @@ STATIC INLINE BOOL IsValidFP(UINTPTR regFP, UINTPTR start, UINTPTR end, vaddr_t
return TRUE;
}
//找到一个合适的栈
STATIC INLINE BOOL FindSuitableStack(UINTPTR regFP, UINTPTR *start, UINTPTR *end, vaddr_t *vaddr)
{
UINT32 index, stackStart, stackEnd;
......@@ -668,7 +668,7 @@ VOID OsExcInit(VOID)
{
OsExcStackInfoReg(g_excStack, sizeof(g_excStack) / sizeof(g_excStack[0]));
}
//由注册后回调
VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr)
{
OsExcType(excType, excBufAddr, far, fsr);
......@@ -755,7 +755,7 @@ VOID OsBackTrace(VOID)
PRINTK("runTask->taskID = %u\n", runTask->taskID);
BackTrace(regFP);
}
//未定义的异常处理函数,由汇编调用 见于 los_hw_exc.s
#ifdef LOSCFG_GDB
VOID OsUndefIncExcHandleEntry(ExcContext *excBufAddr)
{
......@@ -771,7 +771,7 @@ VOID OsUndefIncExcHandleEntry(ExcContext *excBufAddr)
}
while (1) {}
}
//预取异常处理函数,由汇编调用 见于 los_hw_exc.s
#if __LINUX_ARM_ARCH__ >= 7
VOID OsPrefetchAbortExcHandleEntry(ExcContext *excBufAddr)
{
......@@ -791,7 +791,7 @@ VOID OsPrefetchAbortExcHandleEntry(ExcContext *excBufAddr)
}
while (1) {}
}
//数据中止异常处理函数,由汇编调用 见于 los_hw_exc.s
VOID OsDataAbortExcHandleEntry(ExcContext *excBufAddr)
{
UINT32 far;
......@@ -816,7 +816,7 @@ VOID OsDataAbortExcHandleEntry(ExcContext *excBufAddr)
#if (LOSCFG_KERNEL_SMP == YES)
#define EXC_WAIT_INTER 50U
#define EXC_WAIT_TIME 2000U
//打印所有CPU的状态信息
STATIC VOID OsAllCpuStatusOutput(VOID)
{
UINT32 i;
......@@ -937,33 +937,33 @@ STATIC VOID OsCheckCpuStatus(UINTPTR taskStackPointer)
g_currHandleExcCpuID = ArchCurrCpuid();
#endif
}
//执行期间的优先处置 excBufAddr为CPU硬件上下文,
LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr)
{
#if (LOSCFG_KERNEL_SMP == YES)
UINT16 runCount;
#endif
if ((excBufAddr->regCPSR & CPSR_MASK_MODE) == CPSR_USER_MODE) {
g_minAddr = USER_ASPACE_BASE;
g_maxAddr = USER_ASPACE_BASE + USER_ASPACE_SIZE;
g_excFromUserMode[ArchCurrCpuid()] = TRUE;
if ((excBufAddr->regCPSR & CPSR_MASK_MODE) == CPSR_USER_MODE) {//用户模式下,访问地址不能出用户空间
g_minAddr = USER_ASPACE_BASE; //可访问地址范围的开始地址,
g_maxAddr = USER_ASPACE_BASE + USER_ASPACE_SIZE;//地址范围的结束地址,就是用户空间
g_excFromUserMode[ArchCurrCpuid()] = TRUE;//当前CPU执行切到用户态
} else {
g_minAddr = KERNEL_ASPACE_BASE;
g_maxAddr = KERNEL_ASPACE_BASE + KERNEL_ASPACE_SIZE;
g_excFromUserMode[ArchCurrCpuid()] = FALSE;
g_minAddr = KERNEL_ASPACE_BASE; //可访问地址范围的开始地址
g_maxAddr = KERNEL_ASPACE_BASE + KERNEL_ASPACE_SIZE;//可访问地址范围的结束地址
g_excFromUserMode[ArchCurrCpuid()] = FALSE;//当前CPU执行切到内核态
}
OsCheckCpuStatus(excBufAddr->SP);
OsCheckCpuStatus(excBufAddr->SP);//检查CPU的状态
if (g_excFromUserMode[ArchCurrCpuid()] == TRUE) {
if (g_excFromUserMode[ArchCurrCpuid()] == TRUE) {//为用户态时
while (1) {
OsProcessSuspendAllTask();
#if (LOSCFG_KERNEL_SMP == YES)
OsProcessSuspendAllTask();//当前进程的所有任务挂起
#if (LOSCFG_KERNEL_SMP == YES)//多核情况下的处理
LOS_SpinLock(&g_taskSpin);
runCount = OS_PROCESS_GET_RUNTASK_COUNT(OsCurrProcessGet()->processStatus);
runCount = OS_PROCESS_GET_RUNTASK_COUNT(OsCurrProcessGet()->processStatus);//获取正在运行的task数量,也就是并行数量
LOS_SpinUnlock(&g_taskSpin);
if (runCount == 1) {
if (runCount == 1) {//直接跑到只剩下一个当前任务为止,其实就在等其他核的runtask跑完
break;
}
#else
......@@ -977,11 +977,11 @@ LITE_OS_SEC_TEXT VOID STATIC OsExcPriorDisposal(ExcContext *excBufAddr)
* Description : EXC handler entry
* Input : excType --- exc type
* excBufAddr --- address of EXC buf
*/
*///异常处理的执行入口,由汇编语言层调用 见于 los_hw_exc.s 文件
LITE_OS_SEC_TEXT_INIT VOID OsExcHandleEntry(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr)
{
/* Task scheduling is not allowed during exception handling */
OsPercpuGet()->taskLockCnt++;
/* Task scheduling is not allowed during exception handling *///异常处理期间不允许任务调度
OsPercpuGet()->taskLockCnt++;//
g_curNestCount[ArchCurrCpuid()]++;
......
......@@ -35,9 +35,9 @@
.extern g_losTask
.extern g_intCount
.extern g_curNestCount
.extern OsExcHandleEntry
.extern __svc_stack_top
.extern __exc_stack_top
.extern OsExcHandleEntry @异常处理入口
.extern __svc_stack_top @管理栈顶位置 操作系统使用的保护模式
.extern __exc_stack_top @任务栈顶位置
.extern __stack_chk_guard
.extern OsRandomStackGuard
#ifdef LOSCFG_GDB
......@@ -375,7 +375,7 @@ _osExceptionSwi:
LDR R4, [R3]
CMP R4, #0
BNE _osExceptionGetSP
BNE _osExceptionGetSP @ BNE: 不相等则跳转
LDR R3, =g_intCount @ Judge the exception is occur in task stack or system stack
ADD R3, R3, R2
......@@ -392,7 +392,7 @@ _osExceptionGetSP:
MOV R2, R8 @ far
MOV R3, R9 @ fsr
LDR R5, =OsExcHandleEntry @ OsExcHandleEntry(UINT32 excType, ExcContext * excBufAddr)
BX R5
BX R5 @LDR为加载指令把OsExcHandleEntry加载到R5寄存器,BX为带分支的跳转指令,再跳到R5执行
_OsExcReturn:
LDR R0, [SP, #(2 * 4)]
......
......@@ -52,7 +52,7 @@ extern "C" {
* Description: register information stored when an exception occurs on an LPC2458 platform.
*
* Note: The following register names without uw are the register names used in the chip manual.
*/
*///以下不带uw的寄存器名是芯片手册中使用的寄存器名
#ifdef LOSCFG_ARCH_ARM_AARCH64
#define EXC_GEN_REGS_NUM 30
typedef struct {
......@@ -64,9 +64,9 @@ typedef struct {
} ExcContext;
#else
typedef struct {
UINT32 USP; /**< User mode stack pointer */
UINT32 ULR; /**< User mode program returning address */
UINT32 regCPSR; /**< Current program status register (CPSR) */
UINT32 USP; /**< User mode stack pointer *///用户模式下栈指针
UINT32 ULR; /**< User mode program returning address *///用户模式下程序返回地址
UINT32 regCPSR; /**< Current program status register (CPSR) *///当前程序状态寄存器
UINT32 R0; /**< Register R0 */
UINT32 R1; /**< Register R1 */
UINT32 R2; /**< Register R2 */
......@@ -94,11 +94,11 @@ typedef struct {
*
*/
typedef struct {
UINT16 phase; /**< Phase in which an exception occurs */
UINT16 type; /**< Exception type */
UINT16 nestCnt; /**< Count of nested exception */
UINT16 phase; /**< Phase in which an exception occurs *///异常发生的阶段
UINT16 type; /**< Exception type *///异常类型
UINT16 nestCnt; /**< Count of nested exception *///嵌套异常计数
UINT16 reserved; /**< Reserved for alignment */
ExcContext *context; /**< Hardware context when an exception occurs */
ExcContext *context; /**< Hardware context when an exception occurs *///异常发生时的硬件上下文
} ExcInfo;
/**
......
......@@ -594,11 +594,11 @@ LITE_OS_SEC_TEXT UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
return LOS_OK;
#endif
}
//任务同步唤醒
STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB)
{
#if (LOSCFG_KERNEL_SMP_TASK_SYNC == YES)
(VOID)OsSemPostUnsafe(taskCB->syncSignal, NULL);
(VOID)OsSemPostUnsafe(taskCB->syncSignal, NULL);//唤醒一个挂在信号量链表上的阻塞任务
#else
(VOID)taskCB;
#endif
......@@ -617,19 +617,19 @@ STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack)
#endif
(VOID)LOS_MemFree(poolTmp, (VOID *)topOfStack);
}
//从回收链表中回收任务到空闲链表
LITE_OS_SEC_TEXT VOID OsTaskCBRecyleToFree()
{
LosTaskCB *taskCB = NULL;
UINT32 intSave;
SCHEDULER_LOCK(intSave);
while (!LOS_ListEmpty(&g_taskRecyleList)) {
taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecyleList));
LOS_ListDelete(&taskCB->pendList);
while (!LOS_ListEmpty(&g_taskRecyleList)) {//不空就一个一个回收任务
taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecyleList));//取出第一个待回收任务
LOS_ListDelete(&taskCB->pendList);//从回收链表上将自己摘除
SCHEDULER_UNLOCK(intSave);
OsTaskResourcesToFree(taskCB);
OsTaskResourcesToFree(taskCB);//释放任务资源
SCHEDULER_LOCK(intSave);
}
......@@ -638,16 +638,16 @@ LITE_OS_SEC_TEXT VOID OsTaskCBRecyleToFree()
LITE_OS_SEC_TEXT VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
{
LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);
LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);//通过任务找到所属进程
UINT32 syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT;
UINT32 mapSize, intSave;
UINTPTR mapBase, topOfStack;
UINT32 ret;
if (OsProcessIsUserMode(processCB) && (taskCB->userMapBase != 0)) {
if (OsProcessIsUserMode(processCB) && (taskCB->userMapBase != 0)) {//进程在用户态而且任务栈不为空
SCHEDULER_LOCK(intSave);
mapBase = (UINTPTR)taskCB->userMapBase;
mapSize = taskCB->userMapSize;
mapBase = (UINTPTR)taskCB->userMapBase;//先保存任务栈底位置
mapSize = taskCB->userMapSize;//先保存任务栈大小
taskCB->userMapBase = 0;
taskCB->userArea = 0;
SCHEDULER_UNLOCK(intSave);
......@@ -1761,7 +1761,7 @@ LITE_OS_SEC_TEXT VOID OsExecDestroyTaskGroup(VOID)
OsTaskExitGroup(OS_PRO_EXIT_OK);
OsTaskCBRecyleToFree();
}
//暂停进程的所有任务
//暂停当前进程的所有任务
LITE_OS_SEC_TEXT VOID OsProcessSuspendAllTask(VOID)
{
LosProcessCB *process = NULL;
......
......@@ -294,23 +294,23 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
#define OS_TCB_NAME_LEN 32
typedef struct {
VOID *stackPointer; /**< Task stack pointer */
UINT16 taskStatus; /**< Task status */
UINT16 priority; /**< Task priority */
VOID *stackPointer; /**< Task stack pointer */ //非用户模式下的栈指针
UINT16 taskStatus; /**< Task status */ //各种状态标签,可以拥有多种标签,按位标识
UINT16 priority; /**< Task priority */ //任务优先级[0:31],默认是31级
UINT16 policy; //任务的调度方式(三种 .. LOS_SCHED_RR )
UINT16 timeSlice; /**< Remaining time slice */
UINT32 stackSize; /**< Task stack size */
UINTPTR topOfStack; /**< Task stack top */
UINT16 timeSlice; /**< Remaining time slice *///剩余时间片
UINT32 stackSize; /**< Task stack size */ //非用户模式下栈大小
UINTPTR topOfStack; /**< Task stack top */ //非用户模式下的栈顶
UINT32 taskID; /**< Task ID */
TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */
TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */ //任务执行入口函数
VOID *joinRetval; /**< pthread adaption */
VOID *taskSem; /**< Task-held semaphore */
VOID *taskMux; /**< Task-held mutex *///task在等哪把锁
VOID *taskEvent; /**< Task-held event */
UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 */
VOID *taskSem; /**< Task-held semaphore */ //task在等哪个信号量
VOID *taskMux; /**< Task-held mutex */ //task在等哪把锁
VOID *taskEvent; /**< Task-held event */ //task在等哪个事件
UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 */ //入口函数的参数 例如 main (int argc,char *argv[])
CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */
LOS_DL_LIST pendList; /**< Task pend node *///如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时
LOS_DL_LIST threadList; /**< thread list */
LOS_DL_LIST pendList; /**< Task pend node */ //如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时
LOS_DL_LIST threadList; /**< thread list */
SortLinkList sortList; /**< Task sortlink node */
UINT32 eventMask; /**< Event mask */
UINT32 eventMode; /**< Event mode */
......@@ -335,7 +335,7 @@ typedef struct {
#endif
#endif
UINTPTR userArea; //使用区域,由运行时划定,根据运行态不同而不同
UINTPTR userMapBase; //使用区栈底位置
UINTPTR userMapBase; //用户模式下的栈底位置
UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */
UINT32 processID; /**< Which belong process */
FutexNode futex;
......
......@@ -139,7 +139,7 @@ STATIC INLINE VOID OsVmPhysFreeListInit(struct VmPhysSeg *seg)
LOS_SpinLockSave(&seg->freeListLock, &intSave);
for (i = 0; i < VM_LIST_ORDER_MAX; i++) {
list = &seg->freeList[i];
LOS_ListInit(&list->node);//初始化9个链表 2|0,2|1,2|2 分配页框 |代表次方的意思
LOS_ListInit(&list->node);//初始化9个链表 2^0,2^1,2^2 分配页框 ^代表次方的意思
list->listCnt = 0;
}
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
......@@ -322,12 +322,12 @@ VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order)
if (order < VM_LIST_ORDER_MAX - 1) {//order[0,7]
pa = VM_PAGE_TO_PHYS(page);//获取物理地址
do {
pa ^= VM_ORDER_TO_PHYS(order);//注意这里是高位和低位的^=,也就是说跳到 order块组 物理地址处,此处处理甚妙!
buddyPage = OsVmPhysToPage(pa, page->segID);//如此就能拿到以2order次方跳的buddyPage
pa ^= VM_ORDER_TO_PHYS(order);//注意这里是高位和低位的 ^= ,也就是说跳到 order块组 物理地址处,此处处理甚妙!
buddyPage = OsVmPhysToPage(pa, page->segID);//如此就能拿到以2^order次方跳的buddyPage
if ((buddyPage == NULL) || (buddyPage->order != order)) {
break;
}
OsVmPhysFreeListDel(buddyPage);//注意buddypage是连续的物理页框 例如order=2时,连续的4页就是一个块组 |_|_|_|_|
OsVmPhysFreeListDel(buddyPage);//注意buddypage是连续的物理页框 例如order=2时,2^2=4页就是一个块组 |_|_|_|_|
order++;
pa &= ~(VM_ORDER_TO_PHYS(order) - 1);
page = OsVmPhysToPage(pa, page->segID);
......@@ -355,10 +355,10 @@ VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages)
nPages -= n;//总页数减少
page += n;//释放的页数增多
}
//举例省下 7个页框时,依次用 4 2 1 方式释放
//举例剩下 7个页框时,依次用 2^2 2^1 2^0 方式释放
for (count = 0; count < nPages; count += n) {
order = LOS_HighBitGet(nPages);//从高到低块组释放
n = VM_ORDER_TO_PAGES(order);//2order次方
n = VM_ORDER_TO_PAGES(order);//2^order次方
OsVmPhysPagesFree(page, order);//释放块组
page += n;
}
......@@ -398,7 +398,7 @@ VOID *LOS_PhysPagesAllocContiguous(size_t nPages)
if (nPages == 0) {
return NULL;
}
//鸿蒙 nPages 不能大于 28 次方,即256个页,1M内存,仅限于内核态,用户态不限制分配大小.
//鸿蒙 nPages 不能大于 2^8 次方,即256个页,1M内存,仅限于内核态,用户态不限制分配大小.
page = OsVmPhysPagesGet(nPages);//通过伙伴算法获取物理上连续的页
if (page == NULL) {
return NULL;
......
git add -A
git commit -m '开始对信号量这块代码进行注释,信号量的出现为了解决task的同步问题
git commit -m 'CPU硬件上下文 及其各种寄存器,异常处理函数的注释
鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki
给鸿蒙内核源码逐行加上中文注解,详细阐述设计细节, 助你快速精读 HarmonyOS 内核源码, 掌握整个鸿蒙内核运行机制.'
项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.'
git push origin
git push gitee_origin master
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册