【第7章】区分系统进程和用户进程

     现在我们的OS已经有4个进程在运行了,分别是TTY和A,B,C。其中ABC是实验性的进程,并不属于OS的一部分,而TTY进程则负责键盘的输入并在显示器中输出的任务,我们的OS要是没有它,就等于是个哑巴。所以我们有必要将它们区分开来,把TTY进程称为系统进程,把A,B,C进程称为用户进程。在程序实现上也就是让系统进程运行在RING1上,而让用户进程运行在RING3上。

     下面就来对程序进行修改,对于系统进程和用户进程的PCB表和TASK表区分开来,而在之前是在一起的,进程栈的空间也得区分开来。分别在global.h和global.c中添加:

Code:
  1. extern PCB User_PCB_Table[];       
  2. extern TASK User_Task_Table[];       
  3. extern u8 User_Proc_Stack_Space_Total[];     
Code:
  1. PCB User_PCB_Table[USER_PROC_NUM];       
  2. u8 User_Proc_Stack_Space_Total[USER_PROC_STACK_SIZE_TOTAL];       
  3. u8 Proc_Stack_Space_Total[PROC_STACK_SIZE_TOTAL];       
  4. TASK Task_Table[PROC_NUM] = { {tty,PROC_TTY_STACK_SIZE} };       
  5. TASK User_Task_Table[USER_PROC_NUM] = { {Proc_A,PROC_A_STACK_SIZE},       
  6.                                         {Proc_B,PROC_B_STACK_SIZE},       
  7.                                         {Proc_C,PROC_C_STACK_SIZE}       
  8.                                       };     

     对应的宏也要修改,在proc.h中:

Code:
  1. #define PROC_NUM                         1       
  2. #define USER_PROC_NUM                    3       
  3. #define USER_PROC_STACK_SIZE_TOTAL      (PROC_A_STACK_SIZE + /       
  4.                                          PROC_B_STACK_SIZE + /       
  5.                                          PROC_C_STACK_SIZE)       
  6. #define PROC_STACK_SIZE_TOTAL           (PROC_TTY_STACK_SIZE)     

     接下来修改初始化PCB的代码,我们把用户进程的LDT中的描述符的DPL都改为3,各段选择子的RPL也都改为3,在Init_PCB函数中修改:

