特權級--ring3到ring0_osdev

來源:互聯網
上載者:User

還記得嗎。我們用調用門和lcall指令實現特權級由低到高的轉移.

假設我們想由代碼A轉移到代碼B,運用一個調用門G,即調用門G中的目標選擇子指向代碼B的段。實際上我們要考慮4個要素:CPL、RPL、DPL_B(代碼B的DPL)、DPL_G(調用門G的DPL)。

第一步,當A訪問調用門G時,規則相當於訪問一個資料區段,要求CPL和RPL都小於或者等於DPL_G.也就是CPL和RPL需要在更高的特權級上。

第二步,除了上面系統還將比較CPL和DPL_B。如果是一致程式碼片段的話,要求DPL_B<=CPL;如果是非一致程式碼片段的話,call指令要求DPL_B<=CPL;jmp指令要求DPL_B==CPL.

 

當我們用call和調用門實現從ring3到ring0的轉移時,會從TSS載入ring0的堆棧STACKR0,然後將調用者ring3的ss、esp壓入新堆棧STACKR0,然後從調用者堆棧STACKR3中複製Param Count個參數併入棧,然後將當前ring3的cs和ip入棧,然後載入調用門中的新的cs和ip,開始執行被調用者的過程。

 

TSS結構如下: [plain] view plain copy LABEL_TSS:       .4byte  0           # Back       .4byte  TopOfStack      # 0 級堆棧       .4byte  SelectorStack               .4byte  0           # 1 級堆棧       .4byte  0           #        .4byte  0           # 2 級堆棧       .4byte  0           #        .4byte  0           # CR3       .4byte  0           # EIP       .4byte  0           # EFLAGS       .4byte  0           # EAX       .4byte  0           # ECX       .4byte  0           # EDX       .4byte  0           # EBX       .4byte  0           # ESP       .4byte  0           # EBP       .4byte  0           # ESI       .4byte  0           # EDI       .4byte  0           # ES       .4byte  0           # CS       .4byte  0           # SS       .4byte  0           # DS       .4byte  0           # FS       .4byte  0           # GS       .4byte  0           # LDT       .2byte  0           # 調試陷阱標誌       .2byte  . - LABEL_TSS + 2   # I/O位元影像基址       .byte   0xff                            # I/O位元影像結束標誌   .set     TSSLen,(. - LABEL_TSS)  




不過我想在一個開機磁區內搞定,而我們只用到了0級堆棧,所有我寫成了這樣: [plain] view plain copy LABEL_TSS:       .4byte  0           /* Back Link */       .4byte  TopOfStackR0  /* ESP0 */       .4byte  SelectorStackR0 /* SS0 */   .set    TSSLen, (. - LABEL_TSS)  


添加ring0的堆棧: [plain] view plain copy LABEL_STACKR0:   .space  20, 0   .set    TopOfStackR0, (. - LABEL_STACKR0)  


 

添加ring0堆棧的描述符和TSS的描述符以及對應的選擇子,然後初始化
Descriptor_STACKR0:Descriptor(0,TopOfStackR0, (DA_DRWA + DA_32))
LABEL_DESC_TSS: Descriptor(0,       (TSSLen - 1), DA_386TSS)

.set  SelectorStackR0,  (Descriptor_STACKR0  - GDT_START)
.set    SelectorTSS,    (LABEL_DESC_TSS - GDT_START)

InitDescrptor(Descriptor_STACKR0,LABEL_STACKR0);
InitDescrptor(LABEL_DESC_TSS,LABEL_TSS);

將調用門描述符的DPL改為DA_DPL3,將其選擇子的RPL改為SA_RPL3
Descriptor_Gate_Call:Gate(Selector_Code_Gate,0,0,(DA_386CGate+DA_DPL3)) 
.set  Selector_Code_Gate,(Descriptor_CODE_GATE-GDT_START+ SA_RPL3)

