diff --git a/README.md b/README.md index 91bd086e3226a96a430cbf7176e6baee5174884f..7b31360964c1dd5743e91447383309e06458040b 100644 --- a/README.md +++ b/README.md @@ -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) 每个码农,职业生涯,都应精读一遍内核源码. 鸿蒙内核源码就是很好的精读项目.一旦熟悉内核代码级实现,将迅速拔高对计算机整体理解,从此高屋建瓴看问题. diff --git a/arch/arm/arm/include/los_arch_mmu.h b/arch/arm/arm/include/los_arch_mmu.h index 0b4360d62ad26a9a14410ed0ba99e8dc7c9ac4f2..ae81e94df7e2e86f5bc51c2404816e491b7f9387 100644 --- a/arch/arm/arm/include/los_arch_mmu.h +++ b/arch/arm/arm/include/los_arch_mmu.h @@ -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; diff --git a/arch/arm/arm/src/los_hw.c b/arch/arm/arm/src/los_hw.c index ef2405fcc11db2e38e5b4aafd8ea140c9a329767..4174b459be3478e7a7e85ef61b97115678e8ce12 100644 --- a/arch/arm/arm/src/los_hw.c +++ b/arch/arm/arm/src/los_hw.c @@ -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) diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 71875cd49fddb4b0d091e3fe0fbea89dcb818cb5..45ff1a29f3a2725a665eff07ba60853eb4ad986a 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -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();// 申请调度 } diff --git a/kernel/base/vm/los_vm_map.c b/kernel/base/vm/los_vm_map.c index 2edd57a8747e6acdd48f5a0406d5a4448f9624e3..3f6a872d7bbed905d1ebbca17883ad8216ff98c5 100644 --- a/kernel/base/vm/los_vm_map.c +++ b/kernel/base/vm/los_vm_map.c @@ -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) { diff --git a/kernel/base/vm/shm.c b/kernel/base/vm/shm.c index a920f2047ba17314c1dc208a30e086cd86edd073..1f509ed3661bd6bfd411b3c2861514971f0a1340 100644 --- a/kernel/base/vm/shm.c +++ b/kernel/base/vm/shm.c @@ -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; diff --git a/zzz/git/push.sh b/zzz/git/push.sh index 02d24145ba58f0922a29fb9a40ebd066c376f50f..deb2f9dad5d57057a59f28f35601ca3275de5d90 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,5 +1,5 @@ git add -A -git commit -m 'CPU硬件上下文 及其各种寄存器,异常处理函数的注释 +git commit -m '完善进程部分注释,注释进程是怎么一步步被Fork的 鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】 鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki 项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.'