進入保護模式(五)簡單任務的安裝

1、任務

       任務是動態的概念,程序的執行狀態。程序給的解釋就是靜態的,例如桌面上放了個五子棋的程序。 小程序

       爲了保存任務的狀態,並在下次從新執行程序的時候恢復它們,每一個任務都應當擁有一個額外的內存區域記錄相關的信息,這叫作任務狀態段(TSS)。 安全

       這個地方寫這個與點不合適,由於麼有徹底看懂。 測試

       下面簡單在串一下。 spa

2、保護模式下的段式尋址

       在前面簡單介紹過,保護模式的尋址http://my.oschina.net/u/1185580/blog/182241 .net

       這裏詳細囉嗦下。 調試

  

      1.保護模式下的段是找的上圖這種的描述符 每一個描述符的大小是8個字節=2個雙字 code

      2.描述符有 全局描述符表、局部描述符秒、任務描述符表、中斷、門;描述符都在全局描述符中定義 blog

      3.上圖中的s=0 系統 type=1100(門);權限間的切換 ip

                                       0010(ldt 也就是局部描述符); 內存

                                       1001(任務ltr不忙);

                                       1011(任務ltr忙)

                    =1 代碼、數據段(type(第一位也就是11位)=0數據段;=1代碼段)

       下面是一個簡單的描述符的定義 

;建立1#描述符,這是一個數據段,對應0~4GB的線性地址空間
         mov dword [ebx+0x08],0x0000ffff    ;基地址爲0,段界限爲0xFFFFF
        mov dword [ebx+0x0c],0x00cf9200    ;粒度爲4KB,存儲器段描述符

      4.進入保護模式後,根據選擇子獲得 基地址+偏移量 而後檢查權限、檢查界限=安全的檢查

      5.暫且看的是,代碼數據段當即加載過去了;

                        若是是局部描述表要先獲得局部描述符的,lldt中,而後獲得局部描述符表信息;(<64KB大小)

                        若是是任務描述符則就應該是後面的偏移量是沒有用的

3、任務描述符的信息

      這些是記錄任務當前運行的狀態

      這裏說明下調用門的格式:

                                   31--------------------16-15----------------------------0

                                          選擇子                           偏移量15-0

                                   31--------------------16-15-14-13-12-11----8-7-4----0

                                          偏移量                 P   |DPL|  0   |TYPE| 0    參數個數


    調用門實施特權級的控制轉移,可使用jmp far指令,也可使用 call far 指令

    使用jmp far指令能夠將控制經過門轉移到比當前特權級別高的代碼段,但不改變當前的特權級別;

    若是使用call會改變當前特權級的CPL。1.堆棧的請求要求是必須與當前的特權級請求一致,哪意味着堆棧的切換

                                                  2.數據段的請求權限》=當前的權限

                                                  3.代碼段的請求權限 同級別或者依從【(權限《=當前)纔可使用】

                                                    type 11-8 10位是C位

                                                  系統不容許高的權限轉移到底的權限中。

call 段內轉移 esp入棧

call 段間轉移 cs、esp依次入棧

當沒有特權級變化的時候,cal,jmp均可以進入任務門。

*這樣的處理權限的轉換問題

當特權級切換的時候哪?

 

LABEL_TSS:  
        DD  0           ; Back  
        DD  0      ; 0 級堆棧,現處於0級  esp的值
         DD  0x00000020      ;堆棧選擇子   
         DD  0           ; 1 級堆棧  
         DD  0           ;   
        DD  0           ; 2 級堆棧  
         DD  0           ;   
        DD  0           ; CR3  
        DD  0           ; EIP  
        DD  0           ; EFLAGS  
        DD  0           ; EAX  
        DD  0           ; ECX  
        DD  0           ; EDX  
        DD  0           ; EBX  
        DD  0           ; ESP  
        DD  0           ; EBP  
        DD  0           ; ESI  
        DD  0           ; EDI  
        DD  0           ; ES  
        DD  0           ; CS  
        DD  0           ; SS  
        DD  0           ; DS  
        DD  0           ; FS  
        DD  0           ; GS  
        DD  0           ; LDT 就是0 
        DW  0           ; 調試陷阱標誌  
         DW  $ - LABEL_TSS + 2   ; I/O位圖基址 截取後16位  
         DB  0ffh            ; I/O位圖結束標誌  
TSSLen      equ $ - LABEL_TSS

4、集中起來的一個小程序

;目的是分頁的練習
;時間 2013-12-14 下午 週六