添加載入TSS的代碼:
movw     $(SelectorTSS), %ax    /* Load TSS to TR register */
ltr     %ax

在ring3代碼中列印完字元‘3’後添加
lcall $Selector_Gate_Call,$0
回到ring0

代碼如下: [plain] view plain copy #define Descriptor(base,lim,attr)\   .word lim&0xffff;\   .word base&0xffff;\   .byte (base>>16)&0xff;\   .word ((lim>>8)&0xf00)|(attr&0x0f0ff);\   .byte ((base>>24)&0xff)          /*     *InitDescrptor(Descriptor,SegBase)初始化描述符函數     *Descriptor:要初始化的描述符     *SegBase:段基址     */     #define InitDescrptor(Descriptor,SegBase)\   xor     %eax,%eax; \   mov     %cs,%ax  ; \   shl     $4,%eax  ; \   addl    $(SegBase), %eax ;\   movw    %ax, (Descriptor + 2);\   shr     $16, %eax;\   movb    %al, (Descriptor + 4);\   movb    %ah, (Descriptor + 7)        #define Gate(Selector,Offset,PCount,Attr)\   .2byte (Offset&0xffff);\   .2byte (Selector);\   .2byte (PCount&0x1f)|((Attr<<8)&0xff00);\   .2byte ((Offset>>16)&0xffff)        DA_386CGate = 0x8c   DA_C   = 0x98     DA_32  = 0x4000     DA_DRW = 0x92    DA_DRWA=0x93    SA_TIL = 0x4     DA_LDT = 0x82       SA_RPL3 = 3   DA_DPL0=0x00   DA_DPL1=0x20   DA_DPL2=0x40   DA_DPL3=0x60        DA_386TSS=0x89     .text     .globl start     .code16     start:      jmpl $0x0, $code            /**-----------------------------------------------------------------      * 通用描述元表: GDT      *-------------------------------*/          GDT_START:       Descriptor_DUMMY: Descriptor(0x0,0x0,0x0)     Descriptor_CODE32:Descriptor(0x0,0xffffffff,DA_C+DA_32)    Descriptor_STACKR0:Descriptor(0,TopOfStackR0, (DA_DRWA + DA_32))   Descriptor_VIDEO: Descriptor(0xb8000,0x0ffff,DA_DRW + DA_DPL3)     Descriptor_CODE_GATE:Descriptor(0x0,CodeGLen,DA_C+DA_32)   Descriptor_CODE3:Descriptor(0x0,0xffffffff,DA_C+DA_32+DA_DPL3)   Descriptor_STACKR3:Descriptor(0,TopOfStackR3, (DA_DRWA + DA_32 + DA_DPL3))   LABEL_DESC_TSS: Descriptor(0,       (TSSLen - 1), DA_386TSS)      /*門描述符*/    Descriptor_Gate_Call:Gate(Selector_Code_Gate,0,0,(DA_386CGate+DA_DPL3))     GDT_END:          GdtPtr:         .word (GDT_END-GDT_START)-1 # so does gdt          .long GDT_START     # This will be rewrite by code.        /**-----------------------------------------------------------------      * GDT中的選擇子    *-------------------------------*/    .set    selector_Code32,(Descriptor_CODE32-GDT_START)   .set  SelectorStackR0,  (Descriptor_STACKR0  - GDT_START)   .set    Selector_Video,(Descriptor_VIDEO-GDT_START)        .set  Selector_Code_Gate,(Descriptor_CODE_GATE-GDT_START+ SA_RPL3)   .set    selector_CodeR3,(Descriptor_CODE3-GDT_START+SA_RPL3)   .set    SelectorStackR3,(Descriptor_STACKR3- GDT_START + SA_RPL3)   .set    SelectorTSS,    (LABEL_DESC_TSS - GDT_START)   /*調用門選擇子*/   .set    Selector_Gate_Call,(Descriptor_Gate_Call-GDT_START)         /* 32-bit ring 3 stack segment. */   .align  4   LABEL_STACKR0:   .space  20, 0   .set    TopOfStackR0, (. - LABEL_STACKR0)         LABEL_STACKR3:   .space  20, 0   .set    TopOfStackR3, (. - LABEL_STACKR3)      LABEL_TSS:       .4byte  0           /* Back Link */       .4byte  TopOfStackR0  /* ESP0 */       .4byte  SelectorStackR0 /* SS0 */   .set    TSSLen, (. - LABEL_TSS)      /******************************************   *程式從這裡開始   */   code:         mov     %cs,%ax            mov     %ax,%ds          mov     %ax,%es             mov     %ax,%ss           mov  $0x8000,%sp               /*初始全域描述符Descriptor_CODE32*/     InitDescrptor(Descriptor_CODE32,LABEL_SEG_CODE32);        /*初始全域描述符Descriptor_CODE_GATE*/     InitDescrptor(Descriptor_CODE_GATE,LABEL_CODE_G);        /*初始全域描述符LABEL_STACKR0  ring0堆棧*/   InitDescrptor(Descriptor_STACKR0,LABEL_STACKR0);      /*初始全域描述符LABEL_STACKR3  ring3堆棧*/   InitDescrptor(Descriptor_STACKR3,LABEL_STACKR3);            /*初始全域描述符Descriptor_CODE3*/     InitDescrptor(Descriptor_CODE3,LABEL_CODE_3);      InitDescrptor(LABEL_DESC_TSS,LABEL_TSS);         /*載入gdtr即將通用描述元表gdt的首地址和gdt的界限賦給gdtr寄存器*/                lgdt GdtPtr          /*關中斷*/         cli          /*開啟地址線A20*/         inb $0x92,%al         or  $0x02,%al         outb %al,$0x92          /*設定cr0寄存器,切換到保護模式*/         movl %cr0,%eax         or   $1,%eax         movl %eax,%cr0               /*真正進入保護模式,執行此命令後CS=0x8,IP=0*/         ljmp $selector_Code32,$0                LABEL_SEG_CODE32:     .align  32     .code32            movw     $(SelectorStackR0), %ax       movw     %ax, %ss        movl     $(TopOfStackR0), %esp               movw $Selector_Video,%ax         movw %ax,%gs/* 視頻段選擇子(目的)*/                       movl $((80*11+79)*2),%edi/*第11行,79列*/         movb $0x0c,%ah/*高四位表示黑底,低四位表示紅字*/         movb $'P',%al/*顯示的字元*/         movw %ax,%gs:(%edi)                #ljmp $selector_CodeR3,$0       movw     $(SelectorTSS), %ax    /* Load TSS to TR register */       ltr     %ax        #lcall $Selector_Gate_Call,$0       pushl $SelectorStackR3       pushl $TopOfStackR3       pushl $selector_CodeR3       pushl $0       lret                lcall $Selector_Gate_Call,$0                              jmp .              LABEL_CODE_G:          movl $((80*12+0)*2),%edi/*第10行,0列*/         movb $0x0c,%ah/*高四位0000表示黑底,低四位1100表示紅字*/         movb $'G',%al/*要顯示的字元*/         movw %ax,%gs:(%edi)                        lret   .set CodeGLen,(. - LABEL_CODE_G)        LABEL_CODE_3:       movw $Selector_Video,%ax       movw %ax,%gs/* 視頻段選擇子(目的)*/       movl $((80*12+10)*2),%edi/*第10行,0列*/       movb $0x0c,%ah/*高四位0000表示黑底,低四位1100表示紅字*/       movb $'3',%al/*要顯示的字元*/       movw %ax,%gs:(%edi)              lcall $Selector_Gate_Call,$0      jmp .   .set Code3Len,(. - LABEL_CODE_3)        .org 0x1fe, 0x90      .word 0xaa55   


 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.