提交 62d5a098 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析

完善进程部分注释,注释进程是怎么一步步被Fork的

鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki
项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.
上级 c25a0f2b
......@@ -6,7 +6,7 @@
# **[kernel\_liteos\_a_note](https://gitee.com/weharmony/kernel_liteos_a_note): 鸿蒙内核源码注释中文版**
[![star](https://gitee.com/weharmony/kernel_liteos_a_note/badge/star.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)[![下载源码](https://gitee.com/oschina/git-osc/widgets/widget_3.svg)](https://gitee.com/weharmony/kernel_liteos_a_note)[![fork](https://gitee.com/weharmony/kernel_liteos_a_note/badge/fork.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)
[![star](https://gitee.com/weharmony/kernel_liteos_a_note/badge/star.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)[![fork](https://gitee.com/weharmony/kernel_liteos_a_note/badge/fork.svg?theme=dark)](https://gitee.com/weharmony/kernel_liteos_a_note)
每个码农,职业生涯,都应精读一遍内核源码. 鸿蒙内核源码就是很好的精读项目.一旦熟悉内核代码级实现,将迅速拔高对计算机整体理解,从此高屋建瓴看问题.
......
......@@ -48,8 +48,8 @@ extern "C" {
typedef struct ArchMmu {
LosMux mtx; /**< arch mmu page table entry modification mutex lock */
VADDR_T *virtTtb; /**< translation table base virtual addr */
PADDR_T physTtb; /**< translation table base phys addr */
VADDR_T *virtTtb; /**< translation table base virtual addr */ //注意:这里是个指针,内核操作都用这个地址
PADDR_T physTtb; /**< translation table base phys addr */ //注意:这里是个值,这个值是记录给MMU使用的,MMU只认它,内核是无法使用的
UINT32 asid; /**< TLB asid */
LOS_DL_LIST ptList; /**< page table vm page list *///L1 为表头,后面挂的是n多L2
} LosArchMmu;
......
......@@ -124,8 +124,8 @@ LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(LosTaskCB *childTaskCB, LosTaskCB *
//cloneStack指向 TaskContext
LOS_ASSERT(parentTaskCB->taskStatus & OS_TASK_STATUS_RUNNING);//当前任务一定是正在运行的task
(VOID)memcpy_s(childTaskCB->stackPointer, sizeof(TaskContext), cloneStack, sizeof(TaskContext));
context->R[0] = 0;
(VOID)memcpy_s(childTaskCB->stackPointer, sizeof(TaskContext), cloneStack, sizeof(TaskContext));//直接把任务上下文拷贝了一份
context->R[0] = 0;//R0寄存器为0
}
//用户任务使用栈初始化
LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_FUNC taskEntry, UINTPTR stack)
......
......@@ -1736,11 +1736,11 @@ STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR
if (OsProcessIsUserMode(childProcessCB)) {//是否是用户进程
SCHEDULER_LOCK(intSave);
OsUserCloneParentStack(childTaskCB, OsCurrTaskGet());
OsUserCloneParentStack(childTaskCB, OsCurrTaskGet());//任务栈拷贝
SCHEDULER_UNLOCK(intSave);
}
OS_TASK_PRI_QUEUE_ENQUEUE(childProcessCB, childTaskCB);
childTaskCB->taskStatus |= OS_TASK_STATUS_READY;
OS_TASK_PRI_QUEUE_ENQUEUE(childProcessCB, childTaskCB);//将task加入进程的就绪队列
childTaskCB->taskStatus |= OS_TASK_STATUS_READY;//任务状态贴上就绪标签
return LOS_OK;
}
//拷贝父亲大人的遗传基因信息
......@@ -1782,10 +1782,10 @@ STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB
return LOS_OK;
}
if (flags & CLONE_VM) {
if (flags & CLONE_VM) {//贴有虚拟内存的标签
SCHEDULER_LOCK(intSave);
childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb;
childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb;
childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb;//TTB虚拟地址基地址,即L1表存放位置,virtTtb是个指针,进程的虚拟空间是指定的范围的
childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb;//TTB物理地址基地址,physTtb是个值,取决于运行时映射到物理内存的具体哪个位置.
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
......@@ -1796,7 +1796,7 @@ STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB
}
return LOS_OK;
}
//拷贝文件信息
STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
{
#ifdef LOSCFG_FS_VFS
......@@ -1832,7 +1832,7 @@ STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name,
return OsCopyTask(flags, child, name, sp, size);//拷贝任务,设置任务入口函数,栈大小
}
//设置进程组和加入进程调度就绪队列
STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB *run)
{
UINT32 intSave;
......@@ -1840,17 +1840,17 @@ STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB *
ProcessGroup *group = NULL;
SCHEDULER_LOCK(intSave);
if (run->group->groupID == OS_USER_PRIVILEGE_PROCESS_GROUP) {
ret = OsSetProcessGroupIDUnsafe(child->processID, child->processID, &group);
if (run->group->groupID == OS_USER_PRIVILEGE_PROCESS_GROUP) {//如果是有用户特权进程组
ret = OsSetProcessGroupIDUnsafe(child->processID, child->processID, &group);//设置组ID,存在不安全的风险
if (ret != LOS_OK) {
SCHEDULER_UNLOCK(intSave);
return LOS_ENOMEM;
}
}
OS_PROCESS_PRI_QUEUE_ENQUEUE(child);
child->processStatus &= ~OS_PROCESS_STATUS_INIT;
child->processStatus |= OS_PROCESS_STATUS_READY;
OS_PROCESS_PRI_QUEUE_ENQUEUE(child);//
child->processStatus &= ~OS_PROCESS_STATUS_INIT;//去掉初始化标签
child->processStatus |= OS_PROCESS_STATUS_READY;//贴上就绪标签
#ifdef LOSCFG_KERNEL_CPUP
OsCpupSet(child->processID);
......@@ -1865,19 +1865,19 @@ STATIC INT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProces
{
UINT32 ret;
ret = OsCopyMM(flags, child, run);
ret = OsCopyMM(flags, child, run);//拷贝虚拟空间
if (ret != LOS_OK) {
return ret;
}
ret = OsCopyFile(flags, child, run);
ret = OsCopyFile(flags, child, run);//拷贝文件信息
if (ret != LOS_OK) {
return ret;
}
#if (LOSCFG_KERNEL_LITEIPC == YES)
if (OsProcessIsUserMode(child)) {
ret = LiteIpcPoolReInit(&child->ipcInfo, (const ProcIpcInfo *)(&run->ipcInfo));
if (OsProcessIsUserMode(child)) {//用户模式下
ret = LiteIpcPoolReInit(&child->ipcInfo, (const ProcIpcInfo *)(&run->ipcInfo));//重新初始化IPC池
if (ret != LOS_OK) {
return LOS_ENOMEM;
}
......@@ -1885,7 +1885,7 @@ STATIC INT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProces
#endif
#ifdef LOSCFG_SECURITY_CAPABILITY
OsCopyCapability(run, child);
OsCopyCapability(run, child);//拷贝安全能力
#endif
return LOS_OK;
......@@ -1907,18 +1907,18 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si
goto ERROR_INIT;
}
ret = OsCopyProcessResources(flags, child, run);
ret = OsCopyProcessResources(flags, child, run);//拷贝进程的资源,包括虚拟空间,文件,安全,IPC ==
if (ret != LOS_OK) {
goto ERROR_TASK;
}
ret = OsChildSetProcessGroupAndSched(child, run);
ret = OsChildSetProcessGroupAndSched(child, run);//设置进程组和加入进程调度就绪队列
if (ret != LOS_OK) {
goto ERROR_TASK;
}
LOS_MpSchedule(OS_MP_CPU_ALL);
if (OS_SCHEDULER_ACTIVE) {
LOS_MpSchedule(OS_MP_CPU_ALL);//给各CPU发送准备接受调度信号
if (OS_SCHEDULER_ACTIVE) {//当前CPU core处于活动状态
LOS_Schedule();// 申请调度
}
......
......@@ -255,49 +255,49 @@ STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace)
return LOS_ERRNO_VM_INVALID_ARGS;
}
if ((OsIsVmRegionEmpty(oldVmSpace) == TRUE) || (oldVmSpace == &g_kVmSpace)) {
if ((OsIsVmRegionEmpty(oldVmSpace) == TRUE) || (oldVmSpace == &g_kVmSpace)) {//不允许clone内核空间,内核空间是独一无二的.
return LOS_ERRNO_VM_INVALID_ARGS;
}
//空间克隆的主体实现是:线性区重新一个个分配物理内存,重新映射.
/* search the region list */
newVmSpace->mapBase = oldVmSpace->mapBase;
newVmSpace->heapBase = oldVmSpace->heapBase;
newVmSpace->heapNow = oldVmSpace->heapNow;
(VOID)LOS_MuxAcquire(&oldVmSpace->regionMux);
RB_SCAN_SAFE(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext)
RB_SCAN_SAFE(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext)//红黑树循环开始
oldRegion = (LosVmMapRegion *)pstRbNode;
newRegion = OsVmRegionDup(newVmSpace, oldRegion, oldRegion->range.base, oldRegion->range.size);
newRegion = OsVmRegionDup(newVmSpace, oldRegion, oldRegion->range.base, oldRegion->range.size);//复制线性区
if (newRegion == NULL) {
VM_ERR("dup new region failed");
ret = LOS_ERRNO_VM_NO_MEMORY;
goto ERR_CLONE_ASPACE;
}
if (oldRegion->regionFlags & VM_MAP_REGION_FLAG_SHM) {
OsShmFork(newVmSpace, oldRegion, newRegion);
continue;
if (oldRegion->regionFlags & VM_MAP_REGION_FLAG_SHM) {//如果老线性区是共享内存
OsShmFork(newVmSpace, oldRegion, newRegion);//fork共享线性区,如此新虚拟空间也能用那个线性区
continue;//不往下走了,因为共享内存不需要重新映射,下面无非就是需要MMU映射虚拟地址<-->物理地址
}
if (oldRegion == oldVmSpace->heap) {
newVmSpace->heap = newRegion;
if (oldRegion == oldVmSpace->heap) {//如果这个线性区是堆区
newVmSpace->heap = newRegion;//那么新的线性区也是新虚拟空间的堆区
}
numPages = newRegion->range.size >> PAGE_SHIFT;
for (i = 0; i < numPages; i++) {
numPages = newRegion->range.size >> PAGE_SHIFT;//计算线性区页数
for (i = 0; i < numPages; i++) {//一页一页进行重新映射
vaddr = newRegion->range.base + (i << PAGE_SHIFT);
if (LOS_ArchMmuQuery(&oldVmSpace->archMmu, vaddr, &paddr, &flags) != LOS_OK) {
if (LOS_ArchMmuQuery(&oldVmSpace->archMmu, vaddr, &paddr, &flags) != LOS_OK) {//先查物理地址
continue;
}
page = LOS_VmPageGet(paddr);
page = LOS_VmPageGet(paddr);//通过物理页获取物理内存的页框
if (page != NULL) {
LOS_AtomicInc(&page->refCounts);//refCounts 自增
}
if (flags & VM_MAP_REGION_FLAG_PERM_WRITE) {
LOS_ArchMmuUnmap(&oldVmSpace->archMmu, vaddr, 1);
LOS_ArchMmuMap(&oldVmSpace->archMmu, vaddr, paddr, 1, flags & ~VM_MAP_REGION_FLAG_PERM_WRITE);
if (flags & VM_MAP_REGION_FLAG_PERM_WRITE) {//可写入区标签
LOS_ArchMmuUnmap(&oldVmSpace->archMmu, vaddr, 1);//取消老空间映射
LOS_ArchMmuMap(&oldVmSpace->archMmu, vaddr, paddr, 1, flags & ~VM_MAP_REGION_FLAG_PERM_WRITE);//老空间重新映射
}
LOS_ArchMmuMap(&newVmSpace->archMmu, vaddr, paddr, 1, flags & ~VM_MAP_REGION_FLAG_PERM_WRITE);
LOS_ArchMmuMap(&newVmSpace->archMmu, vaddr, paddr, 1, flags & ~VM_MAP_REGION_FLAG_PERM_WRITE);//映射新空间
#ifdef LOSCFG_FS_VFS
if (LOS_IsRegionFileValid(oldRegion)) {
......@@ -311,7 +311,7 @@ STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace)
}
#endif
}
RB_SCAN_SAFE_END(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext)
RB_SCAN_SAFE_END(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext)//红黑树循环结束
goto OUT_CLONE_ASPACE;
ERR_CLONE_ASPACE:
if (LOS_VmSpaceFree(newVmSpace) != LOS_OK) {
......
......@@ -319,37 +319,37 @@ VOID OsShmFork(LosVmSpace *space, LosVmMapRegion *oldRegion, LosVmMapRegion *new
return;
}
newRegion->shmid = oldRegion->shmid;
newRegion->forkFlags = oldRegion->forkFlags;
ShmVmmMapping(space, &seg->node, newRegion->range.base, newRegion->regionFlags);
seg->ds.shm_nattch++;
newRegion->shmid = oldRegion->shmid;//一样的共享区ID
newRegion->forkFlags = oldRegion->forkFlags;//forkFlags也一样了
ShmVmmMapping(space, &seg->node, newRegion->range.base, newRegion->regionFlags);//共享内存映射
seg->ds.shm_nattch++;//附在共享线性区上的进程数++
SYSV_SHM_UNLOCK();
}
//释放共享线性区
VOID OsShmRegionFree(LosVmSpace *space, LosVmMapRegion *region)
{
struct shmIDSource *seg = NULL;
SYSV_SHM_LOCK();
seg = ShmFindSeg(region->shmid);
seg = ShmFindSeg(region->shmid);////通过线性区ID获取对应的共享资源ID结构体
if (seg == NULL) {
SYSV_SHM_UNLOCK();
return;
}
ShmPagesRefDec(seg);
seg->ds.shm_nattch--;
if (seg->ds.shm_nattch <= 0) {
ShmFreeSeg(seg);
ShmPagesRefDec(seg);//ref --
seg->ds.shm_nattch--;//附在共享线性区上的进程数--
if (seg->ds.shm_nattch <= 0) {//没有任何进程在使用这个线性区的情况
ShmFreeSeg(seg);//就释放掉物理内存!注意是:物理内存
}
SYSV_SHM_UNLOCK();
}
//是否为共享线性区
//是否为共享线性区,看他有没有标签
BOOL OsIsShmRegion(LosVmMapRegion *region)
{
return (region->regionFlags & VM_MAP_REGION_FLAG_SHM) ? TRUE : FALSE;
}
//使用共享段数量
STATIC INT32 ShmSegUsedCount(VOID)
{
INT32 i;
......
git add -A
git commit -m 'CPU硬件上下文 及其各种寄存器,异常处理函数的注释
git commit -m '完善进程部分注释,注释进程是怎么一步步被Fork的
鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki
项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册