[org 0x7c00]
[bits 16]
		ldt_description         equ 0x00007F00
				 
                  mov ax,cs
	         mov ds,ax
		
		call show_style                    ;設置顯示模式 主要是清屏
		
		;計算GDT所在的邏輯段地址 
         mov eax,[pgdt+0x02]           ;獲得描述符的基地址  
         xor edx,edx
		 mov ebx,16
         div ebx            
         mov ds,eax                         ;令DS指向該段以進行操做
         mov ebx,edx                        ;段內起始偏移地址 
         
         ;建立0#描述符,它是空描述符,這是處理器的要求
		 
        ;建立1#描述符,這是一個數據段,對應0~4GB的線性地址空間
         mov dword [ebx+0x08],0x0000ffff    ;基地址爲0,段界限爲0xFFFFF
         mov dword [ebx+0x0c],0x00cf9200    ;粒度爲4KB,存儲器段描述符 

         ;建立保護模式下初始代碼段描述符
         mov dword [ebx+0x10],0x7c0001ff    ;基地址爲0x00007c00,界限0x1FF 
         mov dword [ebx+0x14],0x00409800    ;粒度爲1個字節,代碼段描述符 

         ;創建保護模式下的堆棧段描述符      ;基地址爲0x00007C00,界限0xFFFFE 
         mov dword [ebx+0x18],0x7c00fffe    ;粒度爲4KB 
         mov dword [ebx+0x1c],0x00cf9600
         
         ;創建保護模式下的顯示緩衝區描述符   
         mov dword [ebx+0x20],0x80007fff    ;基地址爲0x000B8000,界限0x07FFF 
         mov dword [ebx+0x24],0x0040920b    ;粒度爲字節
		 
		 ;爲了測試句不斷選擇子,大小就8個字節也就是一個ldt
		 mov eax,ldt_description         
		 shl eax,16
		 or eax,0x00000007
         mov dword [ebx+0x28],eax    ;基地址爲0,段界限爲8
         mov dword [ebx+0x2c],0x00408200    ;粒度爲4KB,存儲器段描述符 
		  
		  
		 mov eax, LABEL_TSS          ;TSS段基地址
		 shl eax,16
		 or eax,TSSLen-1
		 mov dword [ebx+0x28],eax
         mov dword [ebx+0x2c],0x00408900  
         ;=========================================================  		 
		 
         ;初始化描述符表寄存器GDTR
		 ;由於上面吧數據段地址改了因此這利用代碼段
         mov word [cs:pgdt],55  ;描述符表的界限(總字節數減一) n*8-1;  
          
         lgdt [cs:pgdt]
      
         in al,0x92                         ;南橋芯片內的端口 
         or al,0000_0010B
         out 0x92,al                        ;打開A20

         cli                                ;保護模式下中斷機制還沒有創建,應 
                                            ;禁止中斷 
         mov eax,cr0
         or eax,1
         mov cr0,eax                        ;設置PE位
      
         ;如下進入保護模式... ...
         jmp dword 0x0010:protect_loader-0x7C00;16位的描述符選擇子:32位偏移
		 
		 ;hlt                    ;程序終止
;===================showStyle=============================
show_style:                   ;設置顯示方式
	mov ah,0x00
	mov al,0x03
	int 10h
    ret		
;=========================================================
[bits 32]
        protect_loader:
		               
		                xor eax,eax
		                mov eax,0000_0000_00100_000B     ;#4 顯示段
					    mov es,eax                     
						
						mov byte[es:0x00],'H'
						mov byte[es:0x02],'E'
						mov byte[es:0x04],'L'
						mov byte[es:0x06],'L'
						mov byte[es:0x08],'O'
						mov byte[es:0x0a],','
						mov byte[es:0x0c],'O'
						mov byte[es:0x0e],'S'
		                
						mov eax,0000_0000_00001_000B  ;#1數據段 4G
						mov es,eax
						
	                    xor ebx,ebx
						mov ebx,ldt_description; 獲得偏移地址
						
						
						mov dword [es:ebx+0x00],0x7c0001ff
						mov dword [es:ebx+0x04],0x00409800    ;拼湊一個lldt的選擇子
						
						
						xor eax,eax
						mov ax,0000_0000_00101_000B     ;第五個描述符的位置
						
						lldt ax       ;加載lldt
						
						;hlt
						
						;jmp dword 0x0004:ldt_loader-0x7c00
						
						
						mov eax,0000_0000_00110_000B    ;#6 TSS段
                                                                ltr ax
                        
						xor esp,esp         ;esp設置爲0
						jmp dword ax:0
						
						hlt 	 ;程序終止		
;----------------------------------------------------------------
	    ldt_loader:                                      ;這裏是局部全局變量的加載
		                xor eax,eax
		                mov eax,0000_0000_00100_000B     ;#4 顯示段
					    mov es,eax                     
						
						mov byte[es:0x00+0xa0],'L'
						mov byte[es:0x02+0xa0],'L'
						mov byte[es:0x04+0xa0],'D'
						mov byte[es:0x06+0xa0],'T'
						
		           hlt;
		            
LABEL_TSS:  
        DD  0           ; Back  
        DD  0      ; 0 級堆棧,現處於0級  esp的值
        DD  0x00000020      ;堆棧選擇子   
        DD  0           ; 1 級堆棧  
        DD  0           ;   
        DD  0           ; 2 級堆棧  
        DD  0           ;   
        DD  0           ; CR3  
        DD  0           ; EIP  
        DD  0           ; EFLAGS  
        DD  0           ; EAX  
        DD  0           ; ECX  
        DD  0           ; EDX  
        DD  0           ; EBX  
        DD  0           ; ESP  
        DD  0           ; EBP  
        DD  0           ; ESI  
        DD  0           ; EDI  
        DD  0           ; ES  
        DD  0           ; CS  
        DD  0           ; SS  
        DD  0           ; DS  
        DD  0           ; FS  
        DD  0           ; GS  
        DD  0           ; LDT 就是0 
        DW  0           ; 調試陷阱標誌  
        DW  $ - LABEL_TSS + 2   ; I/O位圖基址 截取後16位  
        DB  0ffh            ; I/O位圖結束標誌  
TSSLen      equ $ - LABEL_TSS  			
						
;--------------數據段--------------------------------------------	
        pgdt       dw 0
	               dd 0x00007e00     ;GDT的物理地?
	         times 510-($-$$) db 0 
                   db 0x55 ;引導識別標示
                   db 0xaa

上面 首先實例化了 1.全局段描述符表GDT;lgdt

                       2.而後跳轉進入了保護模式

                       3.實例化了LDT的描述符表  經過4G的數據段

                       4.加載lldt、加載了ltr

                       5.最後根據ltr的這個選擇子進入了,lldt中的選擇子 0 (固然也能夠直接跳轉加載lldt的選擇子)

效果以下

相關文章
相關標籤/搜索