用户态,内核态代码注解

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    https://my.oschina.net/weharmony
上级 6eb1acd5
......@@ -74,7 +74,7 @@ VOID OsTaskEntrySetupLoopFrame(UINT32 arg0)
"\tpop {fp, pc}\n");
}
#endif
//内核态运行栈初始化
//内核态任务运行栈初始化
LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag)
{
UINT32 index = 1;
......@@ -89,11 +89,12 @@ LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOI
#ifdef LOSCFG_GDB
taskContext->PC = (UINTPTR)OsTaskEntrySetupLoopFrame;
#else
taskContext->PC = (UINTPTR)OsTaskEntry;//程序计数器,CPU首次执行task时跑的第一条指令位置
taskContext->PC = (UINTPTR)OsTaskEntry;//内核态任务有统一的入口地址.
#endif
taskContext->LR = (UINTPTR)OsTaskExit; /* LR should be kept, to distinguish it's THUMB or ARM instruction */
taskContext->resved = 0x0;
taskContext->R[0] = taskID; /* R0 */
taskContext->R[0] = taskID; /* R0 *///因为所有内核态的任务处理函数入口都是一样的,
//OsTaskEntry(UINT32 taskID)需要传递任务ID作为参数来检索调用哪个任务的处理函数.
taskContext->R[index++] = 0x01010101; /* R1, 0x01010101 : reg initialed magic word */ //0x55
for (; index < GEN_REGS_NUM; index++) {//R2 - R12的初始化很有意思,为什么要这么做?
taskContext->R[index] = taskContext->R[index - 1] + taskContext->R[1]; /* R2 - R12 */
......@@ -127,7 +128,10 @@ LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(LosTaskCB *childTaskCB, LosTaskCB *
(VOID)memcpy_s(childTaskCB->stackPointer, sizeof(TaskContext), cloneStack, sizeof(TaskContext));//直接把任务上下文拷贝了一份
context->R[0] = 0;//R0寄存器为0,这个很重要, pid = fork() pid == 0 是子进程返回.
}
//用户态运行栈初始化
/*
用户态运行栈初始化,此时上下文还在内核区
*/
LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_FUNC taskEntry, UINTPTR stack)
{
LOS_ASSERT(context != NULL);
......@@ -137,10 +141,10 @@ LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_F
#else
context->regPSR = PSR_MODE_USR_ARM;//工作模式:用户模式 + 工作状态:arm
#endif
context->R[0] = stack;//栈指针给r0寄存器
context->SP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE);//异常模式所专用的堆栈 segment fault 输出回溯信息
context->R[0] = stack;//因为要回到用户态空间运行,所以要作为参数传回SP值
context->SP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE);//改变 上下文的SP值,指向用户栈空间
context->LR = 0;//保存子程序返回地址 例如 a call b ,在b中保存 a地址
context->PC = (UINTPTR)taskEntry;//入口函数
context->PC = (UINTPTR)taskEntry;//入口函数,由外部传入,由上层应用指定,固然每个都不一样.
}
VOID Sev(VOID)
......
......@@ -432,7 +432,7 @@ STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
if (!LOS_ListEmpty(&processCB->childrenList)) {//如果存在孩子进程
childHead = processCB->childrenList.pstNext;
LOS_ListDelete(&(processCB->childrenList));
if (OsProcessIsUserMode(processCB)) {//是用户模式吗?
if (OsProcessIsUserMode(processCB)) {//是用户态进程
parentID = g_userInitProcess;//指定1号进程父ID
} else {
parentID = g_kernelInitProcess;//指定2号进程为父ID
......@@ -530,10 +530,10 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsProcessInit(VOID)
LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList);//注意g_freeProcess挂的是pendList节点,所以使用要通过OS_PCB_FROM_PENDLIST找到进程实体.
}
g_userInitProcess = 1; /* 1: The root process ID of the user-mode process is fixed at 1 *///用户模式的根进程
g_userInitProcess = 1; /* 1: The root process ID of the user-mode process is fixed at 1 *///用户的根进程
LOS_ListDelete(&g_processCBArray[g_userInitProcess].pendList);// 清空g_userInitProcess pend链表
g_kernelInitProcess = 2; /* 2: The root process ID of the kernel-mode process is fixed at 2 *///内核模式的根进程
g_kernelInitProcess = 2; /* 2: The root process ID of the kernel-mode process is fixed at 2 *///内核的根进程
LOS_ListDelete(&g_processCBArray[g_kernelInitProcess].pendList);// 清空g_kernelInitProcess pend链表
return LOS_OK;
......@@ -722,7 +722,7 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, U
LOS_ListInit(&processCB->threadPriQueueList[count]); //初始化一个个线程队列,队列中存放就绪状态的线程/task
}//在鸿蒙内核中 task就是thread,在鸿蒙源码分析系列篇中有详细阐释 见于 https://my.oschina.net/u/3751245
if (OsProcessIsUserMode(processCB)) {// 是否为用户模式进程
if (OsProcessIsUserMode(processCB)) {// 是否为用户进程
space = LOS_MemAlloc(m_aucSysMem0, sizeof(LosVmSpace));//分配一个虚拟空间
if (space == NULL) {
PRINT_ERR("%s %d, alloc space failed\n", __FUNCTION__, __LINE__);
......@@ -747,7 +747,7 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, U
processCB->vmSpace = space;//设为进程虚拟空间
LOS_ListAdd(&processCB->vmSpace->archMmu.ptList, &(vmPage->node));//将空间映射页表挂在 空间的mmu L1页表, L1为表头
} else {
processCB->vmSpace = LOS_GetKVmSpace();//内核共用一个虚拟空间,内核进程 常驻内存
processCB->vmSpace = LOS_GetKVmSpace();//内核共用一个虚拟空间,内核进程常驻内存
}
#ifdef LOSCFG_SECURITY_VID
......@@ -887,7 +887,7 @@ EXIT:
OsDeInitPCB(processCB);//删除进程控制块,归还内存
return ret;
}
//初始化 2号进程,即内核根进程
//初始化 2号进程,即内核态进程的老祖宗
LITE_OS_SEC_TEXT_INIT UINT32 OsKernelInitProcess(VOID)
{
LosProcessCB *processCB = NULL;
......@@ -1466,7 +1466,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetCurrProcessGroupID(VOID)
{
return LOS_GetProcessGroupID(OsCurrProcessGet()->processID);
}
//用户进程分配栈并初始化
//为用户态任务分配栈空间
STATIC VOID *OsUserInitStackAlloc(UINT32 processID, UINT32 *size)
{
LosVmMapRegion *region = NULL;
......@@ -1489,7 +1489,6 @@ STATIC VOID *OsUserInitStackAlloc(UINT32 processID, UINT32 *size)
}
/**************************************************
进程的回收再利用,被LOS_DoExecveFile调用
**************************************************/
LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name,
LosVmSpace *oldSpace, UINTPTR oldFiles)
......@@ -1573,8 +1572,8 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT
taskCB = OsCurrTaskGet();//获取当前任务
processCB->threadGroupID = taskCB->taskID;//threadGroupID是进程的主线程ID,也就是应用程序 main函数线程
taskCB->userMapBase = mapBase;//任务栈底地址
taskCB->userMapSize = mapSize;//任务栈大小
taskCB->userMapBase = mapBase;//任务用户态栈底地址
taskCB->userMapSize = mapSize;//任务用户态栈大小
taskCB->taskEntry = (TSK_ENTRY_FUNC)entry;//任务的入口函数
taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize, (VOID *)taskCB->topOfStack, FALSE);//创建任务上下文
......@@ -1642,7 +1641,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID)
(VOID)memset_s((VOID *)((UINTPTR)userText + userInitBssStart - userInitTextStart), initBssSize, 0, initBssSize);// 除了代码段,其余都清0
stack = OsUserInitStackAlloc(g_userInitProcess, &size);// 初始化堆栈区
stack = OsUserInitStackAlloc(g_userInitProcess, &size);//分配任务在用户态下的运行栈,大小为1M,注意此内存来自进程空间,而非内核空间.
if (stack == NULL) {
PRINTK("user init process malloc user stack failed!\n");
ret = LOS_NOK;
......@@ -1650,9 +1649,9 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID)
}
param.pfnTaskEntry = (TSK_ENTRY_FUNC)userInitTextStart;// 从代码区开始执行,也就是应用程序main 函数的位置
param.userParam.userSP = (UINTPTR)stack + size;// 指向栈顶
param.userParam.userMapBase = (UINTPTR)stack;// 栈底
param.userParam.userMapSize = size;// 栈大小
param.userParam.userSP = (UINTPTR)stack + size;// 用户态栈底
param.userParam.userMapBase = (UINTPTR)stack;// 用户态栈顶
param.userParam.userMapSize = size;// 用户态栈大小
param.uwResved = OS_TASK_FLAG_PTHREAD_JOIN;// 可结合的(joinable)能够被其他线程收回其资源和杀死
ret = OsUserInitProcessStart(g_userInitProcess, &param);// 创建一个任务,来运行main函数
if (ret != LOS_OK) {
......
......@@ -585,11 +585,11 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCreateParamCheck(const UINT32 *taskID,
}
}
if (initParam->pfnTaskEntry == NULL) {
if (initParam->pfnTaskEntry == NULL) {//入口函数不能为空
return LOS_ERRNO_TSK_ENTRY_NULL;
}
if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) {
if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) {//优先级必须大于31
return LOS_ERRNO_TSK_PRIOR_ERROR;
}
......@@ -599,16 +599,16 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCreateParamCheck(const UINT32 *taskID,
poolSize = OS_EXC_INTERACTMEM_SIZE;
}
#endif
if (initParam->uwStackSize > poolSize) {
if (initParam->uwStackSize > poolSize) {//希望申请的栈大小不能大于总池子
return LOS_ERRNO_TSK_STKSZ_TOO_LARGE;
}
if (initParam->uwStackSize == 0) {
if (initParam->uwStackSize == 0) {//运行栈空间不能为0
initParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
}
initParam->uwStackSize = (UINT32)ALIGN(initParam->uwStackSize, LOSCFG_STACK_POINT_ALIGN_SIZE);
if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) {
if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) {//运行栈空间不能低于最低值
return LOS_ERRNO_TSK_STKSZ_TOO_SMALL;
}
......@@ -804,18 +804,20 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_IN
UINT16 mode;
LosProcessCB *processCB = NULL;
OsTaskCBInitBase(taskCB, stackPtr, topStack, initParam);//初始化任务的基本信息
OsTaskCBInitBase(taskCB, stackPtr, topStack, initParam);//初始化任务的基本信息,
//taskCB->stackPointer = stackPtr ,用户态时将改写taskCB->stackPointer指向
SCHEDULER_LOCK(intSave);
processCB = OS_PCB_FROM_PID(initParam->processID);//通过ID获取PCB ,单核进程数最多64个
taskCB->processID = processCB->processID;//进程-线程的父子关系绑定
mode = processCB->processMode;//模式方式同步process
LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList));//挂入进程的线程链表
if (mode == OS_USER_MODE) {//用户模式
if (mode == OS_USER_MODE) {//任务支持用户态时,将改写 taskCB->stackPointer = initParam->userParam.userSP
taskCB->userArea = initParam->userParam.userArea;
taskCB->userMapBase = initParam->userParam.userMapBase;
taskCB->userMapSize = initParam->userParam.userMapSize;
OsUserTaskStackInit(taskCB->stackPointer, taskCB->taskEntry, initParam->userParam.userSP);//用户任务栈上下文初始化
OsUserTaskStackInit(taskCB->stackPointer, taskCB->taskEntry, initParam->userParam.userSP);//初始化用户态任务栈
//这里要注意,任务的上下文是始终保存在内核栈空间,但用户态时运行是在用户态的栈空间.(因为SP指向了用户态空间)
}
if (!processCB->threadNumber) {//进程线程数量为0时,
......@@ -887,18 +889,18 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S
goto LOS_ERREND_REWIND_TCB;
}
//OsTaskStackAlloc 只在LOS_TaskCreateOnly中被调用,此处是分配任务在内核态栈空间
OsTaskStackAlloc(&topStack, initParam->uwStackSize, pool);//为任务分配内核态栈空间
OsTaskStackAlloc(&topStack, initParam->uwStackSize, pool);//为任务分配内核栈空间,注意此内存来自系统内核空间
if (topStack == NULL) {
errRet = LOS_ERRNO_TSK_NO_MEMORY;
goto LOS_ERREND_REWIND_SYNC;
}
stackPtr = OsTaskStackInit(taskCB->taskID, initParam->uwStackSize, topStack, TRUE);//初始化任务栈
stackPtr = OsTaskStackInit(taskCB->taskID, initParam->uwStackSize, topStack, TRUE);//初始化内核态任务栈,返回栈SP位置
errRet = OsTaskCBInit(taskCB, initParam, stackPtr, topStack);//初始化TCB,包括绑定进程等操作
if (errRet != LOS_OK) {
goto LOS_ERREND_TCB_INIT;
}
if (OsConsoleIDSetHook != NULL) {//每个任务都可以有属于自己的控制台
if (OsConsoleIDSetHook != NULL) {//每个任务都可以有属于自己的控制台
OsConsoleIDSetHook(taskCB->taskID, OsCurrTaskGet()->taskID);//设置控制台ID
}
......@@ -936,7 +938,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in
if (initParam->uwResved & OS_TASK_FLAG_IDLEFLAG) {//OS_TASK_FLAG_IDLEFLAG 是属于内核 idle进程专用的
initParam->processID = OsGetIdleProcessID();//获取空闲进程
} else if (OsProcessIsUserMode(OsCurrProcessGet())) {//当前进程是否为用户模式
initParam->processID = OsGetKernelInitProcessID();//是就取"Kernel"进程
initParam->processID = OsGetKernelInitProcessID();//任务归属于"Kernel"进程
} else {
initParam->processID = OsCurrProcessGet()->processID;//获取当前进程 ID赋值
}
......@@ -1929,7 +1931,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID,
return LOS_OK;
}
//创建一个用户任务
//创建一个用户任务
LITE_OS_SEC_TEXT_INIT INT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam)
{
LosProcessCB *processCB = NULL;
......
......@@ -315,8 +315,8 @@ STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)//查下进程
#define OS_USER_TASK_SYSCALL_SATCK_SIZE 0x3000 //用户通过系统调用的栈大小 12K ,这时是运行在内核模式下
#define OS_USER_TASK_STACK_SIZE 0x100000 //用户任务运行在用户空间的栈大小 1M
#define OS_KERNEL_MODE 0x0U //内核模式
#define OS_USER_MODE 0x1U //用户模式
#define OS_KERNEL_MODE 0x0U //内核
#define OS_USER_MODE 0x1U //用户
STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)//用户模式进程
{
return (processCB->processMode == OS_USER_MODE);
......@@ -330,8 +330,8 @@ STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)//用户模
#define LOS_PRIO_PGRP 1U //进程组标识
#define LOS_PRIO_USER 2U //用户标识
#define OS_KERNEL_PROCESS_GROUP 2U //内核进程组
#define OS_USER_PRIVILEGE_PROCESS_GROUP 1U //用户特权进程组
#define OS_KERNEL_PROCESS_GROUP 2U //内核进程组
#define OS_USER_PRIVILEGE_PROCESS_GROUP 1U //用户特权进程组
/*
* Process exit code
......@@ -464,7 +464,7 @@ STATIC INLINE User *OsCurrUserGet(VOID)//获取当前进程的所属用户
#define OS_PROCESS_INFO_ALL 1
#define OS_PROCESS_DEFAULT_UMASK 0022
extern UINTPTR __user_init_entry; // 第一个用户态进程入口地址 查看 LITE_USER_SEC_ENTRY
extern UINTPTR __user_init_entry; // 第一个用户态任务的入口地址 查看 LITE_USER_SEC_ENTRY
extern UINTPTR __user_init_bss; // 查看 LITE_USER_SEC_BSS
extern UINTPTR __user_init_end; //
extern UINTPTR __user_init_load_addr;
......
......@@ -104,8 +104,8 @@ https://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html
#define OS_SYSCALL_GET_CPSR(regs) (*((unsigned long *)((UINTPTR)(regs) - 4)))
#define SIG_STOP_VISIT 1
#define OS_KERNEL_KILL_PERMISSION 0U //内核 kill 权限
#define OS_USER_KILL_PERMISSION 3U //用户 kill 权限
#define OS_KERNEL_KILL_PERMISSION 0U //内核 kill 权限
#define OS_USER_KILL_PERMISSION 3U //用户 kill 权限
#define OS_RETURN_IF(expr, errcode) \
if ((expr)) { \
......
......@@ -294,13 +294,13 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
#define OS_TCB_NAME_LEN 32
typedef struct {
VOID *stackPointer; /**< Task stack pointer */ //内核态栈指针,SP位置,切换任务时先保存上下文并指向TaskContext位置.
VOID *stackPointer; /**< Task stack pointer */ //栈指针,SP位置,切换任务时先保存上下文并指向TaskContext位置.
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 */ //内核态栈顶 bottom = top + size
UINT32 stackSize; /**< Task stack size */ //栈大小,内存来自内核空间
UINTPTR topOfStack; /**< Task stack top */ //栈顶 bottom = top + size,内存来自内核空间
UINT32 taskID; /**< Task ID */ //任务ID,任务池本质是一个大数组,ID就是数组的索引,默认 < 128
TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */ //任务执行入口函数
VOID *joinRetval; /**< pthread adaption */ //用来存储join线程的返回值
......@@ -335,7 +335,7 @@ typedef struct {
#endif
#endif
UINTPTR userArea; //用户区域,由运行时划定,根据运行态不同而不同
UINTPTR userMapBase; //用户模式下的栈底位置
UINTPTR userMapBase; //内存来自进程空间,用户态下的栈底位置,和topOfStack有本质的区别.
UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */
UINT32 processID; /**< Which belong process *///所属进程ID
FutexNode futex; //实现快锁功能
......
......@@ -160,7 +160,7 @@ typedef struct VmSpace {
#define VM_MAP_REGION_FLAG_UNCACHED_DEVICE (2<<0) /* only exists on some arches, otherwise UNCACHED */
#define VM_MAP_REGION_FLAG_WRITE_COMBINING (3<<0) /* only exists on some arches, otherwise UNCACHED */
#define VM_MAP_REGION_FLAG_CACHE_MASK (3<<0) //缓冲区掩码
#define VM_MAP_REGION_FLAG_PERM_USER (1<<2) //可使用
#define VM_MAP_REGION_FLAG_PERM_USER (1<<2) //用户
#define VM_MAP_REGION_FLAG_PERM_READ (1<<3) //可读取区
#define VM_MAP_REGION_FLAG_PERM_WRITE (1<<4) //可写入区
#define VM_MAP_REGION_FLAG_PERM_EXECUTE (1<<5) //可被执行区
......
......@@ -337,7 +337,7 @@ int OsDispatch(pid_t pid, siginfo_t *info, int permission)
}
}
#endif
if ((permission == OS_USER_KILL_PERMISSION) && (OsSignalPermissionToCheck(spcb) < 0)) {//
if ((permission == OS_USER_KILL_PERMISSION) && (OsSignalPermissionToCheck(spcb) < 0)) {
return -EPERM;
}
return OsSigProcessSend(spcb, info);//给参数进程发送信号
......
......@@ -478,11 +478,11 @@ typedef VOID *(*TSK_ENTRY_FUNC)(UINTPTR param1,
* @ingroup los_task
* You are not allowed to add any fields and adjust fields to the structure
*/
typedef struct {
UINTPTR userArea;//用户区域
UINTPTR userSP; //用户态下栈指针
UINTPTR userMapBase;//用户态下映射基地址
UINT32 userMapSize;//用户态下映射大小
typedef struct {//用户态栈信息,(按递减满栈方式注解)
UINTPTR userArea; //用户区域
UINTPTR userSP; //用户态下栈底位置
UINTPTR userMapBase;//用户态下映射基地址,代表栈顶位置.
UINT32 userMapSize;//用户态下映射大小,代表栈大小
} UserTaskParam;
/**
......@@ -496,7 +496,7 @@ typedef struct tagTskInitParam {//Task的初始化参数
UINT16 usTaskPrio; /**< Task priority */ //任务优先级
UINT16 policy; /**< Task policy */ //任务调度方式
UINTPTR auwArgs[4]; /**< Task parameters, of which the maximum number is four */ //入口函数的参数,最多四个
UINT32 uwStackSize; /**< Task stack size */ //任务栈大小
UINT32 uwStackSize; /**< Task stack size */ //内核栈大小
CHAR *pcName; /**< Task name */ //任务名称
#if (LOSCFG_KERNEL_SMP == YES)
UINT16 usCpuAffiMask; /**< Task cpu affinity mask */ //任务cpu亲和力掩码
......@@ -505,7 +505,7 @@ typedef struct tagTskInitParam {//Task的初始化参数
It is unable to be deleted if set to 0. */ //如果设置为LOS_TASK_STATUS_DETACHED,则自动删除。如果设置为0,则无法删除
UINT16 consoleID; /**< The console id of task belongs */ //任务的控制台id所属
UINT32 processID; //进程ID
UserTaskParam userParam; //用户态运行时栈参数
UserTaskParam userParam; //任务用户态运行时栈参数
} TSK_INIT_PARAM_S;
/**
......
git add -A
git commit -m 'v45.01 (fork篇) | fork是如何做到调用一次,返回两次的 ?
git commit -m '用户态,内核态代码注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://my.oschina.net/weharmony
'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册