Million Chinese character annotation > > intensive reading kernel source code, Chinese annotation analysis, deep foundation engineering, permanent brain memory, and four code warehouses are updated synchronously every day< gitee | github | csdn | coding >
One hundred blog Analysis > > story telling kernel, question and answer guide, life style metaphor, tabular description, graphical display, and regular updates of mainstream websites< oschina | csdn | harmony >
Three processes
Hongmeng has three special processes, which are created in the following order:
- Process 2, KProcess, is a kernel root process Created during startup
- Process 0, KIdle is the second process in kernel mode, which comes from KProcess fork It's a little hard to understand
- Process 1, init, is the user state root process Created by task SystemInit
- It is found that process 0 is not visible in the figure. After reading this article, please think about why?
Family management
- Process is a family management, which is divided into two families: user state family and kernel state family
- The process of user status is the civilian class, working in all walks of life, with limited rights, large number and limited scope of activities Zhongnanhai is definitely not allowed to enter or leave at will This class has a common ancestor G_ Userinitprocess (process 1)
g_userInitProcess = 1; /* 1: The root process ID of the user-mode process is fixed at 1 *///Root process in user mode //Get the root process of user state process. All user processes are g_processCBArray[g_userInitProcess] fork LITE_OS_SEC_TEXT UINT32 OsGetUserInitProcessID(VOID) { return g_userInitProcess; }
- The process of kernel state is aristocratic class, managing civilian class and maintaining civilian life order. It has super authority and a small number of people The ancestor of this class is g_ Kernelinitprocess (process 2)
g_kernelInitProcess = 2; /* 2: The root process ID of the kernel-mode process is fixed at 2 *///Kernel root process //Get the root process of the kernel state process. All kernel processes are g_processCBArray[g_kernelInitProcess] fork, including g_processCBArray[g_kernelIdleProcess] process LITE_OS_SEC_TEXT UINT32 OsGetKernelInitProcessID(VOID) { return g_kernelInitProcess; }
- Can these two classes flow with each other? Is there an opportunity to change their fate through the college entrance examination? The answer is: absolutely impossible!!! A dragon begets a dragon, a phoenix begets a Phoenix, and a mouse begets a son. He can make a hole It has been engraved in the gene since the founding of our ancestors Because all the processes were cloned by these two old comrades and inherited this gene Los processcb has a special label to distinguish the two levels of processMode The whole Hongmeng kernel source code does not provide a set function to change the chance of fate
#define OS_KERNEL_MODE 0x0U // Kernel state #define OS_USER_MODE 0x1U // User state STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)//User mode process { return (processCB->processMode == OS_USER_MODE); } typedef struct ProcessCB { // ... UINT16 processMode; /**< Kernel Mode:0; User Mode:1; */ //Specifies whether the mode is kernel or user process } LosProcessCB;
Process 2 KProcess
Process 2 is the ancestor of kernel state and the first process created by kernel. The source code process is as follows, and irrelevant code is omitted
bl main @belt LR Subroutine jump, LR = pc - 4 ,implement C layer main function /****************************************************************************** Kernel entry function, called by assembly, can be found in reset_vector_up.S and reset_vector_mp.S up Refers to single core CPU, mp refers to multi-core CPU, BL main ******************************************************************************/ LITE_OS_SEC_TEXT_INIT INT32 main(VOID)//It is executed by the main CPU. By default, CPU 0 is the main CPU { // ... ellipsis uwRet = OsMain();// Initialization of kernel modules } LITE_OS_SEC_TEXT_INIT INT32 OsMain(VOID) { // ... ret = OsKernelInitProcess();// Create kernel root process // ... ret = OsSystemInit(); //The user status root process is created in the middle } //Initialize process 2, the ancestor of kernel state process LITE_OS_SEC_TEXT_INIT UINT32 OsKernelInitProcess(VOID) { LosProcessCB *processCB = NULL; UINT32 ret; ret = OsProcessInit();// Initialize all variables of the process module and create a circular two-way linked list if (ret != LOS_OK) { return ret; } processCB = OS_PCB_FROM_PID(g_kernelInitProcess);// Get a process in PID mode ret = OsProcessCreateInit(processCB, OS_KERNEL_MODE, "KProcess", 0);// The highest priority of initialization process is 0. Hongmeng process has a total of 32 priorities (0-31), of which 0-9 are kernel processes, and the configurable priorities of user processes are 22 (10-31) if (ret != LOS_OK) { return ret; } processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;// Process initialization location 1 g_processGroup = processCB->group;//The global process group points to the process group where KProcess is located LOS_ListInit(&g_processGroup->groupList);// Process group linked list initialization OsCurrProcessSet(processCB);// Set as current process return OsCreateIdleProcess();// Create an idle process }
unscramble
- The main function will be discussed separately in the series. Please check it by yourself. It is created in SVC mode at the beginning of startup
- The ancestor of kernel state is called KProcess, with the highest priority of level 0 The "KProcess" process is long-term and active, and many important tasks will run under it For example:
- Swt_Task
- oom_task
- system_wq
- tcpip_thread
- SendToSer
- SendToTelnet
- eth_irq_task
- TouchEventHandler
- USB_GIANT_Task
These tasks are not discussed in detail here. They are introduced in other sections, but you can guess eight or nine by just looking at the name. Please look through them yourself
- Then KProcess with CLONE_FILES fork s a child process named "KIdle"
- All processes in the kernel state come from process 2. This old comrade, his children and grandchildren, are passed down from generation to generation to form a family tree. Different from human inheritance, they are often white haired people to black haired people, and the processes of their children and grandchildren are often short-lived ghosts. The old ancestors can live best, their children and grandchildren are dead, and they are still there. Some corpse collection work needs to be done by them
Process 0 KIdle
Process 0 is the first process created by the kernel. After process 2 is set as the current process at the end of OsKernelInitProcess, process 0 is forked immediately Why do you have to set the current process first, because fork needs a parent process. At this time, the system is in the startup stage and there is no current process Yes, you are right Process is a concept derived from the operating system to facilitate the management of resources. The system does not need processes and tasks to run There is nothing in the boot phase. It runs in svc mode by default, and the entry address reset is specified by default_ Vectors are specified after the hardware is powered on Process and thread are given the meaning slowly after running. OsCurrProcessSet gives the concept of current process from the software level This is the first current process set by the kernel
//Create a 0 process named "KIdle" to be used when the CPU is idle STATIC UINT32 OsCreateIdleProcess(VOID) { UINT32 ret; CHAR *idleName = "Idle"; LosProcessCB *idleProcess = NULL; Percpu *perCpu = OsPercpuGet(); UINT32 *idleTaskID = &perCpu->idleTaskID;//Get the idle task of CPU ret = OsCreateResourceFreeTask();// Create a resource recycling task with priority of 5 to recycle various resources when the process exits if (ret != LOS_OK) { return ret; } //When the CPU creates an idle process called "idle task", it waits for a process called "idle task" ret = LOS_Fork(CLONE_FILES, "KIdle", (TSK_ENTRY_FUNC)OsIdleTask, LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE); if (ret < 0) {//The fork of the kernel process will not be called once and returned twice. The starting position of the execution of this sub process is the parameter OsIdleTask return LOS_NOK; } g_kernelIdleProcess = (UINT32)ret;//Return to process 0 idleProcess = OS_PCB_FROM_PID(g_kernelIdleProcess);//Get the process entity through ID *idleTaskID = idleProcess->threadGroupID;//Bind the IdleTask of the CPU, or change the existing idle task of the CPU OS_TCB_FROM_TID(*idleTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//Set Idle task as a system task #if (LOSCFG_KERNEL_SMP == YES) OS_TCB_FROM_TID(*idleTaskID)->cpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());//Task assignment of multi-core CPU to prevent disorderly string. Pay attention to multi-core before parallel processing #endif (VOID)memset_s(OS_TCB_FROM_TID(*idleTaskID)->taskName, OS_TCB_NAME_LEN, 0, OS_TCB_NAME_LEN);//Clear 0 first for task name (VOID)memcpy_s(OS_TCB_FROM_TID(*idleTaskID)->taskName, OS_TCB_NAME_LEN, idleName, strlen(idleName));//The name of the task is idle return LOS_OK; }
unscramble
- After reading the fork article, you may find a parameter. The way KIdle is created is different from that through system call. One uses CLONE_FILES, one is clone_ The specific creation method of sighand is as follows:
#define CLONE_VM 0x00000100 // The child process runs in the same memory space as the parent process #define CLONE_FS 0x00000200 // The child process shares the same file system as the parent process, including root, current directory and umask #define CLONE_FILES 0x00000400 // The child process and the parent process share the same file descriptor table #define CLONE_SIGHAND 0x00000800 // The child process and the parent process share the same signal handler table #define CLONE_PTRACE 0x00002000 // If the parent process is tracked, the child process is also tracked #define CLONE_VFORK 0x00004000 // The parent process is suspended until the child process releases virtual memory resources #define CLONE_PARENT 0x00008000 // The parent process of the created child process is the parent process of the caller. The new process and the process that created it become "brothers" rather than "parents and children" #define CLONE_THREAD 0x00010000 // Added in Linux 2.4 to support POSIX thread standard. Child processes and parent processes share the same thread group
- KIdle creates a task named Idle. The entry function of the task is OsIdleTask. This is an Idle task that does nothing It is specially used to give the cpu rest. When the cpu is free, it will stay in this task and wait for work
LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID) { while (1) {//There is only one dead cycle #ifdef LOSCFG_KERNEL_TICKLESS / / low power mode switch. Turn off tick in idle task if (OsTickIrqFlagGet()) { OsTickIrqFlagSet(0); OsTicklessStart(); } #endif Wfi();//WFI instruction: arm core immediately enters low power standby state, waits for interruption and enters sleep mode. } }
- There is one difference between fork kernel state process and fork user state process, that is, the value of SP register The fork user state process calls and returns twice at a time (once for the parent and child processes), and the return location is the same (because it copies the context when the parent process falls into the kernel) Therefore, the return value can only be used to judge whether the parent or child returns This is described in detail in the fork article Please look through it yourself However, although fork kernel processes return twice, the return location is different. The return location of child processes is specified by the kernel For example, OsIdleTask is the entry function See code for details:
//Copy task information during task initialization 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();//Get the current task and pay attention to the variable name. It can also be seen from here that thread and task are a concept, but the kernel often says task and the upper application says thread, which is the mapping of the concept if (OsProcessIsUserMode(childProcessCB)) {//User state process childPara->pfnTaskEntry = mainThread->taskEntry;//Copy the current task entry address childPara->uwStackSize = mainThread->stackSize; //Stack space size childPara->userParam.userArea = mainThread->userArea; //Top position of user status stack area childPara->userParam.userMapBase = mainThread->userMapBase; //User status stack bottom childPara->userParam.userMapSize = mainThread->userMapSize; //User state stack size } else {//Note that the entry of the kernel process creation task is specified by the outside world. For example, OsCreateIdleProcess specifies OsIdleTask childPara->pfnTaskEntry = (TSK_ENTRY_FUNC)entry;//Parameter (sp) is the kernel state entry address childPara->uwStackSize = size;//The parameter (size) is the kernel stack size } childPara->pcName = (CHAR *)name; //Copy process name childPara->policy = mainThread->policy; //Copy scheduling mode childPara->usTaskPrio = mainThread->priority; //Copy priority childPara->processID = childProcessCB->processID; //Copy process ID 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; } SCHEDULER_UNLOCK(intSave); }
- The conclusion is that the OsCreateIdleProcess in process 0 calls LOS_ There will only be one return after fork And the return value is 0 because G_ Process 0 in freeprocess has not been assigned See the code for details, and pay attention to the final comments:
//The process module is initialized and compiled in the code segment In init LITE_OS_SEC_TEXT_INIT UINT32 OsProcessInit(VOID) { UINT32 index; UINT32 size; g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT;//64 processes are supported by default size = g_processMaxNum * sizeof(LosProcessCB);//Calculate the total size g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size);// Process pool, occupied kernel heap, memory pool allocation if (g_processCBArray == NULL) { return LOS_NOK; } (VOID)memset_s(g_processCBArray, size, 0, size);//Safe mode reset clear 0 LOS_ListInit(&g_freeProcess);//Process idle linked list initialization, when creating a process from G_ Apply for a process descriptor in freeprocess LOS_ListInit(&g_processRecyleList);//The process recycling linked list is initialized. After the recycling is completed, enter g_freeProcess is waiting to be applied for again for (index = 0; index < g_processMaxNum; index++) {//Process pool loop creation g_processCBArray[index].processID = index;//Assignment of process ID[0-g_processMaxNum-1] g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED;// The default is a piece of white paper with unused labels LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList);//Attention g_freeProcess is attached to the pendList node, so it needs to be used through the OS_PCB_FROM_PENDLIST found the process entity } g_userInitProcess = 1; /* 1: The root process ID of the user-mode process is fixed at 1 *///Root process in user mode LOS_ListDelete(&g_processCBArray[g_userInitProcess].pendList);// Remove process 1 from the free linked list g_kernelInitProcess = 2; /* 2: The root process ID of the kernel-mode process is fixed at 2 *///Kernel root process LOS_ListDelete(&g_processCBArray[g_kernelInitProcess].pendList);// Remove process 2 from the free linked list //Note: after this bosao operation, G_ There are also 0, 3, 4 g_ Processmaxnum - process 1 The creation process is from G_ Apply on freeprocess //That is, the next application will be process 0, and OsCreateIdleProcess will occupy process 0 return LOS_OK; }
Process 1 init
Process 1 is the ancestral source code of user status. The process is as follows, and irrelevant code is omitted
LITE_OS_SEC_TEXT_INIT INT32 OsMain(VOID) { // ... ret = OsKernelInitProcess();// Create kernel root process // ... ret = OsSystemInit(); //The user status root process is created in the middle } UINT32 OsSystemInit(VOID) { //.. ret = OsSystemInitTaskCreate();//Created a system task, } STATIC UINT32 OsSystemInitTaskCreate(VOID) { UINT32 taskID; TSK_INIT_PARAM_S sysTask; (VOID)memset_s(&sysTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); sysTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SystemInit;//The entry function of the task. This function implementation is provided externally sysTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16K sysTask.pcName = "SystemInit";//Name of the task sysTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;// The kernel default priority is 10 sysTask.uwResved = LOS_TASK_STATUS_DETACHED;//Task separation mode #if (LOSCFG_KERNEL_SMP == YES) sysTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());//CPU affinity setting, record the CPU that has executed the task, and try to ensure that the same CPU completes the task cycle #endif return LOS_TaskCreate(&taskID, &sysTask);//Create a task and join the ready queue, and immediately participate in the scheduling } //The implementation of SystemInit is provided externally, such as \vendor\hi3516dv300\module_init\src\system_init.c void SystemInit(void) { // ... if (OsUserInitProcess()) {//The ancestor of creating user state processes PRINT_ERR("Create user init process faialed!\n"); return; } } //The creation process of user status root process LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) { INT32 ret; UINT32 size; TSK_INIT_PARAM_S param = { 0 }; VOID *stack = NULL; VOID *userText = NULL; CHAR *userInitTextStart = (CHAR *)&__user_init_entry;//Start position of code area, corresponding to LITE_USER_SEC_ENTRY CHAR *userInitBssStart = (CHAR *)&__user_init_bss;// The data area (BSS) is not initialized. Change the value corresponding to Lite during operation_ USER_ SEC_ BSS CHAR *userInitEnd = (CHAR *)&__user_init_end;// End address UINT32 initBssSize = userInitEnd - userInitBssStart; UINT32 initSize = userInitEnd - userInitTextStart; LosProcessCB *processCB = OS_PCB_FROM_PID(g_userInitProcess);//"Init process priority is 28" ret = OsProcessCreateInit(processCB, OS_USER_MODE, "Init", OS_PROCESS_USERINIT_PRIORITY);// Initialize the user process, which will be the parent process of all applications if (ret != LOS_OK) { return ret; } userText = LOS_PhysPagesAllocContiguous(initSize >> PAGE_SHIFT);// Allocate contiguous physical pages if (userText == NULL) { ret = LOS_NOK; goto ERROR; } (VOID)memcpy_s(userText, initSize, (VOID *)&__user_init_load_addr, initSize);// The result of security copy through loader load__ 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_PERM_EXECUTE | VM_MAP_REGION_FLAG_PERM_USER);// Mapping between virtual address and physical address if (ret < 0) { goto ERROR; } (VOID)memset_s((VOID *)((UINTPTR)userText + userInitBssStart - userInitTextStart), initBssSize, 0, initBssSize);// Except for the code segment, the rest are cleared 0 stack = OsUserInitStackAlloc(g_userInitProcess, &size);//The running stack of the assigned task in the user state is 1M in size if (stack == NULL) { PRINTK("user init process malloc user stack failed!\n"); ret = LOS_NOK; goto ERROR; } param.pfnTaskEntry = (TSK_ENTRY_FUNC)userInitTextStart;// Execution starts from the code area, which is the location of the main function of the application param.userParam.userSP = (UINTPTR)stack + size;// User status stack bottom param.userParam.userMapBase = (UINTPTR)stack;// User status stack top param.userParam.userMapSize = size;// User state stack size param.uwResved = OS_TASK_FLAG_PTHREAD_JOIN;// joinable can be reclaimed and killed by other threads ret = OsUserInitProcessStart(g_userInitProcess, ¶m);// Create a task to run the main function if (ret != LOS_OK) { (VOID)OsUnMMap(processCB->vmSpace, param.userParam.userMapBase, param.userParam.userMapSize); goto ERROR; } return LOS_OK; ERROR: (VOID)LOS_PhysPagesFreeContiguous(userText, initSize >> PAGE_SHIFT);//Freeing physical memory blocks OsDeInitPCB(processCB);//Delete PCB block return ret; }
unscramble
- From the code, we can see that the creation process of the ancestor of user mode is a little interesting. First, its source is the same as the ancestor of kernel mode in OsMain
- This is accomplished by creating a separate mode, priority 10 system task SystemInit The implementation of the task entry function SystemInit() is specified by the platform integrator This paper adopts the implementation of hi3516dv300 That is to say, the ancestor of user status was created in systask uwStackSize = LOSCFG_ BASE_ CORE_ TSK_ DEFAULT_ STACK_ SIZE;// Completed in 16K stack This task belongs to the kernel process KProcess
- The ancestor of user status is called Init, and the priority is level 28
- Each process in user mode has an independent virtual process space vmSpace and has independent memory mapping tables (L1 and L2 tables). The applied memory needs to be remapped. The mapping process is described in detail in the memory series
- Init creates a task whose entry address is__ user_init_entry, specified by the compiler
- User state process refers to the process that should be run by the program, which is started by dynamically loading ELF file The specific loading process is explained in the series, not in detail User mode processes run in user space, but can fall into kernel space through system calls See this picture for details:
Hongmeng source code 100 blog review
-
v46.xx (special progress chapter) | dragon born dragon, phoenix born phoenix, mouse born son can make holes < csdn | harmony >
-
v45.xx (fork) | how does fork call once and return twice? < csdn | harmony >
-
v44.xx (interrupt management) | implementation of hard interrupt < > observer mode < csdn | harmony >
-
v43.xx (interruption concept) | a powerful father-in-law of the Red Sea in the eyes of outsiders < csdn | harmony >
-
v42.xx (interrupt switching) | what exactly is interrupt switching switching? < csdn | harmony >
-
v41.xx (task switching) | assemble line by line annotation to analyze task context < csdn | harmony >
-
v40.xx (assembly summary) | all assembly codes are here < csdn | harmony >
-
v39.xx (abnormal takeover) | society is very simple, and people are complex < csdn | harmony >
-
v38.xx (register chapter) | all the registers of ARM are caught in one net, which is no longer mysterious < csdn | harmony >
-
v37.xx (system call) | overall anatomy system call implementation process < csdn | harmony >
-
v36.xx (working mode) | CPU is trinket. Which seven wives do you have? < csdn | harmony >
-
v35.xx (time management) | Tick is the basic time unit of the operating system < csdn | harmony >
-
v34.xx (atomic operation) | who is escorting atomic operation? < csdn | harmony >
-
v33.xx (message queuing) | how to transfer big data asynchronously and decoupled between processes? < csdn | harmony >
-
v32.xx (CPU) | how does the kernel describe the CPU? < csdn | harmony >
-
v31.xx (timer) | who is the highest priority task of the kernel? < csdn | harmony >
-
v30.xx (event control) | many to many synchronization scheme between tasks < csdn | harmony >
-
v29.xx (semaphores) | semaphores solve the problem of task synchronization < csdn | harmony >
-
v28.xx (process communication) | what are the nine ways of inter process communication? < csdn | harmony >
-
v27.xx (mutex) | mutex locks are much fuller than spin locks < csdn | harmony >
-
v26.xx (spin lock) | I really want to set up a chastity archway for spin lock! < csdn | harmony >
-
v25.xx (concurrent and parallel) | how to remember the difference between concurrent and parallel? < csdn | harmony >
-
v24.xx (process concept) | what resources are processes managing? < csdn | harmony >
-
v23.xx (assembly transfer reference) | how does assembly transfer complex parameters? < csdn | harmony >
-
v22.xx (compilation Basics) | where does the CPU clock in? < csdn | harmony >
-
v21.xx (thread concept) | who is constantly tossing the CPU? < csdn | harmony >
-
v20.xx (stack mode) | stack is the basis for building the underlying operation < csdn | harmony >
-
v19.xx (bitmap Management) | why do processes and threads have 32 priorities? < csdn | harmony >
-
v18.xx (source code structure) | how many can you answer correctly? < csdn | harmony >
-
v17.xx (physical memory) | remember that the partner algorithm will never forget < csdn | harmony >
-
v16.xx (Memory Rules) | what does memory management really care about? < csdn | harmony >
-
v15.xx (memory mapping) | what is the most important implementation basis of memory? < csdn | harmony >
-
v14.xx (memory assembly) | what is the implementation basis of virtual memory? < csdn | harmony >
-
v13.xx (source code comments) | love is all the reasons and answers < csdn | harmony >
-
v12.xx (memory management) | what is the panorama of virtual memory? < csdn | harmony >
-
v11.xx (memory allocation) | what are the allocation methods of memory? < csdn | harmony >
-
v10. How do the masters and slaves of the Forbidden City get along with each other? < csdn | harmony >
-
v09.xx (scheduling story) | using stories to tell kernel scheduling < csdn | harmony >
-
v08.xx (General Catalogue) | analysis of 100 blogs annotated with millions of Chinese characters < csdn | harmony >
-
v07.xx (scheduling mechanism) | how are tasks scheduled and executed? < csdn | harmony >
-
v06.xx (scheduling queue) | the effect of ready queue on Scheduling < csdn | harmony >
-
v05.xx (task management) | who is keeping the CPU busy? < csdn | harmony >
-
v04.xx (task scheduling) | task is the unit of kernel scheduling < csdn | harmony >
-
v03.xx (clock task) | where is the biggest power to trigger scheduling? < csdn | harmony >
-
v02.xx (process management) | process is the kernel resource management unit < csdn | harmony >
-
v01.xx (two-way linked list) | who is the most important structure of the kernel? < csdn | harmony >
Participation and contribution
-
Fork this warehouse >>New Feat_xxx Branch > > submit code comments > > Create a new Pull Request
If you like, please "like + follow + collect"
-
Search "Hongmeng kernel source code analysis" on major websites Welcome to reprint, please indicate the source