提交 1b01ca35 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析
上级 bb1b1f85
...@@ -127,7 +127,7 @@ LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(LosTaskCB *childTaskCB, LosTaskCB * ...@@ -127,7 +127,7 @@ LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(LosTaskCB *childTaskCB, LosTaskCB *
(VOID)memcpy_s(childTaskCB->stackPointer, sizeof(TaskContext), cloneStack, sizeof(TaskContext)); (VOID)memcpy_s(childTaskCB->stackPointer, sizeof(TaskContext), cloneStack, sizeof(TaskContext));
context->R[0] = 0; context->R[0] = 0;
} }
//用户栈初始化 //用户任务使用栈初始化
LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_FUNC taskEntry, UINTPTR stack) LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_FUNC taskEntry, UINTPTR stack)
{ {
LOS_ASSERT(context != NULL); LOS_ASSERT(context != NULL);
...@@ -139,7 +139,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_F ...@@ -139,7 +139,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_F
#endif #endif
context->R[0] = stack;//栈指针给r0寄存器 context->R[0] = stack;//栈指针给r0寄存器
context->SP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE);//异常模式所专用的堆栈 segment fault 输出回溯信息 context->SP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE);//异常模式所专用的堆栈 segment fault 输出回溯信息
context->LR = 0;//保存子程序返回地址 a call b ,在b中保存 a地址 context->LR = 0;//保存子程序返回地址 例如 a call b ,在b中保存 a地址
context->PC = (UINTPTR)taskEntry;//入口函数 context->PC = (UINTPTR)taskEntry;//入口函数
} }
......
...@@ -127,7 +127,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskSchedQueueEnqueue(LosTaskCB *taskCB, UINT16 sta ...@@ -127,7 +127,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskSchedQueueEnqueue(LosTaskCB *taskCB, UINT16 sta
} else { } else {
OS_PROCESS_PRI_QUEUE_ENQUEUE(processCB);//入进程入g_priQueueList就绪队列 OS_PROCESS_PRI_QUEUE_ENQUEUE(processCB);//入进程入g_priQueueList就绪队列
} }
processCB->processStatus &= ~(status | OS_PROCESS_STATUS_PEND); processCB->processStatus &= ~(status | OS_PROCESS_STATUS_PEND);//去掉外传标签和阻塞标签
processCB->processStatus |= OS_PROCESS_STATUS_READY; processCB->processStatus |= OS_PROCESS_STATUS_READY;
} else { } else {
LOS_ASSERT(!(processCB->processStatus & OS_PROCESS_STATUS_PEND)); LOS_ASSERT(!(processCB->processStatus & OS_PROCESS_STATUS_PEND));
...@@ -739,10 +739,10 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, U ...@@ -739,10 +739,10 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, U
LOS_PhysPagesFreeContiguous(ttb, 1);//释放物理页,4K LOS_PhysPagesFreeContiguous(ttb, 1);//释放物理页,4K
return LOS_EAGAIN; return LOS_EAGAIN;
} }
processCB->vmSpace = space; processCB->vmSpace = space;//设为进程虚拟空间
LOS_ListAdd(&processCB->vmSpace->archMmu.ptList, &(vmPage->node)); LOS_ListAdd(&processCB->vmSpace->archMmu.ptList, &(vmPage->node));//将空间映射页表挂在 空间的mmu L1页表, L1为表头
} else { } else {
processCB->vmSpace = LOS_GetKVmSpace(); processCB->vmSpace = LOS_GetKVmSpace();//内核共用一个虚拟空间,内核进程 常驻内存
} }
#ifdef LOSCFG_SECURITY_VID #ifdef LOSCFG_SECURITY_VID
...@@ -762,7 +762,7 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, U ...@@ -762,7 +762,7 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, U
return LOS_OK; return LOS_OK;
} }
//创建用户
#ifdef LOSCFG_SECURITY_CAPABILITY #ifdef LOSCFG_SECURITY_CAPABILITY
STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size) STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)
{ {
...@@ -1540,7 +1540,7 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR ...@@ -1540,7 +1540,7 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR
LOS_VmSpaceFree(oldSpace); LOS_VmSpaceFree(oldSpace);
return LOS_OK; return LOS_OK;
} }
//进程层面的开始执行, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小
LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize) LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize)
{ {
LosProcessCB *processCB = NULL; LosProcessCB *processCB = NULL;
...@@ -1552,36 +1552,36 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT ...@@ -1552,36 +1552,36 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT
return LOS_NOK; return LOS_NOK;
} }
if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) { if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) {//对齐
return LOS_NOK; return LOS_NOK;
} }
if ((mapBase == 0) || (mapSize == 0) || (sp <= mapBase) || (sp > (mapBase + mapSize))) { if ((mapBase == 0) || (mapSize == 0) || (sp <= mapBase) || (sp > (mapBase + mapSize))) {//参数检查
return LOS_NOK; return LOS_NOK;
} }
SCHEDULER_LOCK(intSave); SCHEDULER_LOCK(intSave);//拿自旋锁
processCB = OsCurrProcessGet(); processCB = OsCurrProcessGet();//获取当前进程
taskCB = OsCurrTaskGet(); taskCB = OsCurrTaskGet();//获取当前任务
processCB->threadGroupID = taskCB->taskID; processCB->threadGroupID = taskCB->taskID;//threadGroupID是进程的主线程ID,也就是应用程序 main函数线程
taskCB->userMapBase = mapBase; taskCB->userMapBase = mapBase;//任务栈底地址
taskCB->userMapSize = mapSize; taskCB->userMapSize = mapSize;//任务栈大小
taskCB->taskEntry = (TSK_ENTRY_FUNC)entry; taskCB->taskEntry = (TSK_ENTRY_FUNC)entry;//任务的入口函数
taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize, (VOID *)taskCB->topOfStack, FALSE); taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize, (VOID *)taskCB->topOfStack, FALSE);//创建任务上下文
OsUserTaskStackInit(taskContext, taskCB->taskEntry, sp); OsUserTaskStackInit(taskContext, taskCB->taskEntry, sp);//用户进程任务栈初始化
SCHEDULER_UNLOCK(intSave); SCHEDULER_UNLOCK(intSave);//解锁
return LOS_OK; return LOS_OK;
} }
//用户进程开始初始化
STATIC UINT32 OsUserInitProcessStart(UINT32 processID, TSK_INIT_PARAM_S *param) STATIC UINT32 OsUserInitProcessStart(UINT32 processID, TSK_INIT_PARAM_S *param)
{ {
UINT32 intSave; UINT32 intSave;
INT32 taskID; INT32 taskID;
INT32 ret; INT32 ret;
taskID = OsCreateUserTask(processID, param); taskID = OsCreateUserTask(processID, param);//创建一个用户态任务
if (taskID < 0) { if (taskID < 0) {
return LOS_NOK; return LOS_NOK;
} }
...@@ -1657,7 +1657,7 @@ ERROR: ...@@ -1657,7 +1657,7 @@ ERROR:
OsDeInitPCB(processCB);//删除PCB块 OsDeInitPCB(processCB);//删除PCB块
return ret; return ret;
} }
//拷贝用户信息 直接用memcpy_s
STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB) STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB)
{ {
#ifdef LOSCFG_SECURITY_CAPABILITY #ifdef LOSCFG_SECURITY_CAPABILITY
...@@ -1671,7 +1671,7 @@ STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB) ...@@ -1671,7 +1671,7 @@ STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB)
#endif #endif
return LOS_OK; return LOS_OK;
} }
//任务初始化时拷贝任务信息
STATIC VOID OsInitCopyTaskParam(LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size, STATIC VOID OsInitCopyTaskParam(LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size,
TSK_INIT_PARAM_S *childPara) TSK_INIT_PARAM_S *childPara)
{ {
...@@ -1679,9 +1679,9 @@ STATIC VOID OsInitCopyTaskParam(LosProcessCB *childProcessCB, const CHAR *name, ...@@ -1679,9 +1679,9 @@ STATIC VOID OsInitCopyTaskParam(LosProcessCB *childProcessCB, const CHAR *name,
UINT32 intSave; UINT32 intSave;
SCHEDULER_LOCK(intSave); SCHEDULER_LOCK(intSave);
mainThread = OsCurrTaskGet(); mainThread = OsCurrTaskGet();//获取当前task,注意变量名从这里也可以看出 thread 和 task 是一个概念,只是内核常说task,上层应用说thread ,概念的映射.
if (OsProcessIsUserMode(childProcessCB)) { if (OsProcessIsUserMode(childProcessCB)) {//用户模式进程
childPara->pfnTaskEntry = mainThread->taskEntry; childPara->pfnTaskEntry = mainThread->taskEntry;
childPara->uwStackSize = mainThread->stackSize; childPara->uwStackSize = mainThread->stackSize;
childPara->userParam.userArea = mainThread->userArea; childPara->userParam.userArea = mainThread->userArea;
......
...@@ -1838,7 +1838,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, ...@@ -1838,7 +1838,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID,
return LOS_OK; return LOS_OK;
} }
//创建一个用户任务
LITE_OS_SEC_TEXT_INIT INT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam) LITE_OS_SEC_TEXT_INIT INT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam)
{ {
LosProcessCB *processCB = NULL; LosProcessCB *processCB = NULL;
...@@ -1851,32 +1851,32 @@ LITE_OS_SEC_TEXT_INIT INT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S ...@@ -1851,32 +1851,32 @@ LITE_OS_SEC_TEXT_INIT INT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S
return ret; return ret;
} }
initParam->uwStackSize = OS_USER_TASK_SYSCALL_SATCK_SIZE; initParam->uwStackSize = OS_USER_TASK_SYSCALL_SATCK_SIZE;//设置任务栈大小,这里用了用户态下系统调用的栈大小(12K)
initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST; initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;//设置默认优先级
initParam->policy = LOS_SCHED_RR; initParam->policy = LOS_SCHED_RR;//调度方式为抢占式,注意鸿蒙不仅仅只支持抢占式调度方式
if (processID == OS_INVALID_VALUE) { if (processID == OS_INVALID_VALUE) {//外面没指定进程ID的处理
SCHEDULER_LOCK(intSave); SCHEDULER_LOCK(intSave);
processCB = OsCurrProcessGet(); processCB = OsCurrProcessGet();//拿当前运行的进程
initParam->processID = processCB->processID; initParam->processID = processCB->processID;//进程ID赋值
initParam->consoleID = processCB->consoleID; initParam->consoleID = processCB->consoleID;//任务控制台ID归属
SCHEDULER_UNLOCK(intSave); SCHEDULER_UNLOCK(intSave);
} else { } else {//外面指定了进程ID的处理
processCB = OS_PCB_FROM_PID(processID); processCB = OS_PCB_FROM_PID(processID);//通过ID拿到进程PCB
if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) { if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) {//进程状态有初始和正在运行两个标签时
return OS_INVALID_VALUE; return OS_INVALID_VALUE;//????? 为什么这两种情况下会无效
} }
initParam->processID = processID; initParam->processID = processID;//进程ID赋值
initParam->consoleID = 0; initParam->consoleID = 0;//默认0号控制台
} }
ret = LOS_TaskCreateOnly(&taskID, initParam); ret = LOS_TaskCreateOnly(&taskID, initParam);//只创建task实体,不申请调度
if (ret != LOS_OK) { if (ret != LOS_OK) {
return OS_INVALID_VALUE; return OS_INVALID_VALUE;
} }
return taskID; return taskID;
} }
//获取任务的调度方式
LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID) LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
{ {
UINT32 intSave; UINT32 intSave;
...@@ -1887,45 +1887,45 @@ LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID) ...@@ -1887,45 +1887,45 @@ LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
return -LOS_EINVAL; return -LOS_EINVAL;
} }
taskCB = OS_TCB_FROM_TID(taskID); taskCB = OS_TCB_FROM_TID(taskID);//通过任务ID获得任务TCB
SCHEDULER_LOCK(intSave); SCHEDULER_LOCK(intSave);
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//状态不能是没有在使用
policy = -LOS_EINVAL; policy = -LOS_EINVAL;
OS_GOTO_ERREND(); OS_GOTO_ERREND();
} }
policy = taskCB->policy; policy = taskCB->policy;//任务的调度方式
LOS_ERREND: LOS_ERREND:
SCHEDULER_UNLOCK(intSave); SCHEDULER_UNLOCK(intSave);
return policy; return policy;
} }
//以不安全的方式设置任务的调度信息, 不安全指的是SCHEDULER_LOCK 在两个函数中SCHEDULER_UNLOCK
LITE_OS_SEC_TEXT INT32 OsTaskSchedulerSetUnsafe(LosTaskCB *taskCB, UINT16 policy, UINT16 priority, LITE_OS_SEC_TEXT INT32 OsTaskSchedulerSetUnsafe(LosTaskCB *taskCB, UINT16 policy, UINT16 priority,
BOOL policyFlag, UINT32 intSave) BOOL policyFlag, UINT32 intSave)
{ {
BOOL needSched = TRUE; BOOL needSched = TRUE;
if (taskCB->taskStatus & OS_TASK_STATUS_READY) { if (taskCB->taskStatus & OS_TASK_STATUS_READY) {//就绪状态的处理
OS_TASK_PRI_QUEUE_DEQUEUE(OS_PCB_FROM_PID(taskCB->processID), taskCB); OS_TASK_PRI_QUEUE_DEQUEUE(OS_PCB_FROM_PID(taskCB->processID), taskCB);//先出就绪队列,因为这里是要改变优先级的.
} }//一旦任务的调度优先级,将划到对应优先级的队列中,每个进程都有32个任务就绪队列. process.threadPriQueueList负责管理
if (policyFlag == TRUE) { if (policyFlag == TRUE) {//TRUE表示 调度方式要改
if (policy == LOS_SCHED_FIFO) { if (policy == LOS_SCHED_FIFO) {//如果是 FIFO 方式
taskCB->timeSlice = 0; taskCB->timeSlice = 0;//不要时间片,只有抢占式才会需要时间片
} }
taskCB->policy = policy; taskCB->policy = policy;//改变调度方式
} }
taskCB->priority = priority; taskCB->priority = priority;//改变优先级
if (taskCB->taskStatus & OS_TASK_STATUS_INIT) { if (taskCB->taskStatus & OS_TASK_STATUS_INIT) {//如果任务状态有初始状态的标签
taskCB->taskStatus &= ~OS_TASK_STATUS_INIT; taskCB->taskStatus &= ~OS_TASK_STATUS_INIT;//去掉初始状态标签
taskCB->taskStatus |= OS_TASK_STATUS_READY; taskCB->taskStatus |= OS_TASK_STATUS_READY;//贴上就绪标签
} }
if (taskCB->taskStatus & OS_TASK_STATUS_READY) { if (taskCB->taskStatus & OS_TASK_STATUS_READY) {//如果有就绪标签
taskCB->taskStatus &= ~OS_TASK_STATUS_READY; taskCB->taskStatus &= ~OS_TASK_STATUS_READY;//去掉就绪标签,why这么做?因为只有非就绪状态的任务才可能加入 OS_TASK_SCHED_QUEUE_ENQUEUE
OS_TASK_SCHED_QUEUE_ENQUEUE(taskCB, OS_PROCESS_STATUS_INIT); OS_TASK_SCHED_QUEUE_ENQUEUE(taskCB, OS_PROCESS_STATUS_INIT);//任务加入到调度队列 ,具体看他的函数实现 OsTaskSchedQueueEnqueue
} else if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { } else if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//如果有运行标签,直接goto调度
goto SCHEDULE; goto SCHEDULE;
} else { } else {
needSched = FALSE; needSched = FALSE;
...@@ -1936,12 +1936,12 @@ SCHEDULE: ...@@ -1936,12 +1936,12 @@ SCHEDULE:
LOS_MpSchedule(OS_MP_CPU_ALL); LOS_MpSchedule(OS_MP_CPU_ALL);
if (OS_SCHEDULER_ACTIVE && (needSched == TRUE)) { if (OS_SCHEDULER_ACTIVE && (needSched == TRUE)) {
LOS_Schedule(); LOS_Schedule();//申请调度
} }
return LOS_OK; return LOS_OK;
} }
//设置任务的调度信息
LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority) LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority)
{ {
UINT32 intSave; UINT32 intSave;
...@@ -1959,9 +1959,9 @@ LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 ...@@ -1959,9 +1959,9 @@ LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16
return LOS_EINVAL; return LOS_EINVAL;
} }
SCHEDULER_LOCK(intSave); SCHEDULER_LOCK(intSave);//拿到自旋锁
taskCB = OS_TCB_FROM_TID(taskID); taskCB = OS_TCB_FROM_TID(taskID);
return OsTaskSchedulerSetUnsafe(taskCB, policy, priority, TRUE, intSave); return OsTaskSchedulerSetUnsafe(taskCB, policy, priority, TRUE, intSave);//以不安全的方式设置任务的调度信息,为什么不安全? 因为自旋锁跨了一个函数
} }
LITE_OS_SEC_TEXT VOID OsWriteResourceEvent(UINT32 events) LITE_OS_SEC_TEXT VOID OsWriteResourceEvent(UINT32 events)
......
...@@ -359,7 +359,7 @@ STATIC INLINE BOOL OsProcessExitCodeSignalIsSet(LosProcessCB *processCB) ...@@ -359,7 +359,7 @@ STATIC INLINE BOOL OsProcessExitCodeSignalIsSet(LosProcessCB *processCB)
return (processCB->exitCode) & 0x7FU;//低7位全部置1 return (processCB->exitCode) & 0x7FU;//低7位全部置1
} }
STATIC INLINE VOID OsProcessExitCodeSet(LosProcessCB *processCB, UINT32 code)//外界提供退出码 STATIC INLINE VOID OsProcessExitCodeSet(LosProcessCB *processCB, UINT32 code)//外界提供退出码
{ {
processCB->exitCode |= ((code & 0x000000FFU) << 8U) & 0x0000FF00U; /* 8: Move 8 bits to the left, exitCode */ processCB->exitCode |= ((code & 0x000000FFU) << 8U) & 0x0000FF00U; /* 8: Move 8 bits to the left, exitCode */
} }
......
...@@ -297,7 +297,7 @@ typedef struct { ...@@ -297,7 +297,7 @@ typedef struct {
VOID *stackPointer; /**< Task stack pointer */ VOID *stackPointer; /**< Task stack pointer */
UINT16 taskStatus; /**< Task status */ UINT16 taskStatus; /**< Task status */
UINT16 priority; /**< Task priority */ UINT16 priority; /**< Task priority */
UINT16 policy; UINT16 policy; //任务的调度方式(三种 .. LOS_SCHED_RR )
UINT16 timeSlice; /**< Remaining time slice */ UINT16 timeSlice; /**< Remaining time slice */
UINT32 stackSize; /**< Task stack size */ UINT32 stackSize; /**< Task stack size */
UINTPTR topOfStack; /**< Task stack top */ UINTPTR topOfStack; /**< Task stack top */
...@@ -318,7 +318,7 @@ typedef struct { ...@@ -318,7 +318,7 @@ typedef struct {
the priority can not be greater than 31 */ the priority can not be greater than 31 */
INT32 errorNo; /**< Error Num */ INT32 errorNo; /**< Error Num */
UINT32 signal; /**< Task signal */ UINT32 signal; /**< Task signal */
sig_cb sig; sig_cb sig; //信号控制块
#if (LOSCFG_KERNEL_SMP == YES) #if (LOSCFG_KERNEL_SMP == YES)
UINT16 currCpu; /**< CPU core number of this task is running on */ UINT16 currCpu; /**< CPU core number of this task is running on */
UINT16 lastCpu; /**< CPU core number of this task is running on last time */ UINT16 lastCpu; /**< CPU core number of this task is running on last time */
...@@ -334,8 +334,8 @@ typedef struct { ...@@ -334,8 +334,8 @@ typedef struct {
SchedStat schedStat; /**< Schedule statistics */ SchedStat schedStat; /**< Schedule statistics */
#endif #endif
#endif #endif
UINTPTR userArea; UINTPTR userArea; //使用区域,由运行时划定,根据运行态不同而不同
UINTPTR userMapBase; UINTPTR userMapBase; //使用区栈底位置
UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */ UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */
UINT32 processID; /**< Which belong process */ UINT32 processID; /**< Which belong process */
FutexNode futex; FutexNode futex;
...@@ -345,9 +345,9 @@ typedef struct { ...@@ -345,9 +345,9 @@ typedef struct {
UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent, UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent,
a specific child process, or any child process */ a specific child process, or any child process */
#if (LOSCFG_KERNEL_LITEIPC == YES) #if (LOSCFG_KERNEL_LITEIPC == YES)
UINT32 ipcStatus; UINT32 ipcStatus; //IPC状态
LOS_DL_LIST msgListHead; LOS_DL_LIST msgListHead; //消息队列头结点
BOOL accessMap[LOSCFG_BASE_CORE_TSK_LIMIT]; BOOL accessMap[LOSCFG_BASE_CORE_TSK_LIMIT];//访问图,指的是task之间是否能访问的标识,LOSCFG_BASE_CORE_TSK_LIMIT 为任务池总数
#endif #endif
} LosTaskCB; } LosTaskCB;
......
...@@ -36,17 +36,17 @@ ...@@ -36,17 +36,17 @@
#include "los_vm_phys.h" #include "los_vm_phys.h"
#include "los_vm_map.h" #include "los_vm_map.h"
#include "los_vm_dump.h" #include "los_vm_dump.h"
//进程开始执行,参数为加载完ELF后的信息
STATIC INT32 OsExecve(const ELFLoadInfo *loadInfo) STATIC INT32 OsExecve(const ELFLoadInfo *loadInfo)
{ {
if ((loadInfo == NULL) || (loadInfo->elfEntry == 0)) { if ((loadInfo == NULL) || (loadInfo->elfEntry == 0)) {//参数检查
return LOS_NOK; return LOS_NOK;
} }
return OsExecStart((TSK_ENTRY_FUNC)(loadInfo->elfEntry), (UINTPTR)loadInfo->stackTop, return OsExecStart((TSK_ENTRY_FUNC)(loadInfo->elfEntry), (UINTPTR)loadInfo->stackTop,
loadInfo->stackBase, loadInfo->stackSize); loadInfo->stackBase, loadInfo->stackSize);//进程开始执行,设置上栈顶,栈底,栈大小
} }
//获取真正的路径
#ifdef LOSCFG_SHELL #ifdef LOSCFG_SHELL
STATIC INT32 OsGetRealPath(const CHAR *fileName, CHAR *buf, UINT32 maxLen) STATIC INT32 OsGetRealPath(const CHAR *fileName, CHAR *buf, UINT32 maxLen)
{ {
...@@ -54,7 +54,7 @@ STATIC INT32 OsGetRealPath(const CHAR *fileName, CHAR *buf, UINT32 maxLen) ...@@ -54,7 +54,7 @@ STATIC INT32 OsGetRealPath(const CHAR *fileName, CHAR *buf, UINT32 maxLen)
UINT32 len, workPathLen, newLen; UINT32 len, workPathLen, newLen;
if (access(fileName, F_OK) < 0) { if (access(fileName, F_OK) < 0) {
workingDirectory = OsShellGetWorkingDirtectory(); workingDirectory = OsShellGetWorkingDirtectory();//获取工作目录
if (workingDirectory == NULL) { if (workingDirectory == NULL) {
goto ERR_FILE; goto ERR_FILE;
} }
...@@ -86,13 +86,13 @@ ERR_FILE: ...@@ -86,13 +86,13 @@ ERR_FILE:
return -ENOENT; return -ENOENT;
} }
#endif #endif
//拷贝用户参数
STATIC INT32 OsCopyUserParam(ELFLoadInfo *loadInfo, const CHAR *fileName, CHAR *kfileName, UINT32 maxSize) STATIC INT32 OsCopyUserParam(ELFLoadInfo *loadInfo, const CHAR *fileName, CHAR *kfileName, UINT32 maxSize)
{ {
UINT32 strLen; UINT32 strLen;
errno_t err; errno_t err;
if (LOS_IsUserAddress((VADDR_T)(UINTPTR)fileName)) { if (LOS_IsUserAddress((VADDR_T)(UINTPTR)fileName)) {//在用户空间
err = LOS_StrncpyFromUser(kfileName, fileName, PATH_MAX + 1); err = LOS_StrncpyFromUser(kfileName, fileName, PATH_MAX + 1);
if (err == -EFAULT) { if (err == -EFAULT) {
return err; return err;
...@@ -100,9 +100,9 @@ STATIC INT32 OsCopyUserParam(ELFLoadInfo *loadInfo, const CHAR *fileName, CHAR * ...@@ -100,9 +100,9 @@ STATIC INT32 OsCopyUserParam(ELFLoadInfo *loadInfo, const CHAR *fileName, CHAR *
PRINT_ERR("%s[%d], filename len exceeds maxlen: %d\n", __FUNCTION__, __LINE__, PATH_MAX); PRINT_ERR("%s[%d], filename len exceeds maxlen: %d\n", __FUNCTION__, __LINE__, PATH_MAX);
return -ENAMETOOLONG; return -ENAMETOOLONG;
} }
} else if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)fileName)) { } else if (LOS_IsKernelAddress((VADDR_T)(UINTPTR)fileName)) {//在内核空间
strLen = strlen(fileName); strLen = strlen(fileName);
err = memcpy_s(kfileName, PATH_MAX, fileName, strLen); err = memcpy_s(kfileName, PATH_MAX, fileName, strLen);//从filename -> kfilename
if (err != EOK) { if (err != EOK) {
PRINT_ERR("%s[%d], Copy failed! err: %d\n", __FUNCTION__, __LINE__, err); PRINT_ERR("%s[%d], Copy failed! err: %d\n", __FUNCTION__, __LINE__, err);
return -EFAULT; return -EFAULT;
...@@ -117,7 +117,7 @@ STATIC INT32 OsCopyUserParam(ELFLoadInfo *loadInfo, const CHAR *fileName, CHAR * ...@@ -117,7 +117,7 @@ STATIC INT32 OsCopyUserParam(ELFLoadInfo *loadInfo, const CHAR *fileName, CHAR *
INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR * const *argv, CHAR * const *envp) INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR * const *argv, CHAR * const *envp)
{ {
ELFLoadInfo loadInfo = { 0 }; ELFLoadInfo loadInfo = { 0 };//ELF加载信息结构体
CHAR kfileName[PATH_MAX + 1] = { 0 }; CHAR kfileName[PATH_MAX + 1] = { 0 };
INT32 ret; INT32 ret;
#ifdef LOSCFG_SHELL #ifdef LOSCFG_SHELL
...@@ -130,7 +130,7 @@ INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR * const *argv, CHAR * const *e ...@@ -130,7 +130,7 @@ INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR * const *argv, CHAR * const *e
((envp != NULL) && !LOS_IsUserAddress((VADDR_T)(UINTPTR)envp))) { ((envp != NULL) && !LOS_IsUserAddress((VADDR_T)(UINTPTR)envp))) {
return -EINVAL; return -EINVAL;
} }
ret = OsCopyUserParam(&loadInfo, fileName, kfileName, PATH_MAX); ret = OsCopyUserParam(&loadInfo, fileName, kfileName, PATH_MAX);//将文件名拷贝到内核空间,PATH_MAX = 256
if (ret != LOS_OK) { if (ret != LOS_OK) {
return ret; return ret;
} }
...@@ -144,15 +144,15 @@ INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR * const *argv, CHAR * const *e ...@@ -144,15 +144,15 @@ INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR * const *argv, CHAR * const *e
} }
#endif #endif
loadInfo.newSpace = LOS_MemAlloc(m_aucSysMem0, sizeof(LosVmSpace)); loadInfo.newSpace = LOS_MemAlloc(m_aucSysMem0, sizeof(LosVmSpace));//分配一个虚拟空间结构体
if (loadInfo.newSpace == NULL) { if (loadInfo.newSpace == NULL) {
PRINT_ERR("%s %d, failed to allocate new vm space\n", __FUNCTION__, __LINE__); PRINT_ERR("%s %d, failed to allocate new vm space\n", __FUNCTION__, __LINE__);
return -ENOMEM; return -ENOMEM;
} }
virtTtb = LOS_PhysPagesAllocContiguous(1); virtTtb = LOS_PhysPagesAllocContiguous(1);//分配一个物理页用于存放L1页表,虚拟地址<--->物理地址映射使用
if (virtTtb == NULL) { if (virtTtb == NULL) {
PRINT_ERR("%s %d, failed to allocate ttb page\n", __FUNCTION__, __LINE__); PRINT_ERR("%s %d, failed to allocate ttb page\n", __FUNCTION__, __LINE__);
LOS_MemFree(m_aucSysMem0, loadInfo.newSpace); LOS_MemFree(m_aucSysMem0, loadInfo.newSpace);//
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -862,7 +862,7 @@ unsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam ...@@ -862,7 +862,7 @@ unsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam
return OsCreateUserTask(OS_INVALID_VALUE, &param); return OsCreateUserTask(OS_INVALID_VALUE, &param);
} }
//系统调用-设置线程使用区域,所有的系统调用都运行在内核态,也运行在内核空间
int SysSetThreadArea(const char *area) int SysSetThreadArea(const char *area)
{ {
unsigned int intSave; unsigned int intSave;
...@@ -870,27 +870,27 @@ int SysSetThreadArea(const char *area) ...@@ -870,27 +870,27 @@ int SysSetThreadArea(const char *area)
LosProcessCB *processCB = NULL; LosProcessCB *processCB = NULL;
unsigned int ret = LOS_OK; unsigned int ret = LOS_OK;
if (!LOS_IsUserAddress((unsigned long)(uintptr_t)area)) { if (!LOS_IsUserAddress((unsigned long)(uintptr_t)area)) {//区域不能在用户空间
return EINVAL; return EINVAL;
} }
SCHEDULER_LOCK(intSave); SCHEDULER_LOCK(intSave);
taskCB = OsCurrTaskGet(); taskCB = OsCurrTaskGet();//获取当前任务
processCB = OS_PCB_FROM_PID(taskCB->processID); processCB = OS_PCB_FROM_PID(taskCB->processID);//获取当前进程
if (processCB->processMode != OS_USER_MODE) { if (processCB->processMode != OS_USER_MODE) {//当前进程不能是用户模式
ret = EPERM; ret = EPERM;
goto OUT; goto OUT;
} }
taskCB->userArea = (unsigned long)(uintptr_t)area; taskCB->userArea = (unsigned long)(uintptr_t)area;//task的使用区域
OUT: OUT:
SCHEDULER_UNLOCK(intSave); SCHEDULER_UNLOCK(intSave);
return ret; return ret;
} }
//获取系统调用线程的使用区域
char *SysGetThreadArea(void) char *SysGetThreadArea(void)
{ {
return (char *)(OsCurrTaskGet()->userArea); return (char *)(OsCurrTaskGet()->userArea);//直接返回使用区域
} }
int SysUserThreadSetDeatch(unsigned int taskID) int SysUserThreadSetDeatch(unsigned int taskID)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册