凌云窟
南山巅上火麟烈,北海潜深雪饮寒。可怜两锋未缘见,雪刀封隐孤剑鸣。
<2008年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

留言簿(0)

随笔分类

随笔档案

文章档案

相册

简历下载

搜索

最新评论

阅读排行榜

评论排行榜

 
VC知识库BLOG   首页  新随笔  联系  聚合  登录 
  随笔-22 文章-0 评论-38 Trackbacks-0

       以前我研究过ucosII的源代码,对应于x86来说,ucos是实模式下面的操作系统。而Minix是保护模式下的操作系统,自然他们的Context Switch有不一样的地方,现在,我就结合我知道的知识谈一下二者的区别。
      Context Switch是多任务操作系统必不可少的部分,它的主要任务就是保护cpu的执行现场,将cpu的寄存器保存起来。在这一点上Minix3 和ucosII是没有区别的。同时二者在实现的层面上都和堆栈有关。
      现在着重谈一下他们的区别:
      第一个首要关注的地方就是x86的硬件体系,保护模式下的内容远远比实模式丰富,研究保护模式下的操作系统,必然跟GDT、LDT、IDT发生关系。所以,保护模式下Conext Switch就要比实模式复杂些。
      ucosII在实现Context Switch时,仅仅将cpu的执行现场也就是寄存器保存在任务自己的堆栈中,保存和还原任务寄存器的功能都是通过中断机制完成的。保护模式下的Context Switch的内容就要丰富的多,首要提到的东西就是新增加的tr寄存器,tr寄存器保存的是任务状态段
TSS的段选择子。

struct tss_s 
{
  reg_t backlink;
  reg_t sp0;                    
/* stack pointer to use during interrupt */
  reg_t ss0;                    
/*   "   segment  "  "    "        "     */
  .
  .
}

struct tss_s tss;
tss.ss0 
= DS_SELECTOR;
init_dataseg(
&gdt[TSS_INDEX], vir2phys(&tss), sizeof(tss), INTR_PRIVILEGE);
  gdt[TSS_INDEX].access 
= PRESENT | (INTR_PRIVILEGE << DPL_SHIFT) | TSS_TYPE;

        可以看出,TSS段实际上就是保存一个tss_s结构。那tss_s又有什么用?
         首先需要说明,保护模式下发生Context Switch时,cpu寄存器并不是保存在自己的工作堆栈中的,而是保存在进程控制块中的。
struct proc 
{
  
struct stackframe_s p_reg;    /* process' registers saved in stack frame */
  .
  .
}
        tss_s的两个最重要的成员就是sp0和ss0。ss0用来指明任务控制块位于数据段内,sp0就指向p_reg的最高位,因为x86的堆栈是向下增加的。
       这样,当中断发生时,通过tr就能够找到tss的sp0和ss0,然后就能够寻址到p_reg,中断将自动压入一些寄存器的指,另外一些则需要我们来压入,如下通过save函数。以下是一个简化的中断处理过程。
 call    save            
    .                          
    ret           
!为什么是ret而不是iret,因为ret会跳到_restart然后iret(?push    _restart?)

相关代码如下:

    .align    
16
save:
    cld            
! set direction flag to a known value
    pushad            
! save EAX, ECX, EDX, EBX, original ESP, EBP,
                                
! ESI, and EDI registers
    o16    push    ds        
! save ds
    o16    push    es        
! save es
    o16    push    fs        
! save fs
    o16    push    gs        
! save gs
    mov    dx, ss        
! ss is kernel data segment, tss.ss0 = DS_SELECTOR
    mov    ds, dx        
! load rest of kernel segments
    mov    es, dx        
! kernel does not use fs, gs
    mov    eax, esp    
! prepare to return
    incb    (_k_reenter)    
! from -1 if not reentering
    jnz    set_restart1    
! stack is already kernel stack
    mov    esp, k_stktop   
!
    push    _restart    
! build return address for int handler
    xor    ebp, ebp    
! for stacktrace
    jmp    RETADR
-P_STACKBASE(eax) !堆栈sp已经被改变了,所以只能够通过硬寻址找到返回地址

    .align    
4
set_restart1:
    push    restart1    
!存在中断嵌套
    jmp    RETADR
-P_STACKBASE(eax)
    
_restart:

! 找到更高优先级的任务,并将相应任务控制块的p_reg赋值给tss.sp0 

    cmp    (_next_ptr), 
0        ! see if another process is scheduled
    jz    0f
    mov     eax, (_next_ptr)
    mov    (_proc_ptr), eax    
! schedule new process 
    mov    (_next_ptr), 
0
0:    mov    esp, (_proc_ptr)    ! will assume P_STACKBASE == 0
    lldt    P_LDT_SEL(esp)        
! enable process' segment descriptors 
    lea    eax, P_STACKTOP(esp)    ! arrange for next interrupt
    mov    (_tss
+TSS3_S_SP0), eax    ! to save state in process table
restart1:
    decb    (_k_reenter)
    o16    pop    gs
    o16    pop    fs
    o16    pop    es
    o16    pop    ds
    popad
    add    esp, 
4        ! skip return adr(?call save?)
    iretd            
! continue process

-----------------------------------------------------------------------------------------------------------
      如果随笔中有什么错误,还请大家指教。谢谢!
posted on 2006-09-04 15:57 莫问春秋 阅读(4562) 评论(2)  编辑 收藏
Comments
  • # re: Minix3 Context Switch实现分析
    tarjan
    Posted @ 2006-09-17 09:04
    i download minix3 3.1.2. 
    i use vmware , 
    but after i install the xwindow and  other softwares , 
    i can't start x-window. 
    os  warns me that u should check the path. 
    also ,how can i use cdrom in vmware. 
    i use 
    mount /dev/c0d2p2 /cdrom 
    and mount /dev/c0d2p2 /mnt 
    both are wrong , can u help me?
    thank you !! 

  • # re: Minix3 Context Switch实现分析
    yrj
    Posted @ 2006-09-18 00:58
    _restart:

    !!!!!!!! Restart the current process or the next process if it is set. 

    cmp (_next_ptr), 0 ! see if another process is scheduled
    jz 0f
    mov  eax, (_next_ptr)
    mov (_proc_ptr), eax ! schedule new process 
    mov (_next_ptr), 0
    0: mov esp, (_proc_ptr) ! will assume P_STACKBASE == 0
    lldt P_LDT_SEL(esp) ! enable process' segment descriptors 
    lea eax, P_STACKTOP(esp) ! arrange for next interrupt
    mov (_tss+TSS3_S_SP0), eax ! to save state in process table
    restart1:
    decb (_k_reenter)
        o16 pop gs
        o16 pop fs
        o16 pop es
        o16 pop ds
    popad
    add esp, 4 ! skip return adr
    iretd ! continue process

    看看这一句
    !!!!!!!! Restart the current process or the next process if it is set. 
标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]