Code:
  1. PCB *p_Cur_PCB = PCB_Table;   
  2.     TASK *p_Cur_Task = Task_Table;   
  3.     u8 *p_Cur_Top_Of_Stack = Proc_Stack_Space_Total + PROC_STACK_SIZE_TOTAL;   
  4.     u16 Cur_LDT_Index = INDEX_OF_FIRST_LDT;   
  5.     u32 i;   
  6.            
  7.     for(i = 0 ; i < PROC_NUM ; i++)   
  8.     {   
  9.         Memory_Set(p_Cur_PCB,sizeof(PCB),0);   
  10.         Memory_Copy(&GDT[1],&p_Cur_PCB->ldts[0],sizeof(Descriptor));   
  11.         Memory_Copy(&GDT[2],&p_Cur_PCB->ldts[1],sizeof(Descriptor));   
  12.         p_Cur_PCB->ldts[0].attr1 &= 0x9f;   
  13.         p_Cur_PCB->ldts[0].attr1 |= DA_DPL1;   
  14.         p_Cur_PCB->ldts[1].attr1 &= 0x9f;   
  15.         p_Cur_PCB->ldts[1].attr1 |= DA_DPL1;   
  16.         p_Cur_PCB->stack_frame.ds = 0 + 4 + 1;   
  17.         p_Cur_PCB->stack_frame.es = 0 + 4 + 1;    
  18.         p_Cur_PCB->stack_frame.gs = 24 + 1 ;    
  19.         p_Cur_PCB->stack_frame.fs = 0 + 4 + 1;    
  20.         p_Cur_PCB->stack_frame.ss = 0 + 4 + 1;    
  21.         p_Cur_PCB->stack_frame.esp = (u32)p_Cur_Top_Of_Stack;    
  22.         p_Cur_PCB->stack_frame.cs = 8 + 4 + 1;    
  23.         p_Cur_PCB->stack_frame.eip = (u32)p_Cur_Task->eip;    
  24.         p_Cur_PCB->stack_frame.eflags = 0x1202;    
  25.         p_Cur_PCB->LDT_Selector = (Cur_LDT_Index << 3);   
  26.         Fill_Desc(Cur_LDT_Index,(u32)p_Cur_PCB->ldts,sizeof(Descriptor) * 2 - 1,DA_LDT);   
  27.                
  28.         p_Cur_Top_Of_Stack -= p_Cur_Task->stack_size;   
  29.         p_Cur_PCB++;   
  30.         p_Cur_Task++;   
  31.         Cur_LDT_Index++;   
  32.     }   
  33.        
  34.     p_Cur_PCB = User_PCB_Table;   
  35.     p_Cur_Task = User_Task_Table;   
  36.     p_Cur_Top_Of_Stack = User_Proc_Stack_Space_Total + USER_PROC_STACK_SIZE_TOTAL;   
  37.        
  38.     for(i = 0 ; i < USER_PROC_NUM ; i++)   
  39.     {   
  40.         Memory_Set(p_Cur_PCB,sizeof(PCB),0);   
  41.         Memory_Copy(&GDT[1],&p_Cur_PCB->ldts[0],sizeof(Descriptor));   
  42.         Memory_Copy(&GDT[2],&p_Cur_PCB->ldts[1],sizeof(Descriptor));   
  43.         p_Cur_PCB->ldts[0].attr1 &= 0x9f;   
  44.         p_Cur_PCB->ldts[0].attr1 |= DA_DPL3;   
  45.         p_Cur_PCB->ldts[1].attr1 &= 0x9f;   
  46.         p_Cur_PCB->ldts[1].attr1 |= DA_DPL3;   
  47.         p_Cur_PCB->stack_frame.ds = 0 + 4 + 3;   
  48.         p_Cur_PCB->stack_frame.es = 0 + 4 + 3;    
  49.         p_Cur_PCB->stack_frame.gs = 24 + 3 ;    
  50.         p_Cur_PCB->stack_frame.fs = 0 + 4 + 3;    
  51.         p_Cur_PCB->stack_frame.ss = 0 + 4 + 3;    
  52.         p_Cur_PCB->stack_frame.esp = (u32)p_Cur_Top_Of_Stack;    
  53.         p_Cur_PCB->stack_frame.cs = 8 + 4 + 3;    
  54.         p_Cur_PCB->stack_frame.eip = (u32)p_Cur_Task->eip;    
  55.         p_Cur_PCB->stack_frame.eflags = 0x202;    
  56.         p_Cur_PCB->LDT_Selector = (Cur_LDT_Index << 3);   
  57.         Fill_Desc(Cur_LDT_Index,(u32)p_Cur_PCB->ldts,sizeof(Descriptor) * 2 - 1,DA_LDT);   
  58.                
  59.         p_Cur_Top_Of_Stack -= p_Cur_Task->stack_size;   
  60.         p_Cur_PCB++;   
  61.         p_Cur_Task++;   
  62.         Cur_LDT_Index++;   
  63.     }  

      接着在调度程序中也得修改,在Clock_Handler函数中修改:

Code:
  1. while(greatest_ticks == 0)   
  2.     {   
  3.         for(p_PCB = PCB_Table ; p_PCB < PCB_Table + PROC_NUM ; p_PCB++)   
  4.         {   
  5.             if(p_PCB->ticks > greatest_ticks)   
  6.             {   
  7.                 greatest_ticks = p_PCB->ticks;   
  8.                 p_Resume_PCB = p_PCB;   
  9.             }   
  10.         }   
  11.            
  12.         for(p_PCB = User_PCB_Table ; p_PCB < User_PCB_Table + USER_PROC_NUM ; p_PCB++)  
  13.         {   
  14.             if(p_PCB->ticks > greatest_ticks)   
  15.             {   
  16.                 greatest_ticks = p_PCB->ticks;   
  17.                 p_Resume_PCB = p_PCB;   
  18.             }   
  19.         }   
  20.            
  21.         if(greatest_ticks == 0)   
  22.         {   
  23.             for(p_PCB = PCB_Table ; p_PCB < PCB_Table + PROC_NUM ; p_PCB++)   
  24.             {   
  25.                 p_PCB->ticks = p_PCB->priority;   
  26.             }   
  27.                
  28.             for(p_PCB = User_PCB_Table ; p_PCB < User_PCB_Table + USER_PROC_NUM ; p_PCB++)   
  29.             {   
  30.                 p_PCB->ticks = p_PCB->priority;   
  31.             }   
  32.         }   
  33.     }  

     最后别忘了在Init_GDT函数中把Video描述符的DPL改为3:

Code:
  1. Fill_Desc(3,0xb8000,0xffff,DA_DRW + DA_DPL3);      

     搞定,make,运行,会发现没什么改变。但我们已经实现了系统进程和用户进程的区分。

你可能感兴趣的:(【第7章】区分系统进程和用户进程)