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

注释内核出现异常时鸿蒙是如何处理的

搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
上级 fd5f1cfa
......@@ -42,7 +42,7 @@ extern "C" {
STATIC INLINE VOID OsSetCurrCpuSp(UINTPTR regSp)
{
__asm__ __volatile__("mov sp, %0" :: "r"(regSp));
__asm__ __volatile__("mov sp, %0" :: "r"(regSp));//将参数设为 sp寄存器的值
}
#define OS_SYSTEM_NORMAL 0 //当前CPU都处于空闲状态
......
......@@ -105,13 +105,13 @@ STATIC UINT32 g_nextExcWaitCpu = INVALID_CPUID;
((ptr) <= g_maxAddr) && \
(IS_ALIGNED((ptr), sizeof(CHAR *))))
STATIC const StackInfo g_excStack[] = {// 6个执行栈
STATIC const StackInfo g_excStack[] = {// 6种异常情况下对应的栈
{ &__undef_stack, OS_EXC_UNDEF_STACK_SIZE, "udf_stack" }, //512 未定义的指令模式堆栈
{ &__abt_stack, OS_EXC_ABT_STACK_SIZE, "abt_stack" }, //512 中止模式堆栈,用于数据中止,可以将处理程序设置为在触发异常终止时运行
{ &__fiq_stack, OS_EXC_FIQ_STACK_SIZE, "fiq_stack" }, //64 FIQ中断模式堆栈.快速中断(FIQ)可能会在IRQ期间发生-它们就像优先级较高的IRQ.在FIQ中,FIQ和IRQ被禁用.
{ &__svc_stack, OS_EXC_SVC_STACK_SIZE, "svc_stack" }, //8K 主管模式堆栈.有些指令只能在SVC模式下运行
{ &__irq_stack, OS_EXC_IRQ_STACK_SIZE, "irq_stack" }, //64 中断(IRQ)模式堆栈.
{ &__exc_stack, OS_EXC_STACK_SIZE, "exc_stack" } //4K 用户和系统模式堆栈.大多数情况下,这是你用于执行代码的常规堆栈
{ &__exc_stack, OS_EXC_STACK_SIZE, "exc_stack" } //4K 异常处理堆栈
};
//获取系统状态
UINT32 OsGetSystemStatus(VOID)
......@@ -235,24 +235,24 @@ STATIC VOID OsExcType(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32
}
}
if (excType == OS_EXCEPT_PREFETCH_ABORT) {
if (excType == OS_EXCEPT_PREFETCH_ABORT) {//取指异常
PrintExcInfo("prefetch_abort fault fsr:0x%x, far:0x%0+8x\n", fsr, far);
(VOID)OsDecodeInstructionFSR(fsr);
} else if (excType == OS_EXCEPT_DATA_ABORT) {
} else if (excType == OS_EXCEPT_DATA_ABORT) {//数据异常
PrintExcInfo("data_abort fsr:0x%x, far:0x%0+8x\n", fsr, far);
(VOID)OsDecodeDataFSR(fsr);
}
}
STATIC const CHAR *g_excTypeString[] = {
"reset",
"undefined instruction",
"software interrupt",
"prefetch abort",
"data abort",
"fiq",
"address abort",
"irq"
STATIC const CHAR *g_excTypeString[] = {//异常类型的字符说明,在鸿蒙内核中什么才算是异常? 看这里
"reset", //重置命令
"undefined instruction", //未定义的指令
"software interrupt", //软中断,比如定时器
"prefetch abort", //取指异常
"data abort", //数据异常
"fiq", //快中断异常
"address abort", //地址异常
"irq" //中断异常
};
//打印系统信息
STATIC VOID OsExcSysInfo(UINT32 excType, const ExcContext *excBufAddr)
......@@ -459,28 +459,28 @@ VOID OsDumpContextMem(const ExcContext *excBufAddr)
OsDumpMemByte(DUMPSIZE, (excBufAddr->SP - (DUMPSIZE >> 1)));
}
}
//异常恢复,继续执行
STATIC VOID OsExcRestore(UINTPTR taskStackPointer)
{
UINT32 currCpuID = ArchCurrCpuid();
UINT32 currCpuID = ArchCurrCpuid(); //获取当前CPU ID
g_excFromUserMode[currCpuID] = FALSE;
g_intCount[currCpuID] = 0;
g_excFromUserMode[currCpuID] = FALSE; //CPU内核态运行
g_intCount[currCpuID] = 0; //CPU对应的中断数量清0
g_curNestCount[currCpuID] = 0;
#if (LOSCFG_KERNEL_SMP == YES)
OsPercpuGet()->excFlag = CPU_RUNNING;
#endif
OsPercpuGet()->taskLockCnt = 0;
OsSetCurrCpuSp(taskStackPointer);
OsSetCurrCpuSp(taskStackPointer);//汇编设置当前CPU sp寄存器值
}
//用户态异常处理函数
STATIC VOID OsUserExcHandle(ExcContext *excBufAddr)
{
UINT32 currCpu = ArchCurrCpuid();
LosProcessCB *runProcess = OsCurrProcessGet();
if (g_excFromUserMode[ArchCurrCpuid()] == FALSE) {
if (g_excFromUserMode[ArchCurrCpuid()] == FALSE) {//内核态直接退出,8处理了.
return;
}
......@@ -497,9 +497,9 @@ STATIC VOID OsUserExcHandle(ExcContext *excBufAddr)
#else
g_currHandleExcCpuID = INVALID_CPUID;
#endif
runProcess->processStatus &= ~OS_PROCESS_FLAG_EXIT;
runProcess->processStatus &= ~OS_PROCESS_FLAG_EXIT; //进程去掉退出标签,要接着执行
OsExcRestore(excBufAddr->SP);
OsExcRestore(excBufAddr->SP); //通过sp恢复
#if (LOSCFG_KERNEL_SMP == YES)
#ifdef LOSCFG_FS_VFS
......@@ -514,7 +514,7 @@ STATIC VOID OsUserExcHandle(ExcContext *excBufAddr)
/* kill user exc process */
LOS_Exit(OS_PRO_EXIT_OK);
/* User mode exception handling failed , which normally does not exist */
/* User mode exception handling failed , which normally does not exist */ //用户态的异常处理失败,通常情况下不会发生
g_curNestCount[currCpu]++;
g_intCount[currCpu]++;
PrintExcInfo("User mode exception ends unscheduled!\n");
......@@ -665,7 +665,7 @@ VOID BackTrace(UINT32 regFP)//fp:R11寄存器
BackTraceSub(regFP);
}
//异常初始化
//异常处理模块的初始化
VOID OsExcInit(VOID)
{
OsExcStackInfoReg(g_excStack, sizeof(g_excStack) / sizeof(g_excStack[0]));//异常模式下注册内核栈信息
......@@ -686,20 +686,20 @@ VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr, UINT32 far, UINT32 fsr)
#endif
OsDumpProcessUsedMemNode(OS_EXC_VMM_NO_REGION);
OsExcStackInfo();
OsExcStackInfo();// 打印任务栈的信息
#ifndef LOSCFG_DEBUG_VERSION
}
#endif
OsDumpContextMem(excBufAddr);
OsDumpContextMem(excBufAddr);// 打印上下文
(VOID)OsShellCmdMemCheck(0, NULL);//检查内存
(VOID)OsShellCmdMemCheck(0, NULL);//检查内存,相当于执行 shell memcheck 命令
#ifdef LOSCFG_COREDUMP
LOS_CoreDumpV2(excType, excBufAddr);
#endif
OsUserExcHandle(excBufAddr);
OsUserExcHandle(excBufAddr);//用户态下异常的处理
}
//打印调用栈信息
VOID OsCallStackInfo(VOID)
......@@ -792,8 +792,8 @@ VOID OsPrefetchAbortExcHandleEntry(ExcContext *excBufAddr)
}
if (g_excHook != NULL) {
far = OsArmReadIfar();
fsr = OsArmReadIfsr();
far = OsArmReadIfar();//far 为CP15的 C6寄存器 详见:https://blog.csdn.net/kuangyufei/article/details/108994081
fsr = OsArmReadIfsr();//fsr 为CP15的 C5寄存器
g_excHook(OS_EXCEPT_PREFETCH_ABORT, excBufAddr, far, fsr);//回调函数,详见: OsExcHook
}
while (1) {}
......@@ -886,7 +886,7 @@ STATIC VOID OsWaitOtherCoresHandleExcEnd(UINT32 currCpuID)
LOS_Mdelay(EXC_WAIT_INTER);
}
}
//检查所以CPU的状态
STATIC VOID OsCheckAllCpuStatus(UINTPTR taskStackPointer)
{
UINT32 currCpuID = ArchCurrCpuid();
......@@ -902,9 +902,9 @@ STATIC VOID OsCheckAllCpuStatus(UINTPTR taskStackPointer)
LOS_SpinUnlock(&g_excSerializerSpin);
if (g_excFromUserMode[currCpuID] == FALSE) {
target = (UINT32)(OS_MP_CPU_ALL & ~CPUID_TO_AFFI_MASK(currCpuID));
HalIrqSendIpi(target, LOS_MP_IPI_HALT);
HalIrqSendIpi(target, LOS_MP_IPI_HALT);//向目标CPU发送停止消息
}
} else if (g_excFromUserMode[currCpuID] == TRUE) {
} else if (g_excFromUserMode[currCpuID] == TRUE) {//当前运行在用户态
if (OsCurrProcessGet()->processID == g_currHandleExcPID) {
LOS_SpinUnlock(&g_excSerializerSpin);
OsExcRestore(taskStackPointer);
......
......@@ -71,7 +71,7 @@ struct LosHeapNode* OsHeapPrvGetNext(struct LosHeapManager *heapMan, struct LosH
* UITN32 size --- size of the heap memory pool
* Return : 1:success 0:error
*/
BOOL OsHeapInit(VOID *pool, UINT32 size)
BOOL OsHeapInit(VOID *pool, UINT32 size)//堆的初始化
{
struct LosHeapNode *node = NULL;
struct LosHeapManager *heapMan = HEAP_CAST(struct LosHeapManager *, pool);
......
......@@ -57,7 +57,7 @@ UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop,
return LOS_NOK;
}
}
//执行栈检查,主要就是检查栈顶值有没有被改写
//异常情况下的栈检查,主要就是检查栈顶值有没有被改写
VOID OsExcStackCheck(VOID)
{
UINT32 index;
......@@ -103,7 +103,7 @@ VOID OsExcStackInfo(VOID)
}
}
OsExcStackCheck();
OsExcStackCheck();//发生异常时栈检查
}
/*************************************************************************************** @note_pic
OsExcStackInfo 各个CPU栈布局图,其他栈也是一样,CPU各核硬件栈都是紧挨着
......
......@@ -128,7 +128,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemCheck(INT32 argc, const CHAR *argv[])
WriteExcInfoToBuf("system memcheck over, all passed!\n");
#endif
}
#ifdef LOSCFG_EXC_INTERACTION
#ifdef LOSCFG_EXC_INTERACTION
if (LOS_MemIntegrityCheck(m_aucSysMem0) == LOS_OK) {
PRINTK("exc interaction memcheck over, all passed!\n");
#ifdef LOSCFG_SHELL_EXCINFO
......@@ -188,7 +188,6 @@ DONE:
bss 表示未初始化全局变量占用内存大小。
*********************************************************/
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdSectionInfo(INT32 argc, const CHAR *argv[])
{
size_t textLen = &__text_end - &__text_start;
......@@ -268,8 +267,23 @@ LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OsShellCmdFreeInfo(INT32 argc, const CHAR *
}
return 0;
}
//free命令可显示系统内存的使用情况,同时显示系统的text段、data段、rodata段、bss段大小。
//free [-k | -m] 以KB为单位显示 / 以MB为单位显示
/*************************************************************
命令功能
free命令可显示系统内存的使用情况,同时显示系统的text段、data段、rodata段、bss段大小。
命令格式
free [-k | -m]
参数说明
参数 参数说明 取值范围
无参数 以Byte为单位显示。N/A
-k 以KB为单位显示。N/A
-m 以MB为单位显示。N/A
使用实例
举例:分别输入free、free -k、free -m.
*************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdFree(INT32 argc, const CHAR *argv[])
{
if (argc > 1) {
......@@ -282,7 +296,30 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdFree(INT32 argc, const CHAR *argv[])
OsShellCmdSectionInfo(argc, argv);//显示系统各段使用情况
return 0;
}
/*************************************************************
命令功能
uname命令用于显示当前操作系统的名称,版本创建时间,系统名称,版本信息等。
命令格式
uname [-a | -s | -t | -v | --help]
参数说明
参数 参数说明
无参数 默认显示操作系统名称。
-a 显示全部信息。
-t 显示版本创建的时间。
-s 显示操作系统名称。
-v 显示版本信息。
--help 显示uname指令格式提示。
使用指南
uname用于显示当前操作系统名称。语法uname -a | -t| -s| -v 描述uname 命令将正在使用的操作系统名写到标准输出中,这几个参数不能混合使用。
使用实例
举例:输入uname -a
*************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdUname(INT32 argc, const CHAR *argv[])
{
if (argc == 0) {
......
......@@ -48,27 +48,27 @@ STATIC VOID OsMagicPanic(VOID);
STATIC VOID OsMagicMemCheck(VOID);
STATIC MagicKeyOp g_magicMemCheckOp = {//快捷键内存检查
.opHandler = OsMagicMemCheck,
.opHandler = OsMagicMemCheck, //等于执行了一次 shell memcheck
.helpMsg = "Check system memory(ctrl+e) ",
.magicKey = 0x05 /* ctrl + e */
.magicKey = 0x05 /* ctrl + e */ //系统进行简单完整性内存池检查,检查出错会输出相关错误信息,检查正常会输出“system memcheck over, all passed!”
};
STATIC MagicKeyOp g_magicPanicOp = {//panic 表示kernel走到了一个不知道该怎么走下一步的状况,
.opHandler = OsMagicPanic, //一旦到这个情况,kernel就尽可能把它此时能获取的全部信息都打印出来.
.helpMsg = "System panic(ctrl+p) ",
.magicKey = 0x10 /* ctrl + p */
.magicKey = 0x10 /* ctrl + p */ //系统主动进入panic,输出panic相关信息后,系统会挂住;
};
STATIC MagicKeyOp g_magicTaskShowOp = { //快捷键显示任务操作
.opHandler = OsMagicTaskShow,
.opHandler = OsMagicTaskShow, //等于执行了一次 shell task -a
.helpMsg = "Show task information(ctrl+t) ",
.magicKey = 0x14 /* ctrl + t */
.magicKey = 0x14 /* ctrl + t */ //输出任务相关信息;
};
STATIC MagicKeyOp g_magicHelpOp = { //快捷键帮助操作
.opHandler = OsMagicHelp,
.helpMsg = "Show all magic op key(ctrl+z) ",
.magicKey = 0x1a /* ctrl + z */
.magicKey = 0x1a /* ctrl + z */ //帮助键,输出相关魔法键简单介绍;
};
/*
......@@ -89,7 +89,7 @@ STATIC MagicKeyOp *g_magicOpTable[MAGIC_KEY_NUM] = {
NULL /* rserved */
};
STATIC VOID OsMagicHelp(VOID)
STATIC VOID OsMagicHelp(VOID)//遍历一下 g_magicOpTable
{
INT32 i;
PRINTK("HELP: ");
......@@ -128,7 +128,7 @@ INT32 CheckMagicKey(CHAR key)
#ifdef LOSCFG_ENABLE_MAGICKEY //魔法键开关
INT32 i;
STATIC UINT32 magicKeySwitch = 0;
if (key == 0x12) { /* ctrl + r */ //用0x12 来打开和关闭魔法键开关
if (key == 0x12) { /* ctrl + r */ //用0x12 打开和关闭魔法键检测功能
magicKeySwitch = ~magicKeySwitch;
if (magicKeySwitch != 0) {
PRINTK("Magic key on\n");
......
......@@ -40,7 +40,7 @@ extern "C" {
typedef struct Spinlock SPIN_LOCK_S;
#define MAX_LOCK_DEPTH 16U
#define MAX_LOCK_DEPTH 16U //最大的锁深度
enum LockDepErrType {
LOCKDEP_SUCEESS = 0,
......@@ -81,7 +81,7 @@ typedef struct {
* <ul><li>los_lockdep.h: the header file that contains the API declaration.</li></ul>
* @see
*/
extern VOID OsLockDepCheckIn(SPIN_LOCK_S *lock);
extern VOID OsLockDepCheckIn(SPIN_LOCK_S *lock);//此API用于检查spinlock中的死锁
/**
* @ingroup los_lockdep
......@@ -100,7 +100,7 @@ extern VOID OsLockDepCheckIn(SPIN_LOCK_S *lock);
* <ul><li>los_lockdep.h: the header file that contains the API declaration.</li></ul>
* @see
*/
extern VOID OsLockDepRecord(SPIN_LOCK_S *lock);
extern VOID OsLockDepRecord(SPIN_LOCK_S *lock);//此API用于跟踪自旋锁锁定的时间
/**
* @ingroup los_lockdep
......@@ -119,7 +119,7 @@ extern VOID OsLockDepRecord(SPIN_LOCK_S *lock);
* <ul><li>los_lockdep.h: the header file that contains the API declaration.</li></ul>
* @see
*/
extern VOID OsLockDepCheckOut(SPIN_LOCK_S *lock);
extern VOID OsLockDepCheckOut(SPIN_LOCK_S *lock);//此API用于跟踪自旋锁何时解锁
/**
* @ingroup los_lockdep
......@@ -137,7 +137,7 @@ extern VOID OsLockDepCheckOut(SPIN_LOCK_S *lock);
* <ul><li>los_lockdep.h: the header file that contains the API declaration.</li></ul>
* @see
*/
extern VOID OsLockdepClearSpinlocks(VOID);
extern VOID OsLockdepClearSpinlocks(VOID);//此API用于清除curret task的lockdep记录
#ifdef __cplusplus
#if __cplusplus
......
......@@ -44,7 +44,7 @@ extern "C" {
#define OS_MP_GC_PERIOD 100 /* ticks */
typedef enum {
typedef enum {//处理器之间发送消息
LOS_MP_IPI_WAKEUP, //唤醒CPU
LOS_MP_IPI_SCHEDULE,//调度CPU
LOS_MP_IPI_HALT, //停止CPU
......
git add -A
git commit -m '注释鸿蒙对异常的跟踪是如何实现的?
git commit -m '注释内核出现异常时鸿蒙是如何处理的
搜索 @note_pic 可以查看全部字符图
搜索 @note_why 是注者尚未看明白的地方,如果您看明白了,请告诉注者完善
搜索 @note_thinking 是注者的思考和吐槽的地方
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册