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, &param);
    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//
}