Question about Hardware Task Switch?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.

Moderators: JAAman, klange, Octocontrabass, sortie, kmcguire, chase, thepowersgang, Owen, Combuster, AJ, 01000101, carbonBased, Candy, pcmattman

Post Reply
chen17981

Question about Hardware Task Switch?

Post by chen17981 »

Hi everyone, now I have a question about task switch.
When I use call intruction to swithc to a task, it will reset Bochs.
I don't know why. By the way,I put my code above 0xf0100020 in linear address, actully the phyical address is above 0x100020. Following is my code:

Compile by NASM

Code: Select all

[bits 32]   

%define   RELOC(x) ((x) - 0xf0000000)
   
jmp start
   
GDT:
NULL_SEL         EQU $-GDT    ; null descriptor is required
                                         ;(64bit per entry)
      DD 0x0
      DD 0x0
CODESEL          EQU $-GDT    ; 4GB Flat Code at 0x0 with 
                                         ;max 0xFFFFF limit
      DW     0xFFFF                ; Limit(15-0 bit):0xFFFF
      DW     0x0                     ; Base(15-0 bit)
      DB     0x0                      ; Base(23-16 bit)
      DB     0x9A                    ; Type:
      DB     0xCF                    ; Limit| Flags
      DB     0x10                    ; Base(31-24 bit)
DATASEL          EQU $-GDT    ; 4GB Flat Data at 0x0 with 
                                         ;max 0xFFFFF limit
      DW     0xFFFF                ; Limit(15-0 bit):0xFFFF
      DW     0x0                     ; Base(15-0 bit)
      DB     0x0                      ; Base(23-16 bit)
      DB     0x92                    ; Type:
      DB     0xCF                    ; Limit(19-16 bit):0xF | Flags
      DB     0x10                    ; Base(31-24 bit)

SYS_TSS      equ   $-GDT ; system TSS
gdt6:   dw 103
   dw 0         ; set to stss
   db 0
   db 0x89         ; present, ring 0, 32-bit
   db 0
   db 0
USER_TSS   equ   $-GDT
gdt7:   dw 103         ; user TSS
   dw 0         ; set to utss
   db 0
   db 0x89         ; present, ring 0, 32-bit
   db 0
   db 0
GDT_END:

GDTR:
GDTsize DW GDT_END-GDT-1   ;limit of GDT
   DD RELOC(GDT)        ;address mygdt


;   task state segments
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
stss:   dw 0, 0         ; back link
   dd 0         ; ESP0
   dw 0, 0         ; SS0, reserved
   dd 0         ; ESP1
   dw 0, 0         ; SS1, reserved
   dd 0         ; ESP2
   dw 0, 0         ; SS2, reserved
   dd 0, 0, 0      ; CR3, EIP, EFLAGS
   dd 0, 0, 0, 0      ; EAX, ECX, EDX, EBX
   dd 0, 0, 0, 0      ; ESP, EBP, ESI, EDI
   dw DATASEL, 0         ; ES, reserved
   dw CODESEL, 0      ; CS, reserved
   dw DATASEL, 0         ; SS, reserved
   dw DATASEL, 0         ; DS, reserved
   dw DATASEL, 0         ; FS, reserved
   dw DATASEL, 0         ; GS, reserved
   dw 0, 0         ; LDT, reserved
   dw 0, 0         ; debug, IO perm.bitmap

utss:   dw 0, 0         ; back link
   dd 0         ; ESP0
   dw 0, 0         ; SS0, reserved
   dd 0         ; ESP1
   dw 0, 0         ; SS1, reserved
   dd 0         ; ESP2
   dw 0, 0         ; SS2, reserved
   dd 0         ; CR3
utss_eip:
   dd 0, 0         ; EIP, EFLAGS
   dd 0, 0, 0, 0      ; EAX, ECX, EDX, EBX
utss_esp:
   dd 0, 0, 0, 0      ; ESP, EBP, ESI, EDI
   dw DATASEL, 0           ; ES, reserved
   dw CODESEL, 0           ; CS, reserved
   dw DATASEL, 0      ; SS, reserved
   dw DATASEL, 0      ; DS, reserved
   dw DATASEL, 0      ; FS, reserved
   dw DATASEL, 0      ; GS, reserved
   dw 0, 0         ; LDT, reserved
   dw 0, 0         ; debug, IO perm. bitmap
end:


[global start]   
start: 
   lgdt   [RELOC(GDTR)]         ; load descriptor
        jmp     0x8:chen
chen:       
   mov   ax,DATASEL   ; set up data segment
   mov   ds,ax         ;
   mov   es,ax         ;
   mov   fs,ax              ;
   mov   gs,ax              ;
   mov   ss,ax
   mov    ebp,0x0
   mov     esp,0xf000ffff
   
   lea eax,[ds:stss]      ; set SYS_TSS
   mov [ds:gdt6 + 2],ax
   shr eax,16
   mov [ds:gdt6 + 4],al
   mov [ds:gdt6 + 7],ah
   
   lea eax,[ds:utss]      ; set USER_TSS
   mov [ds:gdt7 + 2],ax
   shr eax,16
   mov [ds:gdt7 + 4],al
   mov [ds:gdt7 + 7],ah


; initialize user TSS
   lea eax,[ds:user]      ; task entry point
   mov [ds:utss_eip],eax
   mov [ds:utss_esp],esp
   
; *** NOTE! ***
; ltr in real mode causes an illegal instruction interrupt
;   
   mov ax,SYS_TSS
   ltr ax
   
; call user task
   call USER_TSS:0

; print ending msg
   call vedio3
END:
   jmp END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   user task
user:   
   mov     byte [ds:0xf00b8002],'X'
   mov     byte [ds:0xf00b8003],0x07
; the task switch set the NT bit, so iret does a return-from-;task
   iret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   character-output video routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

vedio3:
   mov     byte [ds:0xf00b8003],'C'
   mov     byte [ds:0xf00b8004],0x07
   ret


Please also note that if I put my code above 0x100020 linear address which is equal to the physical address, only do some small modification to above code, I could successfully call my USER_TASK. I am very confused about that.

Hope someone could give me some suggestion. Thanks in advance.
Post Reply