From 305f40e848a0b5fce6433db642c6a2d4e86b6b85 Mon Sep 17 00:00:00 2001 From: pqk2c5h8v <3232796758@qq.com> Date: Mon, 4 Dec 2023 21:36:03 +0800 Subject: [PATCH 1/3] ADD file via upload --- process(800-1200).docx | Bin 0 -> 10895 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 process(800-1200).docx diff --git a/process(800-1200).docx b/process(800-1200).docx new file mode 100644 index 0000000000000000000000000000000000000000..e358788d49c765d2724de09df50840733b34e9b7 GIT binary patch literal 10895 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 AfB*mh literal 0 HcmV?d00001 From 594279cc80b4f6088b423c6956de0cf49ffeb6d8 Mon Sep 17 00:00:00 2001 From: pqk2c5h8v <3232796758@qq.com> Date: Mon, 4 Dec 2023 21:36:19 +0800 Subject: [PATCH 2/3] ADD file via upload --- process(800-1200).cpp | 426 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 426 insertions(+) create mode 100644 process(800-1200).cpp diff --git a/process(800-1200).cpp b/process(800-1200).cpp new file mode 100644 index 0000000..32abce8 --- /dev/null +++ b/process(800-1200).cpp @@ -0,0 +1,426 @@ +```c +// 去掉初始化标签 +kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT; +g_processGroup = kerInitProcess->group; +LOS_ListInit(&g_processGroup->groupList); +OsCurrProcessSet(kerInitProcess); + +// 创建内核态0号进程 +LosProcessCB *idleProcess = OS_PCB_FROM_PID(g_kernelIdleProcess); +ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, OS_TASK_PRIORITY_LOWEST, "KIdle"); +if (ret != LOS_OK) { + return ret; +} +idleProcess->parentProcessID = kerInitProcess->processID; +LOS_ListTailInsert(&kerInitProcess->childrenList, &idleProcess->siblingList); +idleProcess->group = kerInitProcess->group; +LOS_ListTailInsert(&kerInitProcess->group->processList, &idleProcess->subordinateGroupList); + +#ifdef LOSCFG_SECURITY_CAPABILITY +idleProcess->user = kerInitProcess->user; +#endif + +#ifdef LOSCFG_FS_VFS +idleProcess->files = kerInitProcess->files; +#endif + +// 创建空闲任务并将其指定给内核态0号进程 +ret = OsIdleTaskCreate(); +if (ret != LOS_OK) { + return ret; +} +idleProcess->threadGroupID = OsPercpuGet()->idleTaskID; + +return LOS_OK; +``` + +```c +// 进程调度参数检查 +STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 prio, UINT16 policy) +{ + if (OS_PID_CHECK_INVALID(pid)) { + return LOS_EINVAL; + } + + if (which != LOS_PRIO_PROCESS) { + return LOS_EINVAL; + } + + if (prio > OS_PROCESS_PRIORITY_LOWEST) { + return LOS_EINVAL; + } + + if (policy != LOS_SCHED_RR) { + return LOS_EINVAL; + } + + return LOS_OK; +} + +#ifdef LOSCFG_SECURITY_CAPABILITY +STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, UINT16 prio) +{ + LosProcessCB *runProcess = OsCurrProcessGet(); + + // 对于内核态进程直接通过检查 + if (!OsProcessIsUserMode(runProcess)) { + return TRUE; + } + + // 用户态进程可以降低自己的优先级 + if ((runProcess->processID == processCB->processID) && (prio > processCB->priority)) { + return TRUE; + } + + // 如果具有 CAP_SCHED_SETPRIORITY 权限,可以修改进程的优先级 + if (IsCapPermit(CAP_SCHED_SETPRIORITY)) { + return TRUE; + } + return FALSE; +} +#endif + +LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy) +{ + LosProcessCB *processCB = NULL; + BOOL needSched = FALSE; + UINT32 intSave; + INT32 ret; + + ret = OsProcessSchedlerParamCheck(which, pid, prio, policy); + if (ret != LOS_OK) { + return -ret; + } + + SCHEDULER_LOCK(intSave); + processCB = OS_PCB_FROM_PID(pid); + + // 如果进程未激活,则返回错误 + if (OsProcessIsInactive(processCB)) { + ret = LOS_ESRCH; + goto EXIT; + } + +#ifdef LOSCFG_SECURITY_CAPABILITY + // 如果权限不足,则返回错误 + if (!OsProcessCapPermitCheck(processCB, prio)) { + ret = LOS_EPERM; + goto EXIT; + } +#endif + + // 修改进程调度参数,判断是否需要进行调度 + needSched = OsSchedModifyProcessSchedParam(processCB, policy, prio); + SCHEDULER_UNLOCK(intSave); + + // 调度其他核上的进程 + LOS_MpSchedule(OS_MP_CPU_ALL); + + // 如果需要调度且调度器已经激活,则进行调度 + if (needSched && OS_SCHEDULER_ACTIVE) { + LOS_Schedule(); + } + return LOS_OK; + +EXIT: + SCHEDULER_UNLOCK(intSave); + return -ret; +} + +LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, UINT16 prio) +{ + return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, prio, policy); +} + +LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid) +{ + UINT32 intSave; + + if (OS_PID_CHECK_INVALID(pid)) { + return -LOS_EINVAL; + } + + SCHEDULER_LOCK(intSave); + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + + // 如果进程未使用,则返回错误 + if (OsProcessIsUnused(processCB)) { + SCHEDULER_UNLOCK(intSave); + return -LOS_ESRCH; + } + + SCHEDULER_UNLOCK(intSave); + + return LOS_SCHED_RR; +} + +LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, UINT16 prio) +{ + return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, prio, LOS_GetProcessScheduler(pid)); +} + +LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid) +{ + LosProcessCB *processCB = NULL; + INT32 prio; + UINT32 intSave; + (VOID)which; + + if (OS_PID_CHECK_INVALID(pid)) { + return -LOS_EINVAL; + } + + if (which != LOS_PRIO_PROCESS) { + return -LOS_EINVAL; + } + + SCHEDULER_LOCK(intSave); + processCB = OS_PCB_FROM_PID(pid); + + // 如果进程未使用,则返回错误 + if (OsProcessIsUnused(processCB)) { + prio = -LOS_ESRCH; + goto OUT; + } + + prio = (INT32)processCB->priority; + +OUT: + SCHEDULER_UNLOCK(intSave); + return prio; +} + +LITE_OS_SEC_TEXT INT32 LOS_GetProcessPriority(INT32 pid) +{ + return OsGetProcessPriority(LOS_PRIO_PROCESS, pid); +} + +// 将运行任务插入等待列表 +STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *processCB) +{ + LOS_DL_LIST *head = &processCB->waitList; + LOS_DL_LIST *list = head; + LosTaskCB *taskCB = NULL; + + if (runTask->waitFlag == OS_PROCESS_WAIT_GID) { + while (list->pstNext != head) { + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list)); + + // 如果等待标记为 OS_PROCESS_WAIT_PRO,则继续查找下一个等待队列 + if (taskCB->waitFlag == OS_PROCESS_WAIT_PRO) { + list = list->pstNext; + continue; + } + break; + } + } else if (runTask->waitFlag == OS_PROCESS_WAIT_ANY) { + while (list->pstNext != head) { + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list)); + + // 如果等待标记不为 OS_PROCESS_WAIT_ANY,则继续查找下一个等待队列 + if (taskCB->waitFlag != OS_PROCESS_WAIT_ANY) { + list = list->pstNext; + continue; + } + break; + } + } +} + +``` +// 等待指定的子进程退出 +STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcessCB **child) +{ + LosProcessCB *childCB = NULL; + ProcessGroup *group = NULL; + LosTaskCB *runTask = OsCurrTaskGet(); // 获取当前运行的任务控制块 + UINT32 ret; + + if (pid > 0) { + // 等待具有指定进程号的子进程退出 + childCB = OsFindExitChildProcess(processCB, pid); // 查找具有指定进程号的已退出的子进程 + if (childCB != NULL) { + goto WAIT_BACK; // 子进程已退出,则跳转到WAIT_BACK标签处 + } + + ret = OsFindChildProcess(processCB, pid); // 查找具有指定进程号的子进程是否存在 + if (ret != LOS_OK) { + return LOS_ECHILD; // 没有找到指定进程号的子进程,返回错误码LOS_ECHILD + } + runTask->waitFlag = OS_PROCESS_WAIT_PRO; // 设置当前任务的等待标志为进程号 + runTask->waitID = pid; // 设置当前任务等待的进程号为指定进程号 + } else if (pid == 0) { + // 等待同一进程组中的任何子进程退出 + childCB = OsFindGroupExitProcess(processCB->group, OS_INVALID_VALUE); // 查找同一进程组中的已退出的子进程 + if (childCB != NULL) { + goto WAIT_BACK; // 子进程已退出,则跳转到WAIT_BACK标签处 + } + runTask->waitID = processCB->group->groupID; // 设置当前任务等待的进程号为进程组号 + runTask->waitFlag = OS_PROCESS_WAIT_GID; // 设置当前任务的等待标志为进程组号 + } else if (pid == -1) { + // 等待任何子进程退出 + childCB = OsFindExitChildProcess(processCB, OS_INVALID_VALUE); // 查找任何已退出的子进程 + if (childCB != NULL) { + goto WAIT_BACK; // 子进程已退出,则跳转到WAIT_BACK标签处 + } + runTask->waitID = pid; // 设置当前任务等待的进程号为-1 + runTask->waitFlag = OS_PROCESS_WAIT_ANY; // 设置当前任务的等待标志为任何子进程 + } else { // pid < -1 + // 等待进程组号为pid绝对值的任何子进程退出 + group = OsFindProcessGroup(-pid); // 查找具有指定进程组号的进程组 + if (group == NULL) { + return LOS_ECHILD; // 没有找到指定进程组号的进程组,返回错误码LOS_ECHILD + } + + childCB = OsFindGroupExitProcess(group, OS_INVALID_VALUE); // 查找指定进程组中已退出的子进程 + if (childCB != NULL) { + goto WAIT_BACK; // 子进程已退出,则跳转到WAIT_BACK标签处 + } + + runTask->waitID = -pid; // 设置当前任务等待的进程号为进程组号的绝对值 + runTask->waitFlag = OS_PROCESS_WAIT_GID; // 设置当前任务的等待标志为进程组号 + } + +WAIT_BACK: + *child = childCB; // 返回已退出的子进程 + return LOS_OK; +} + +// 回收已退出的子进程资源,并返回进程号 +STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info) +{ + ProcessGroup *group = NULL; + UINT32 pid = childCB->processID; // 子进程的进程号 + UINT16 mode = childCB->processMode; // 子进程的运行模式 + INT32 exitCode = childCB->exitCode; // 子进程的退出码 + UINT32 uid = 0; + +#ifdef LOSCFG_SECURITY_CAPABILITY + if (childCB->user != NULL) { + uid = childCB->user->userID; // 子进程的用户ID + } +#endif + + OsRecycleZombiesProcess((LosProcessCB *)childCB, &group); // 回收已退出的子进程资源,并获取进程组 + + SCHEDULER_UNLOCK(intSave); // 解锁调度器 + + if (status != NULL) { + if (mode == OS_USER_MODE) { + (VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32)); // 拷贝退出码到用户空间 + } else { + *status = exitCode; // 将退出码保存到status中 + } + } + /* get signal info */ + if (info != NULL) { + siginfo_t tempinfo = { 0 }; + + tempinfo.si_signo = SIGCHLD; + tempinfo.si_errno = 0; + tempinfo.si_pid = pid; + tempinfo.si_uid = uid; + /* + * Process exit code + * 31 15 8 7 0 + * | | exit code | core dump | signal | + */ + if ((exitCode & 0x7f) == 0) { + tempinfo.si_code = CLD_EXITED; + tempinfo.si_status = (exitCode >> 8U); + } else { + tempinfo.si_code = (exitCode & 0x80) ? CLD_DUMPED : CLD_KILLED; + tempinfo.si_status = (exitCode & 0x7f); + } + + if (mode == OS_USER_MODE) { + (VOID)LOS_ArchCopyToUser((VOID *)(info), (const VOID *)(&(tempinfo)), sizeof(siginfo_t)); // 拷贝信号信息到用户空间 + } else { + (VOID)memcpy_s((VOID *)(info), sizeof(siginfo_t), (const VOID *)(&(tempinfo)), sizeof(siginfo_t)); + } + } + (VOID)LOS_MemFree(m_aucSysMem1, group); // 释放进程组资源 + return pid; // 返回子进程的进程号 +} + +// 检查等待子进程的具体信息 +STATIC UINT32 OsWaitChildProcessCheck(LosProcessCB *processCB, INT32 pid, LosProcessCB **childCB) +{ + if (LOS_ListEmpty(&(processCB->childrenList)) && LOS_ListEmpty(&(processCB->exitChildList))) { + return LOS_ECHILD; // 没有子进程,则返回错误码LOS_ECHILD + } + + return OsWaitSetFlag(processCB, pid, childCB); // 设置等待标志等信息 +} + +// 检查等待选项是否正确 +STATIC UINT32 OsWaitOptionsCheck(UINT32 options) +{ + UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WUNTRACED | LOS_WAIT_WCONTINUED; + + flag = ~flag & options; + if (flag != 0) { + return LOS_EINVAL; // 选项不正确,返回错误码LOS_EINVAL + } + + if ((options & (LOS_WAIT_WCONTINUED | LOS_WAIT_WUNTRACED)) != 0) { + return LOS_EOPNOTSUPP; // 不支持的选项,返回错误码LOS_EOPNOTSUPP + } + + if (OS_INT_ACTIVE) { + return LOS_EINTR; // 当前处于中断上下文中,返回错误码LOS_EINTR + } + + return LOS_OK; // 选项正确,返回LOS_OK +} + +// 等待子进程退出 +STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage) +{ + (VOID)rusage; + UINT32 ret; + UINT32 intSave; + LosProcessCB *childCB = NULL; + LosProcessCB *processCB = NULL; + LosTaskCB *runTask = NULL; + + SCHEDULER_LOCK(intSave); // 加锁调度器 + processCB = OsCurrProcessGet(); // 获取当前进程控制块 + runTask = OsCurrTaskGet(); // 获取当前任务控制块 + + ret = OsWaitChildProcessCheck(processCB, pid, &childCB); // 检查等待子进程的具体信息 + if (ret != LOS_OK) { + pid = -ret; // 若等待子进程的标志不正确,将错误码赋值给pid + goto ERROR; + } + + if (childCB != NULL) { + return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info); // 回收已退出的子进程资源并返回进程号 + } + + if ((options & LOS_WAIT_WNOHANG) != 0) { + runTask->waitFlag = 0; // 不阻塞任务 + pid = 0; + goto ERROR; + } + + OsWaitInsertWaitListInOrder(runTask, processCB); // 将当前任务插入等待列表中 + + runTask->waitFlag = 0; + if (runTask->waitID == OS_INVALID_VALUE) { + pid = -LOS_ECHILD; // 没有子进程需要等待,返回错误码LOS_ECHILD + goto ERROR; + } + + childCB = OS_PCB_FROM_PID(runTask->waitID); // 根据等待的进程号获取子进程控制块 + if (!(childCB->processStatus & OS_PROCESS_STATUS_ZOMBIES)) { + pid = -LOS_ESRCH; // 子进程没有退出,返回错误码LOS_ESRCH + goto ERROR; + } + + return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info); // 回收已退出的子进程资源并返回进程号 + +ERROR: + SCHEDULER_UNLOCK(intSave); // 解锁调度器 + return pid; +} \ No newline at end of file From bbb74e871835cd840ab8ae2eedcd9a3d8ae32f88 Mon Sep 17 00:00:00 2001 From: pvrb8ka45 <1664581173@qq.com> Date: Mon, 4 Dec 2023 22:41:29 +0800 Subject: [PATCH 3/3] process1520-2000 --- process1520-2000.c | 460 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 460 insertions(+) create mode 100644 process1520-2000.c diff --git a/process1520-2000.c b/process1520-2000.c new file mode 100644 index 0000000..ebd7a64 --- /dev/null +++ b/process1520-2000.c @@ -0,0 +1,460 @@ +STATIC UINT32 OsLoadUserInit(LosProcessCB *processCB) +{ + /* userInitTextStart ----- + * | user text |//定义起始位置的指针变量// + * + * | user data | initSize + * userInitBssStart ---//定义结束位置的指针变量// + * | user bss | initBssSize + * userInitEnd --- ----- + */ + errno_t errRet; + INT32 ret; + CHAR *userInitTextStart = (CHAR *)&__user_init_entry; + CHAR *userInitBssStart = (CHAR *)&__user_init_bss; + CHAR *userInitEnd = (CHAR *)&__user_init_end; + UINT32 initBssSize = userInitEnd - userInitBssStart;//计算 BSS 段(未初始化数据段)的大小 initBssSize// + UINT32 initSize = userInitEnd - userInitTextStart;//计算和整个初始化段(包括 text、data 和 bss)的大小 // + VOID *userBss = NULL; + VOID *userText = NULL; + + if ((LOS_Align((UINTPTR)userInitTextStart, PAGE_SIZE) != (UINTPTR)userInitTextStart) || + (LOS_Align((UINTPTR)userInitEnd, PAGE_SIZE) != (UINTPTR)userInitEnd)) { + return LOS_EINVAL;//检查 userInitTextStart 和 userInitEnd 是否都按页对齐// + } + + if ((initSize == 0) || (initSize <= initBssSize)) { + return LOS_EINVAL;//检查 initSize 是否为零或者小于等于 initBssSize,如果是,则返回错误码 LOS_EINVAL// + } + + userText = LOS_PhysPagesAllocContiguous(initSize >> PAGE_SHIFT); + if (userText == NULL) { + return LOS_NOK;//使用 LOS_PhysPagesAllocContiguous 函数为用户空间初始化段分配连续的物理页面,并将地址赋值给 userText// + } + + errRet = memcpy_s(userText, initSize, (VOID *)&__user_init_load_addr, initSize - initBssSize); + if (errRet != EOK) { + PRINT_ERR("Load user init text, data and bss failed! err : %d\n", errRet); + goto ERROR;//使用 memcpy_s 将初始化段的 text 和 data 部分从 __user_init_load_addr 复制到新分配的 userText 指向的内存区域// + } + ret = LOS_VaddrToPaddrMmap(processCB->vmSpace, (VADDR_T)(UINTPTR)userInitTextStart, LOS_PaddrQuery(userText), + initSize, VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE | + VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_PERM_EXECUTE | + VM_MAP_REGION_FLAG_PERM_USER); + if (ret < 0) { + PRINT_ERR("Mmap user init text, data and bss failed! err : %d\n", ret); + goto ERROR;//使用 LOS_VaddrToPaddrMmap 函数将新分配的物理页面映射到进程的虚拟地址空间// + } + + /* The User init boot segment may not actually exist */ + if (initBssSize != 0) { + userBss = (VOID *)((UINTPTR)userText + userInitBssStart - userInitTextStart); + errRet = memset_s(userBss, initBssSize, 0, initBssSize); + if (errRet != EOK) { + PRINT_ERR("memset user init bss failed! err : %d\n", errRet); + goto ERROR;//如果存在 BSS 段(initBssSize 不为 0),则使用 memset_s 函数将 BSS 段的内存清零// + } + } + + return LOS_OK; + +ERROR: + (VOID)LOS_PhysPagesFreeContiguous(userText, initSize >> PAGE_SHIFT); + return LOS_NOK; +} + +LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) +{ + UINT32 ret; + UINT32 size; + TSK_INIT_PARAM_S param = { 0 }; + VOID *stack = NULL; + + LosProcessCB *processCB = OS_PCB_FROM_PID(g_userInitProcess); + ret = OsProcessCreateInit(processCB, OS_USER_MODE, "Init", OS_PROCESS_USERINIT_PRIORITY); + if (ret != LOS_OK) { + return ret; + } + + ret = OsLoadUserInit(processCB); + if (ret != LOS_OK) { + goto ERROR; + } + + stack = OsUserInitStackAlloc(processCB, &size); + if (stack == NULL) { + PRINT_ERR("Alloc user init process user stack failed!\n"); + goto ERROR;//如果在复制或内存映射过程中发生错误,会跳转到 ERROR 标签处理错误情况,释放已分配资源并返回错误码// + } + + param.pfnTaskEntry = (TSK_ENTRY_FUNC)(CHAR *)&__user_init_entry; + param.userParam.userSP = (UINTPTR)stack + size; + param.userParam.userMapBase = (UINTPTR)stack; + param.userParam.userMapSize = size; + param.uwResved = OS_TASK_FLAG_PTHREAD_JOIN; + ret = OsUserInitProcessStart(g_userInitProcess, ¶m); + if (ret != LOS_OK) { + (VOID)OsUnMMap(processCB->vmSpace, param.userParam.userMapBase, param.userParam.userMapSize); + goto ERROR; + } + + return LOS_OK;//如果一切顺利,函数最后返回 LOS_OK,表示用户空间初始化程序加载成功// + +ERROR: + OsDeInitPCB(processCB);//在发生错误时,调用此函数来清理进程控制块// + return ret;//返回错误码// +} + +STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB) +{ +#ifdef LOSCFG_SECURITY_CAPABILITY//执行用户信息的复制// + UINT32 size = sizeof(User) + sizeof(UINT32) * (parentCB->user->groupNumber - 1);//算需要复制的用户信息所需的内存大小// + childCB->user = LOS_MemAlloc(m_aucSysMem1, size);//为子进程分配内存来存储用户信息// + if (childCB->user == NULL) { + return LOS_ENOMEM;//如果分配失败,返回 LOS_ENOMEM 表示内存不足// + } + + (VOID)memcpy_s(childCB->user, size, parentCB->user, size);//使用 memcpy_s 将父进程的用户信息复制到子进程// +#endif + return LOS_OK;//返回 LOS_OK 表示成功// +} + +STATIC VOID OsInitCopyTaskParam(LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size, + TSK_INIT_PARAM_S *childPara) +{ + LosTaskCB *mainThread = NULL; + UINT32 intSave;//初始化子进程的任务参数// + + SCHEDULER_LOCK(intSave); + mainThread = OsCurrTaskGet();//锁定调度器以保证线程安全// + + if (OsProcessIsUserMode(childProcessCB)) { + childPara->pfnTaskEntry = mainThread->taskEntry; + childPara->uwStackSize = mainThread->stackSize; + childPara->userParam.userArea = mainThread->userArea; + childPara->userParam.userMapBase = mainThread->userMapBase; + childPara->userParam.userMapSize = mainThread->userMapSize;//根据子进程是否为用户模式,设置任务入口点、堆栈大小以及其他用户特定的参数// + } else { + childPara->pfnTaskEntry = (TSK_ENTRY_FUNC)entry; + childPara->uwStackSize = size; + } + childPara->pcName = (CHAR *)name; + childPara->policy = mainThread->policy; + childPara->usTaskPrio = mainThread->priority; + childPara->processID = childProcessCB->processID;//设置任务名称、调度策略、优先级等信息// + if (mainThread->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) { + childPara->uwResved = OS_TASK_FLAG_PTHREAD_JOIN; + } else if (mainThread->taskStatus & OS_TASK_FLAG_DETACHED) { + childPara->uwResved = OS_TASK_FLAG_DETACHED;//如果当前任务支持线程的 join 操作或者是 detached 状态,则相应地设置标志位// + } + + SCHEDULER_UNLOCK(intSave);//解锁调度器// +} + +STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size) +{//创建一个新的任务,作为子进程的主线程// + LosTaskCB *runTask = OsCurrTaskGet(); + TSK_INIT_PARAM_S childPara = { 0 }; + UINT32 ret; + UINT32 intSave; + UINT32 taskID; + + OsInitCopyTaskParam(childProcessCB, name, entry, size, &childPara); + + ret = LOS_TaskCreateOnly(&taskID, &childPara);//调用 LOS_TaskCreateOnly 来创建任务,仅创建任务而不立即运行// + if (ret != LOS_OK) { + if (ret == LOS_ERRNO_TSK_TCB_UNAVAILABLE) { + return LOS_EAGAIN; + } + return LOS_ENOMEM;//如果任务创建失败,根据错误类型返回相应的错误码(如 LOS_EAGAIN 表示资源暂时不可用,LOS_ENOMEM 表示内存不足)// + } + + LosTaskCB *childTaskCB = OS_TCB_FROM_TID(taskID);//获取新创建任务的任务控制块指针// + childTaskCB->taskStatus = runTask->taskStatus; + if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING; + } else { + if (OS_SCHEDULER_ACTIVE) { + LOS_Panic("Clone thread status not running error status: 0x%x\n", childTaskCB->taskStatus); + }//如果子任务的状态为运行状态,则清除运行状态位// + childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED; + childProcessCB->priority = OS_PROCESS_PRIORITY_LOWEST;//如果调度器处于激活状态并且子任务不在运行状态,触发内核恐慌// + } + + if (OsProcessIsUserMode(childProcessCB)) { + SCHEDULER_LOCK(intSave); + OsUserCloneParentStack(childTaskCB->stackPointer, runTask->topOfStack, runTask->stackSize); + SCHEDULER_UNLOCK(intSave); + } + return LOS_OK; +} + +STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) +{ + UINT32 ret; + UINT32 intSave; + LosProcessCB *parentProcessCB = NULL; + + SCHEDULER_LOCK(intSave);//锁定调度器以保证线程安全// + childProcessCB->priority = runProcessCB->priority; + + if (flags & CLONE_PARENT) { + parentProcessCB = OS_PCB_FROM_PID(runProcessCB->parentProcessID); + } else { + parentProcessCB = runProcessCB; + }//根据 flags 中的 CLONE_PARENT 位决定子进程的父进程是当前进程的父进程还是当前进程本身// + childProcessCB->parentProcessID = parentProcessCB->processID; + LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList); + childProcessCB->group = parentProcessCB->group; + LOS_ListTailInsert(&parentProcessCB->group->processList, &childProcessCB->subordinateGroupList); + ret = OsCopyUser(childProcessCB, parentProcessCB);//调用 OsCopyUser 函数复制用户信息// + + SCHEDULER_UNLOCK(intSave);//解锁调度器// + return ret; +} + +STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) +{ + status_t status; + UINT32 intSave; + + if (!OsProcessIsUserMode(childProcessCB)) { + return LOS_OK;//如果子进程不是用户模式,直接返回 LOS_OK// + } + + if (flags & CLONE_VM) { + SCHEDULER_LOCK(intSave); + childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb; + childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb; + SCHEDULER_UNLOCK(intSave); + return LOS_OK;//如果 flags 中的 CLONE_VM 位被设置,表示需要共享虚拟内存空间,那么将父进程的虚拟内存表指针复制给子进程,并返回 LOS_OK// + } + + status = LOS_VmSpaceClone(runProcessCB->vmSpace, childProcessCB->vmSpace); + if (status != LOS_OK) { + return LOS_ENOMEM; + } + return LOS_OK;//如果没有设置 CLONE_VM 位,则调用 LOS_VmSpaceClone 函数来克隆父进程的虚拟内存空间给子进程// +} + +STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB) +{ +#ifdef LOSCFG_FS_VFS + if (flags & CLONE_FILES) { + childProcessCB->files = runProcessCB->files; + } else { + childProcessCB->files = dup_fd(runProcessCB->files); + } + if (childProcessCB->files == NULL) { + return LOS_ENOMEM;//如果虚拟内存空间克隆失败,返回 LOS_ENOMEM 表示内存不足// + } +#endif + + childProcessCB->consoleID = runProcessCB->consoleID; + childProcessCB->umask = runProcessCB->umask; + return LOS_OK; +} + +STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINTPTR sp, UINT32 size) +{//初始化子进程的进程控制块(PCB)// + UINT32 ret; + LosProcessCB *run = OsCurrProcessGet(); + + ret = OsInitPCB(child, run->processMode, OS_PROCESS_PRIORITY_LOWEST, name); + if (ret != LOS_OK) { + return ret; + }//调用 OsInitPCB 来初始化 PCB 的基本信息// + + ret = OsCopyParent(flags, child, run); + if (ret != LOS_OK) { + return ret; + } + + return OsCopyTask(flags, child, name, sp, size);//继续调用 OsCopyParent 复制父进程的某些资源给子进程,最后调用 OsCopyTask 来复制任务相关的资源// +} + +STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB *run) +{//用于将子进程设置到正确的进程组,并将其加入到调度队列中// + UINT32 intSave; + UINT32 ret; + ProcessGroup *group = NULL; + + SCHEDULER_LOCK(intSave); + if (run->group->groupID == OS_USER_PRIVILEGE_PROCESS_GROUP) { + ret = OsSetProcessGroupIDUnsafe(child->processID, child->processID, &group); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + return LOS_ENOMEM; + } + }//如果父进程属于用户特权进程组,则会为子进程创建一个新的进程组// + + OsSchedTaskEnQueue(OS_TCB_FROM_TID(child->threadGroupID)); + SCHEDULER_UNLOCK(intSave); + + (VOID)LOS_MemFree(m_aucSysMem1, group); + return LOS_OK;//将子进程的主线程加入调度队列,并释放之前可能分配的进程组内存// +} + +STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProcessCB *run) +{//负责复制父进程的资源给子进程,包括内存管理单元、文件描述符等// + UINT32 ret; + + ret = OsCopyMM(flags, child, run); + if (ret != LOS_OK) { + return ret; + } + + ret = OsCopyFile(flags, child, run); + if (ret != LOS_OK) { + return ret; + }//如果系统配置了 LOSCFG_KERNEL_LITEIPC,则还需要重新初始化 IPC 资源// + +#ifdef LOSCFG_KERNEL_LITEIPC + if (OsProcessIsUserMode(child)) { + ret = LiteIpcPoolReInit(&child->ipcInfo, (const ProcIpcInfo *)(&run->ipcInfo)); + if (ret != LOS_OK) { + return LOS_ENOMEM; + } + } +#endif + +#ifdef LOSCFG_SECURITY_CAPABILITY + OsCopyCapability(run, child); +#endif + + return LOS_OK;//如果配置了 LOSCFG_SECURITY_CAPABILITY,还需要复制安全能力// +} + +STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size) +{ + UINT32 intSave, ret, processID; + LosProcessCB *run = OsCurrProcessGet(); + + LosProcessCB *child = OsGetFreePCB(); + if (child == NULL) { + return -LOS_EAGAIN; + } + processID = child->processID;//获取一个空闲的 PCB,然后通过调用 OsForkInitPCB 初始化 PCB// + + ret = OsForkInitPCB(flags, child, name, sp, size); + if (ret != LOS_OK) { + goto ERROR_INIT; + } + + ret = OsCopyProcessResources(flags, child, run); + if (ret != LOS_OK) { + goto ERROR_TASK; + }//通过 OsCopyProcessResources 复制资源// + + ret = OsChildSetProcessGroupAndSched(child, run); + if (ret != LOS_OK) { + goto ERROR_TASK; + } + + LOS_MpSchedule(OS_MP_CPU_ALL); + if (OS_SCHEDULER_ACTIVE) { + LOS_Schedule(); + } + + return processID;//通过 OsChildSetProcessGroupAndSched 设置进程组和调度。如果任何步骤失败,它会跳转到错误处理部分并释放已分配的资源// + +ERROR_TASK: + SCHEDULER_LOCK(intSave); + (VOID)OsTaskDeleteUnsafe(OS_TCB_FROM_TID(child->threadGroupID), OS_PRO_EXIT_OK, intSave);//调用来删除已经创建但未能成功完成初始化的子进程的主线程// +ERROR_INIT: + OsDeInitPCB(child); + return -ret;//调用来释放和反初始化进程控制块(PCB)// +} + +LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size) +{ + UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_VM; + + if (flags & (~cloneFlag)) { + PRINT_WARN("Clone dont support some flags!\n");//检查传入的 flags 参数,并确保没有不支持的标志被设置。如果有不支持的标志,它会打印警告// + } + + return OsCopyProcess(cloneFlag & flags, NULL, sp, size);//调用 OsCopyProcess 来实际创建一个新的进程或线程// +} + +LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize) +{//供了一个创建新进程的接口,类似于 UNIX 系统中的 fork 系统调用// + UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_FILES; + + if (flags & (~cloneFlag)) { + PRINT_WARN("Clone dont support some flags!\n"); + }//检查 flags 参数,确保没有不支持的标志被设置,并添加 CLONE_FILES 标志,以便子进程可以共享文件描述符表// + + flags |= CLONE_FILES; + return OsCopyProcess(cloneFlag & flags, name, (UINTPTR)entry, stackSize); +} +#else +LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) +{ + return 0; +} +#endif//OsCopyProcess 函数来创建一个新的进程// + +LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) +{//允许一个进程退出并释放资源// + UINT32 intSave; + + /* The exit of a kernel - state process must be kernel - state and all threads must actively exit */ + LosProcessCB *processCB = OsCurrProcessGet(); + SCHEDULER_LOCK(intSave);//如果当前进程是内核态进程且拥有多个线程,则不允许直接退出// + if (!OsProcessIsUserMode(processCB) && (processCB->threadNumber != 1)) { + SCHEDULER_UNLOCK(intSave); + PRINT_ERR("Kernel-state processes with multiple threads are not allowed to exit directly\n"); + return; + } + SCHEDULER_UNLOCK(intSave); + + OsTaskExitGroup((UINT32)status); + OsProcessExit(OsCurrTaskGet(), (UINT32)status);//如果条件允许,它会调用 OsTaskExitGroup 和 OsProcessExit 来完成退出流程// +} + +LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum) +{//这个函数用于获取当前正在使用的所有进程的 PID 列表// + LosProcessCB *pcb = NULL; + INT32 num = 0; + UINT32 intSave; + UINT32 pid = 1; + + if (pidList == NULL) { + return 0; + }//它通过遍历所有可能的 PID 并检查对应的 PCB 是否正在使用来实现// + SCHEDULER_LOCK(intSave); + while (OsProcessIDUserCheckInvalid(pid) == false) { + pcb = OS_PCB_FROM_PID(pid); + pid++; + if (OsProcessIsUnused(pcb)) { + continue; + } + pidList[num] = pcb->processID; + num++; + if (num >= pidMaxNum) { + break; + } + } + SCHEDULER_UNLOCK(intSave); + return num;//如果 PCB 正在使用,它将该 PCB 的 PID 添加到 pidList 数组中,并返回找到的 PID 数量// +} + +#ifdef LOSCFG_FS_VFS +LITE_OS_SEC_TEXT struct fd_table_s *LOS_GetFdTable(UINT32 pid) +{//返回指定 PID 的进程的文件描述符表// + LosProcessCB *pcb = NULL; + struct files_struct *files = NULL;//它首先检查 PID 是否有效,然后获取对应的 PCB 和文件结构体 files// + + if (OS_PID_CHECK_INVALID(pid)) { + return NULL; + } + pcb = OS_PCB_FROM_PID(pid); + files = pcb->files; + if (files == NULL) { + return NULL; + } + + return files->fdt;//如果这些结构体有效,它返回文件描述符表 fdt// +} +