Name: Wang Chenguang
Study No.: 20133232
Wang Chenguang + original works reproduced please specify the source + "Linux kernel analysis" MOOC course http://mooc.study.163.com/course/USTC-1000029000
First, the process of starting and switching source code and analysis
typedef struct PCBs are used to represent a process that defines a process-management-related data structure. The data types used to hold the EIP and ESP are also set.
The following code is part of the MYMAIN.C code:
void__init My_start_kernel (void){intPID =0; inti; Task[pid].pid= PID;/*Initialize the process number to 0*/task[pid].state=0; Task[pid].task_entry= Task[pid].thread.ip = (unsignedLong) my_process;/*initializes the entry and EIP of the process to the entry address of the My_process function*/TASK[PID].THREAD.SP= (unsignedLong) &task[pid].stack[kernel_stack_size-1];/*saves the stack top address as the last element of the stack, which is the highest address*/Task[pid].next= &Task[pid];/*The next pointer points to yourself*/ for(i=1; i<max_task_num;i++) {memcpy (&task[i],&task[0],sizeof(TPCB));/*Copy the information from task[0] to each new process*/Task[i].pid= i;/*set the PID of the new process to variable i*/task[i].state= -1;/*the status of the new process is unrunnable*/TASK[I].THREAD.SP= (unsignedLong) &task[i].stack[kernel_stack_size-1Task[i].next= task[i-1].next; Task[i-1].next = &Task[i]; } /*START process 0 by task[0]*/PID=0; My_current_task= &task[pid];//set the current process to process number No. 0Asmvolatile(/*Put esp in process No. 0 into ESP register*/ "MOVL%1,%%esp\n\t" /*set TASK[PID].THREAD.SP to ESP*/ "PUSHL%1\n\t" /*Push EBP*/ "PUSHL%0\n\t" /*Push Task[pid].thread.ip*/ "ret\n\t" /*pop task[pid].thread.ip to Eip*/ "popl%%ebp\n\t" : : "C"(TASK[PID].THREAD.IP),"D"(TASK[PID].THREAD.SP)/*input C or D mean%ecx/%edx*/ );}
The system always starts from process No. 0. The main task of the above code is to initialize the process, and then start the first process, after performing the RET operation will jump to the next function to execute.
The code for MYINTERRUPT.C part of the code:
voidMy_timer_handler (void){#if1/*The function executes 1000 times per execution, and my_need_sched is not equal to 1 when the If judgment is executed, then the my_need_sched is set to 1*/ if(time_count% +==0&& my_need_sched! =1) {PRINTK (Kern_notice">>>my_timer_handler here<<<\n"); My_need_sched=1; } Time_count++ ; #endif return; }voidMy_schedule (void) {TPCB* NEXT;/*Next Process*/TPCB* PREV;/*Current Process*/ if(My_current_task = =NULL|| My_current_task->next = =NULL) { return; } PRINTK (Kern_notice">>>my_schedule<<<\n");/*Schedule*/Next= my_current_task->Next;prev=My_current_task; if(Next->state = =0)/*-1 unrunnable, 0 runnable, >0 stopped*/ { /*switch to Next process*/ASMvolatile( "PUSHL%%ebp\n\t" /*Save EBP*/ "MOVL%%esp,%0\n\t" /*Save ESP*/ "MOVL%2,%%esp\n\t" /*Restore ESP*/ "MOVL $1f,%1\n\t" /*Save Eip*/ "PUSHL%3\n\t" "ret\n\t" /*Restore EIP*/ "1:\t" /*Next process start here*/ "popl%%ebp\n\t" : "=m"(PREV->THREAD.SP),"=m"(prev->thread.ip):"m"(NEXT->THREAD.SP),"m"(next->Thread.ip)); My_current_task=Next; PRINTK (Kern_notice">>>switch%d to%d<<<\n",prev->pid,next->pid); } Else{Next->state =0; My_current_task=Next; PRINTK (Kern_notice">>>switch%d to%d<<<\n",prev->pid,next->pid); /*switch to New process*/ASMvolatile( "PUSHL%%ebp\n\t" /*Save EBP*/ "MOVL%%esp,%0\n\t" /*Save ESP*/ "MOVL%2,%%esp\n\t" /*Restore ESP*/ "MOVL%2,%%ebp\n\t" /*Restore EBP*/ "MOVL $1f,%1\n\t" /*Save Eip*/ "PUSHL%3\n\t" "ret\n\t" /*Restore EIP*/ : "=m"(PREV->THREAD.SP),"=m"(prev->thread.ip):"m"(NEXT->THREAD.SP),"m"(next->Thread.ip)); } return; }
In this code, the My_schedule function is the focus, which realizes the interrupt processing process of the time slice rotation. This function is executed two times, the first is the No. 0 process jumps to the 1th process, and the second entry is the execution of the POP1 ebp recovery site, and then the return function, returned to the original caller is the process of the number No. 0.
Second, the experimental process
Use the built environment to open the file in the lab building
Running the program
MYMAIN.C Program code
MYINTERRUPT.C Program code
Experimental summary: The experiment process in the source code of many lines of code can not understand, through the Baidu, watch the video has a certain understanding, but also a general understanding of how the operating system is working. We can assume that a process is equivalent to a stack, and each process has its own stack space. If EBP and ESP are modified to the EBP and ESP of another process, the process can be switched on. When the process switches, the system also saves the current working state so that the process can continue execution the next time the process is resumed.
Linux kernel Analysis-how the operating system works