系统调用由软中断实现,对其汇编代码注解

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    https://weharmony.gitee.io
上级 d011b438
......@@ -254,23 +254,23 @@ OsKernelTaskLoad: @内核任务的加载
ADD SP, SP, #4 @sp=SP+4
LDMFD SP!, {LR, PC}^ @返回地址赋给pc指针
OsIrqHandler: @中断处理
OsIrqHandler: @中断处理
SUB LR, LR, #4
/* push r0-r3 to irq stack */
STMFD SP, {R0-R3}
STMFD SP, {R0-R3} @r0-r3寄存器入栈
SUB R0, SP, #(4 * 4)
MRS R1, SPSR @获取程序状态控制寄存器
MOV R2, LR
/* disable irq, switch to svc mode */
CPSID i, #0x13 @禁止中断,切换到SVC模式
/* disable irq, switch to svc mode */@超级用户模式(SVC 模式),主要用于 SWI(软件中断) OS(操作系统)
CPSID i, #0x13 @切换到SVC模式,此处一切换,后续指令将入SVC的栈
@CPSID i为关中断指令,对应的是CPSIE
/* push spsr and pc in svc stack */
STMFD SP!, {R1, R2}
STMFD SP, {LR}
STMFD SP!, {R1, R2} @实际是将 SPSR,LR入栈,入栈顺序为 R1,R2,SP自增
STMFD SP, {LR} @LR再入栈,SP不自增
AND R3, R1, #CPSR_MASK_MODE
AND R3, R1, #CPSR_MASK_MODE @获取CPU的运行模式
CMP R3, #CPSR_USER_MODE @中断是否发生在用户模式
BNE OsIrqFromKernel @中断不发生在用户模式下则跳转到OsIrqFromKernel
......@@ -324,15 +324,15 @@ OsIrqFromKernel: @从内核发起中断
ADD SP, SP, #4
OsIrqContextRestore:
LDR R0, [SP, #(4 * 7)]
MSR SPSR_cxsf, R0
OsIrqContextRestore: @中断环境恢复
LDR R0, [SP, #(4 * 7)] @读取 SP+28 位置数据给R0
MSR SPSR_cxsf, R0 @恢复spsr
AND R0, R0, #CPSR_MASK_MODE
CMP R0, #CPSR_USER_MODE
CMP R0, #CPSR_USER_MODE @
LDMFD SP!, {R0-R3, R12}
LDMFD SP!, {R0-R3, R12} @
BNE OsIrqContextRestoreToKernel
BNE OsIrqContextRestoreToKernel @CPU工作在非用户模式
/* load user sp and lr, and jump cpsr */
LDMFD SP, {R13, R14}^
......
......@@ -158,7 +158,7 @@ __stack_chk_guard_setup:
POP {FP, PC}
@ Description: Undefined instruction exception handler
_osExceptUndefInstrHdl:
_osExceptUndefInstrHdl:@出现未定义的指令处理
#ifdef LOSCFG_GDB
GDB_HANDLE OsUndefIncExcHandleEntry
#else
......@@ -172,43 +172,43 @@ _osExceptUndefInstrHdl:
#endif
@ Description: Software interrupt exception handler
_osExceptSwiHdl:
SUB SP, SP, #(4 * 16)
STMIA SP, {R0-R12}
MRS R3, SPSR
MOV R4, LR
AND R1, R3, #CPSR_MASK_MODE @ Interrupted mode
CMP R1, #CPSR_USER_MODE @ User mode
BNE OsKernelSVCHandler @ Branch if not user mode
_osExceptSwiHdl: @软中断异常处理
SUB SP, SP, #(4 * 16) @先申请16个栈空间用于处理本次软中断
STMIA SP, {R0-R12} @保存R0-R12寄存器值
MRS R3, SPSR @读取本模式下的SPSR
MOV R4, LR @保存回跳寄存器LR
AND R1, R3, #CPSR_MASK_MODE @ Interrupted mode 获取中断模式
CMP R1, #CPSR_USER_MODE @ User mode 是否为用户模式
BNE OsKernelSVCHandler @ Branch if not user mode 非用户模式下跳转
@ 当为用户模式时,获取SPLR寄出去值
@ we enter from user mode, we need get the values of USER mode r13(sp) and r14(lr).
@ stmia with ^ will return the user mode registers (provided that r15 is not in the register list).
MOV R0, SP
STMFD SP!, {R3} @ Save the CPSR
ADD R3, SP, #(4 * 17) @ Offset to pc/cpsr storage
STMFD R3!, {R4} @ Save the CPSR and r15(pc)
STMFD R3, {R13, R14}^ @ Save user mode r13(sp) and r14(lr)
MOV R0, SP @获取SP,R0将作为OsArmA32SyscallHandle的参数
STMFD SP!, {R3} @ Save the CPSR 入栈保存CPSR
ADD R3, SP, #(4 * 17) @ Offset to pc/cpsr storage 跳到PC/CPSR存储位置
STMFD R3!, {R4} @ Save the CPSR and r15(pc) 保存LR寄存器
STMFD R3, {R13, R14}^ @ Save user mode r13(sp) and r14(lr) 保存用户模式下的SPLR寄存器
SUB SP, SP, #4
PUSH_FPU_REGS R1
MOV FP, #0 @ Init frame pointer
CPSIE I
CPSIE I @开中断,表明在系统调用期间可响应中断
BLX OsArmA32SyscallHandle /*处理系统调用*/
CPSID I
CPSID I @执行后续指令前必须先关中断
POP_FPU_REGS R1
ADD SP, SP,#4
LDMFD SP!, {R3} @ Fetch the return SPSR
MSR SPSR_cxsf, R3 @ Set the return mode SPSR
POP_FPU_REGS R1 @弹出FP值给R1
ADD SP, SP,#4 @ 定位到保存旧SPSR值的位置
LDMFD SP!, {R3} @ Fetch the return SPSR 弹出旧SPSR
MSR SPSR_cxsf, R3 @ Set the return mode SPSR 恢复该模式下的SPSR
@ we are leaving to user mode, we need to restore the values of USER mode r13(sp) and r14(lr).
@ ldmia with ^ will return the user mode registers (provided that r15 is not in the register list)
LDMFD SP!, {R0-R12}
LDMFD SP, {R13, R14}^ @ Restore user mode R13/R14
ADD SP, SP, #(2 * 4)
LDMFD SP!, {PC}^ @ Return to user
LDMFD SP!, {R0-R12} @恢复R0-R12寄存器
LDMFD SP, {R13, R14}^ @ Restore user mode R13/R14 恢复用户模式的R13/R14寄存器
ADD SP, SP, #(2 * 4) @定位到保存旧PC值的位置
LDMFD SP!, {PC}^ @ Return to user 弹出值给PC寄存器
OsKernelSVCHandler:
ADD R0, SP, #(4 * 16)
......
......@@ -215,14 +215,14 @@ STATIC UINT32 OsHwiDelNoShared(HWI_HANDLE_T hwiNum)
{
UINT32 intSave;
HWI_LOCK(intSave);
HWI_LOCK(intSave);//申请硬中断自旋锁
g_hwiForm[hwiNum].pfnHook = NULL;//回调函数直接NULL
if (g_hwiForm[hwiNum].uwParam) {//如有参数
(VOID)LOS_MemFree(m_aucSysMem0, (VOID *)g_hwiForm[hwiNum].uwParam);//释放内存
}
g_hwiForm[hwiNum].uwParam = 0; //NULL
HWI_UNLOCK(intSave);
HWI_UNLOCK(intSave);//释放硬中断自旋锁
return LOS_OK;
}
//创建一个不支持共享的中断
......@@ -258,7 +258,7 @@ STATIC UINT32 OsHwiDelShared(HWI_HANDLE_T hwiNum, const HwiIrqParam *irqParam)
UINT32 intSave;
HWI_LOCK(intSave);
hwiForm = &g_hwiForm[hwiNum];
hwiForm = &g_hwiForm[hwiNum];//从全局注册的中断向量表中获取中断项
hwiFormtmp = hwiForm;
if ((hwiForm->uwParam & IRQF_SHARED) && ((irqParam == NULL) || (irqParam->pDevId == NULL))) {
......
......@@ -96,10 +96,10 @@
.global __exception_handlers
__exception_handlers:
/*
/* //假设:ROM代码在硬件重置地址有这些向量
*Assumption: ROM code has these vectors at the hardware reset address.
*A simple jump removes any address-space dependencies [i.e. safer]
*/
*///一个简单的跳转将删除任何地址空间依赖关系
b reset_vector
b _osExceptUndefInstrHdl
b _osExceptSwiHdl
......
......@@ -436,7 +436,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
UINT32 ret;
TSK_INIT_PARAM_S taskInitParam;
Percpu *perCpu = OsPercpuGet();//获取CPU信息
UINT32 *idleTaskID = &perCpu->idleTaskID;
UINT32 *idleTaskID = &perCpu->idleTaskID;//指定CPU的空闲任务
(VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//任务初始参数清0
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;//入口函数指定idle
......@@ -449,7 +449,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
#endif
ret = LOS_TaskCreate(idleTaskID, &taskInitParam);//创建task并申请调度,
OS_TCB_FROM_TID(*idleTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//设置task状态为系统任务,系统任务运行在内核态.
//这里说下系统任务有哪些?比如: idle,swtmr(软时钟)等等
//这里说下系统任务有哪些?比如: idle,swtmr(软时钟),资源回收等等
return ret;
}
......@@ -457,7 +457,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
* Description : get id of current running task.
* Return : task id
*/
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)//获取当前任务的ID
{
LosTaskCB *runTask = OsCurrTaskGet();
......@@ -506,10 +506,10 @@ LITE_OS_SEC_TEXT VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status)
LosProcessCB *runProcess = NULL;
LosTaskCB *mainTask = NULL;
SCHEDULER_LOCK(intSave);
SCHEDULER_LOCK(intSave);//禁止调度
runProcess = OS_PCB_FROM_PID(taskCB->processID);//通过任务ID拿到进程实体
mainTask = OS_TCB_FROM_TID(runProcess->threadGroupID);//通过线程组ID拿到主任务实体,threadGroupID就是等于mainTask的taskId
SCHEDULER_UNLOCK(intSave); //这个是在线程组创建的时候指定的.
mainTask = OS_TCB_FROM_TID(runProcess->threadGroupID);//通过线程组ID拿到主任务实体,threadGroupID就是等于mainTask的taskId,这个是在线程组创建的时候指定的.
SCHEDULER_UNLOCK(intSave);//恢复调度
if (mainTask == taskCB) {//如果参数任务就是主任务
OsTaskExitGroup(status);//task退出线程组
}
......@@ -521,8 +521,8 @@ LITE_OS_SEC_TEXT VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status)
return;
}
if (taskCB->taskStatus & OS_TASK_FLAG_DETACHED) {//任务贴有分离的标签
(VOID)OsTaskDeleteUnsafe(taskCB, status, intSave);//任务要over了,走起释放占用的资源的流程
if (taskCB->taskStatus & OS_TASK_FLAG_DETACHED) {//任务状态是否有分离标签
(VOID)OsTaskDeleteUnsafe(taskCB, status, intSave);//任务要over了,释放占用的资源
}
OsTaskJoinPostUnsafe(taskCB);//退出前唤醒跟自己绑在一块的任务
......@@ -546,8 +546,8 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
* from interrupt and other cores. release task spinlock and enable
* interrupt in sequence at the task entry.
*/
LOS_SpinUnlock(&g_taskSpin);
(VOID)LOS_IntUnLock();
LOS_SpinUnlock(&g_taskSpin);//释放任务自旋锁
(VOID)LOS_IntUnLock();//恢复中断
taskCB = OS_TCB_FROM_TID(taskID);
taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1],//调用任务的入口函数
......@@ -782,17 +782,17 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB,
LOS_ListInit(&(taskCB->msgListHead));//初始化 liteipc的消息链表
(VOID)memset_s(taskCB->accessMap, sizeof(taskCB->accessMap), 0, sizeof(taskCB->accessMap));
#endif
taskCB->policy = (initParam->policy == LOS_SCHED_FIFO) ? LOS_SCHED_FIFO : LOS_SCHED_RR;
taskCB->taskStatus = OS_TASK_STATUS_INIT;
taskCB->policy = (initParam->policy == LOS_SCHED_FIFO) ? LOS_SCHED_FIFO : LOS_SCHED_RR;//调度模式
taskCB->taskStatus = OS_TASK_STATUS_INIT;//任务初始状态
if (initParam->uwResved & OS_TASK_FLAG_DETACHED) {//分离模式 代表任务与其他任务的关系
taskCB->taskStatus |= OS_TASK_FLAG_DETACHED;
taskCB->taskStatus |= OS_TASK_FLAG_DETACHED;//任务状态贴上分离标签
} else {//参与模式
LOS_ListInit(&taskCB->joinList);
taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN;
taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN;//任务状态贴上联合标签
}
taskCB->futex.index = OS_INVALID_VALUE;
LOS_ListInit(&taskCB->lockList);
LOS_ListInit(&taskCB->lockList);//初始化互斥锁链表
}
//任务初始化
LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam,
......
......@@ -80,7 +80,7 @@ typedef struct ProcessCB {
CHAR processName[OS_PCB_NAME_LEN]; /**< Process name */ //进程名称
UINT32 processID; /**< process ID = leader thread ID */ //进程ID,由进程池分配,范围[0,64]
UINT16 processStatus; /**< [15:4] process Status; [3:0] The number of threads currently
running in the process *///这里设计很巧妙.用一个16表示了两层逻辑 数量和状态,点赞!
running in the process *///这里设计很巧妙.用一个变量表示了两层逻辑 数量和状态,点赞!
UINT16 priority; /**< process priority */ //进程优先级
UINT16 policy; /**< process policy */ //进程的调度方式,默认抢占式
UINT16 timeSlice; /**< Remaining time slice *///进程时间片,默认2个tick
......
git add -A
git commit -m '硬中断代码注释
百万汉字注解 + 百篇博客分析 -> 挖透鸿蒙内核源码
git commit -m '系统调用由软中断实现,对其汇编代码注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://weharmony.gitee.io
'
git push origin master
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册