ウォンツテック

そでやまのーと

OS作成 - ページング&プロセス編

ユーザプロセスのPrivilege Levelを3にする事に成功。
やり方はLinuxに近いけど以下のようにespから0x80離れたかなり深いスタックにあるiret時のeip,cs,eflags,ss,espを強制的に上書きしました。
※asm_process_switch, i20h_process_switch, switch_toと3つの関数を経由しているのでこんな深さになってます。

NEXT_CS         = 0x8                                                           
NEXT_DS         = 0xC                                                           
NEXT_ESP        = 0x10                                                          
NEXT_CR3        = 0x14                                                          
NEXT_EIP        = 0x18                                                          
PREV            = 0x1C                                                          
NEXT_COUNT      = 0x20                                                          
PREV_EIP        = 0x24                                                          
                                                                                
IRET_EIP        = 0x80 
IRET_CS         = 0x84                                                          
IRET_EFLAGS     = 0x88                                                          
IRET_ESP        = 0x8C                                                          
IRET_SS         = 0x90                                                          
                                                                                
.global switch_to                                                               
switch_to:                                                                      
        pushl   %ebp                                                            
        movl    %esp, %ebp                                                      
        movl    NEXT_COUNT(%ebp), %eax                                          
        cmp     $0, %eax                                                        
        jz      1f                                                              
        pushl   IRET_ESP(%ebp)                                                  
        pushl   IRET_EIP(%ebp)                                                  
        jmp     2f                                                              
1:                                                                              
        pushl   NEXT_ESP(%ebp)                                                  
        pushl   PREV_EIP(%ebp)                                                  
2:                                                                              
        pushl   PREV(%ebp)                                                      
        call    set_context                                                     
        addl    $12, %esp                                                       
        movl    NEXT_CR3(%ebp), %eax                                            
        movl    %eax, %cr3                                                      
                                                                                
        movl    NEXT_CS(%ebp), %eax                                             
        movl    %eax, IRET_CS(%ebp)                                             
        movl    NEXT_DS(%ebp), %eax                                             
        movl    %eax, IRET_SS(%ebp)                                             
        movl    NEXT_ESP(%ebp), %eax                                            
        movl    %eax, IRET_ESP(%ebp)                                            
        movl    NEXT_EIP(%ebp), %eax                                            
        movl    %eax, IRET_EIP(%ebp)                                            
        popl    %ebp                                                            
        ret

また、全ての割り込みディスクリプタのDPLをとりあえず3にしてあります。これは後々必要な所のみ3にする必要がありそうです。
まだユーザプロセス用のスタックとカーネル用のスタックがごっちゃになってる気がするのでそこら辺の修正が必要です。


sodex rev.23