minix的进程怎么实现的?

看了 于渊 的<自己动手写操作系统>一书,其中的进程实现主要是这么几下子:

 1.保存寄存器的值,保存堆栈的值.

 2.完成中断处理.

3.加载新进程的堆栈和寄存器.           

      其中1.部里面,的寄存器的值往哪里保存呢. 首先,中断发生之前,正在运行的进程的esp和ss都保存在了TSS的0优先级的地方.      ;;;这时如果发生中断,那么当前的esp和ss就会由CPU赋值,这个值就是从TSS中的0优先级的地方取得的        

  1.里面的中断处理里面,通过mov esp, StackTop手工把堆栈设成0级的堆栈.  

  3.中断处理完后,由于进程表s_proc特殊的结构,已经为下面pop寄存器的值做好了准备,因此几个pop之后,当前寄存器的值又都加载完毕了.(当然,加载的不一定是刚才保存的寄存器值.可能会加载别的进程表里存储的值,只是另外的进程就开始运行了.)

     其中有个问题不太明白的是TSS的0级ESP和SS中加载的是某个进程的进程表的frame下面的一个地址,如果在进程运行中发生了有特权级变化的门转移怎么办?这时的ss和esp也是要从TSS的同一个位置取的.那取得的值不就乱了吗?当然,也可以在门转移后的代码里手工加上SS和ESP赋值的代码,但是这样不就没有利用CPU的这个特性了吗?     以上是个人的一点看法,请各位看官指教,呵呵.

     为了让大家检索得到,我把那段经典得切换代码粘在下面.呵呵.

;下面这段是首次进行进程切换时候的代码

 restart:  

mov esp, [p_proc_ready] 

  lldt [esp + P_LDT_SEL]

   lea eax, [esp + P_STACKTOP]   mov dword [tss + TSS3_S_SP0], eaxrestart_reenter:   dec dword [k_reenter]   pop gs   pop fs   pop es   pop ds   popad   add esp, 4   iretd  

 ;下面这段是中断发生后cpu进来执行的地方.

 hwint00:  

; Interrupt routine for irq 0 (the clock). 

sub esp, 4 pushad  ; ┓ push ds ; ┃ push es ; ┣ 保存原寄存器值 push fs ; ┃ push gs ; ┛ mov dx, ss mov ds, dx mov es, dx  ;inc byte [gs:0] ; 改变屏幕第 0 行, 第 0 列的字符  mov al, EOI  ; ┓reenable master 8259 out INT_M_CTL, al ; ┛  inc dword [k_reenter] cmp dword [k_reenter], 0 jne .re_enter  mov esp, StackTop  ; 切到内核栈  sti  push 0 call clock_handler add esp, 4  cli  mov esp, [p_proc_ready] ; 离开内核栈; lldt [esp + P_LDT_SEL] lea eax, [esp + P_STACKTOP] mov dword [tss + TSS3_S_SP0], eax .re_enter: ; 如果(k_reenter != 0),会跳转到这里 dec dword [k_reenter] ; k_reenter--; pop gs ; ┓ pop fs ; ┃ pop es ; ┣ 恢复原寄存器值 pop ds ; ┃ popad  ; ┛ add esp, 4  iretd

 

你可能感兴趣的:(存储)