+ -
当前位置:首页 → 问答吧 → 关于利用时钟中断实现两个任务的切换

关于利用时钟中断实现两个任务的切换

时间:2011-06-28

来源:互联网

这和linux 0.00版本类似,不过我用nasm语法写的,我设置了两个tss,分别为两个任务一tss0和任务二tss2,他们的描述符和选择子特权级都为0,再在时钟中断中jmp SelectorTss0和jmp SelectorTss1这样切换,但不知为什么,切换老是出错,bochs显示为gdt descriptor 越界,弄了好久没出来
源代码如下:
%include "pm.inc"
org 0100h
jmp LABEL_BEGIN  
[SECTION .gdt]
LABEL_GDT: Descriptor 0, 0, 0 ;null descriptor
LABEL_DESC_NORMAL: Descriptor 0, 0ffffh, DA_DRW; normal descriptor
LABEL_DESC_CODE32: Descriptor 0, 0ffffh, DA_C+DA_32 ;kernel mode
LABEL_DESC_STACK0: Descriptor 0, TopOfStack0, DA_DRWA+DA_32
LABEL_DESC_STACK00: Descriptor 0, TopOfStack00, DA_DRWA+DA_32
LABEL_DESC_STACK01: Descriptor 0, TopOfStack01, DA_DRWA+DA_32
LABEL_DESC_STACK3: Descriptor 0, TopOfStack3, DA_DRWA+DA_32+DA_DPL3
LABEL_DESC_STACK13: Descriptor 0, TopOfStack13, DA_DRWA+DA_32+DA_DPL3
LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW+DA_32
LABEL_DESC_VIDEO: Descriptor 0b8000h, 0ffffh, DA_DRW+DA_32+DA_DPL3


LABEL_DESC_TSS0: Descriptor 0, Tss0Len-1, DA_386TSS
LABEL_DESC_TSS1: Descriptor 0, Tss1Len-1, DA_386TSS



LABEL_DESC_IDT: Descriptor 0, 0ffffh, DA_DRW+DA_32


LABEL_DESC_TASK0: Descriptor 0, 0ffffh, DA_C+DA_32+DA_DPL3
LABEL_DESC_TASK1: Descriptor 0, 0ffffh, DA_C+DA_32+DA_DPL3
GdtLen equ $ - LABEL_GDT
GdtPtr:
dw GdtLen
dd 0

SelectorNormal equ LABEL_DESC_NORMAL-LABEL_GDT+SA_RPL3
SelectorCode32 equ LABEL_DESC_CODE32-LABEL_GDT
SelectorStack0 equ LABEL_DESC_STACK0-LABEL_GDT
SelectorStack00 equ LABEL_DESC_STACK00-LABEL_GDT
SelectorStack01 equ LABEL_DESC_STACK01-LABEL_GDT
SelectorStack3 equ LABEL_DESC_STACK3-LABEL_GDT+SA_RPL3
SelectorStack13 equ LABEL_DESC_STACK13-LABEL_GDT+SA_RPL3
SelectorData equ LABEL_DESC_DATA-LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO-LABEL_GDT+SA_RPL3

SelectorTask0 equ LABEL_DESC_TASK0 - LABEL_GDT+SA_RPL3
SelectorTask1 equ LABEL_DESC_TASK1 - LABEL_GDT+SA_RPL3


SelectorTss0 equ LABEL_DESC_TSS0-LABEL_GDT
SelectorTss1 equ LABEL_DESC_TSS1-LABEL_GDT


SelectorIdt equ LABEL_DESC_IDT-LABEL_GDT


[SECTION .idt]
ALIGN 32
[BITS 32]
LABEL_IDT:
%rep 32
Gate SelectorCode32, NormalHandler, 0, DA_386IGate
%endrep
.20h:
Gate SelectorCode32, ClockHandler, 0, DA_386IGate
%rep 95
Gate SelectorCode32, NormalHandler, 0, DA_386IGate
%endrep
.80h:
Gate SelectorCode32, system_interrupt, 0, DA_386IGate+060h
%rep 127
Gate SelectorCode32, NormalHandler, 0,DA_386IGate
%endrep

IdtLen equ $ - LABEL_IDT
IdtPtr:
dw IdtLen
dd 0



[SECTION .stack0]
ALIGN 32
[BITS 32]
LABEL_STACK0:
times 512 dd 0
TopOfStack0 equ $ - LABEL_STACK0-1

[SECTION .stack00]
ALIGN 32
[BITS 32]
LABEL_STACK00:
times 512 dd 0
TopOfStack00 equ $ - LABEL_STACK00-1

[SECTION .stack01]
ALIGN 32
[BITS 32]
LABEL_STACK01:
times 512 dd 0
TopOfStack01 equ $ - LABEL_STACK01-1

[SECTION .stack3]
ALIGN 32
[BITS 32]
LABEL_STACK3:
times 512 db 0
TopOfStack3 equ $ - LABEL_STACK3-1

[SECTION .stack3]
ALIGN 32
[BITS 32]
LABEL_STACK13:
times 512 db 0
TopOfStack13 equ $ - LABEL_STACK13-1


[SECTION .tss0]
ALIGN 32
[BITS 32]
LABEL_TSS0:
dd 0 ;back
dd TopOfStack00 ;0 level stack
dd SelectorStack00
dd 0
dd 0 ;1 level stack
dd 0
dd 0 ;2 level stack
dd 0 ;cr3
dd 0 ;eip
dd 0 ;eflags allow time interrupt
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 SelectorTask0 ;cs
dd 0 ;ss
dd 0 ;ds
dd 0 ;fs
dd 0 ;gs
dd 0 ;ldt
dw 0 ;trap flag
dw $ - LABEL_TSS0+2 ;io bitmap base address
db 0ffh ;end flag
Tss0Len equ $ - LABEL_TSS0




[SECTION .tss1]
ALIGN 32
[BITS 32]
LABEL_TSS1:
dd 0 ;back
dd TopOfStack01 ;0 level stack
dd SelectorStack01
dd 0
dd 0 ;1 level stack
dd 0
dd 0 ;2 level stack
dd 0 ;cr3
dd 0 ;eip
dd 0200h ;eflags allow time interrupt
dd 0 ;eax
dd 0 ;ecx
dd 0 ;edx
dd 0 ;ebx
dd TopOfStack13 ;esp
dd 0 ;ebp
dd 0 ;esi
dd 0 ;edi
dd 0 ;es
dd SelectorTask1 ;cs
dd SelectorStack13 ;ss
dd 0 ;ds
dd 0 ;fs
dd SelectorVideo ;gs
dd 0 ;ldt
dw 0 ;trap flag
dw $ - LABEL_TSS1+2 ;io bitmap base address
db 0ffh ;end flag
Tss1Len equ $ - LABEL_TSS1





[SECTION .data]
ALIGN 32
[BITS 32]
LABEL_DATA:
_MessageStr_R: db "initial. . .",0
_MessageStr_P: db "In Protected Mode Now ...",0
_Current db 0
_Scr_loc: dd 0

MessageStr_R equ _MessageStr_R - $$
MessageStr_P equ _MessageStr_P - $$
Current equ _Current - $$
Scr_loc equ _Scr_loc - $$
DataLen equ $ - LABEL_DATA
[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov es, ax
mov ss, ax
mov fs, ax
mov ax, 0b800h
mov gs, ax


xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEGMENT_CODE32
mov word [LABEL_DESC_CODE32+2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE32+4], al
mov byte [LABEL_DESC_CODE32+7], ah ;initial kernel code segment 

xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_DATA
mov word [LABEL_DESC_DATA+2], ax
shr eax, 16
mov byte [LABEL_DESC_DATA+4], al
mov byte [LABEL_DESC_DATA+7], ah ;initial kernel data segment

xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_STACK0
mov word [LABEL_DESC_STACK0+2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK0+4], al
mov byte [LABEL_DESC_STACK0+7], ah ;initial system(kernel) stack segment

xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_STACK00
mov word [LABEL_DESC_STACK00+2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK00+4], al
mov byte [LABEL_DESC_STACK00+7], ah ;initial system(kernel) stack segment


xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_STACK01
mov word [LABEL_DESC_STACK01+2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK01+4], al
mov byte [LABEL_DESC_STACK01+7], ah ;initial system(kernel) stack segment


xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_STACK3
mov word [LABEL_DESC_STACK3+2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK3+4], al
mov byte [LABEL_DESC_STACK3+7], ah

xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_STACK13
mov word [LABEL_DESC_STACK13+2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK13+4], al
mov byte [LABEL_DESC_STACK13+7], ah


;initial task0 user mode - code and data at ring3
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_TSS0
mov word [LABEL_DESC_TSS0+2], ax
shr eax, 16
mov byte [LABEL_DESC_TSS0+4], al
mov byte [LABEL_DESC_TSS0+7], ah



xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_TSS1
mov word [LABEL_DESC_TSS1+2], ax
shr eax, 16
mov byte [LABEL_DESC_TSS1+4], al
mov byte [LABEL_DESC_TSS1+7], ah





xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEGMENT_TASK0
mov word [LABEL_DESC_TASK0+2], ax
shr eax, 16
mov byte [LABEL_DESC_TASK0+4], al
mov byte [LABEL_DESC_TASK0+7], ah


xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEGMENT_TASK1
mov word [LABEL_DESC_TASK1+2], ax
shr eax, 16
mov byte [LABEL_DESC_TASK1+4], al
mov byte [LABEL_DESC_TASK1+7], ah

;initial task1 user mode - code and data at ring3



;initial gdt descriptor
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_GDT
mov dword [GdtPtr+2], eax ;initial gdt


xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_IDT
mov dword [IdtPtr+2], eax


cli

lgdt [GdtPtr]

lidt [IdtPtr]

; 打开地址线A20
in al, 92h
or al, 00000010b
out 92h, al

; 准备切换到保护模式
mov eax, cr0
or eax, 1
mov cr0, eax

; 真正进入保护模式
jmp dword SelectorCode32:0 ; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0 处

请问用tss切换时,在tss里有高特权级的ss的esp,以及cs和eip就可以进行切换么?是不是还要什么特殊的要求?


















作者: bianzhuang09   发布时间: 2011-06-28


[SECTION .s32]
ALIGN 32
[BITS 32]
LABEL_SEGMENT_CODE32:
mov ax, SelectorStack0
mov ss, ax
mov ax, SelectorVideo
mov gs, ax
mov ax, SelectorData
mov ds, ax
mov esp, TopOfStack0

mov byte[gs:(12*80+5)*2],'p'
call Initial8259A
call Initial8253

mov ax, SelectorTss0
ltr ax

pushf
and dword[ss:esp], 0xffffbfff
popf
sti ;allow interrupt
push SelectorStack3
push TopOfStack3
push SelectorTask0
push 0
retf


Initial8259A:
mov al, 11h
out 020h, al
call io_delay

out 0Ah, al
call io_delay

mov al, 020h
out 021h, al ;20h~27h
call io_delay

mov al, 028h
out 0A1h, al
call io_delay ;028h~2Fh


mov al, 4
out 021h, al
call io_delay

mov al, 2
out 0A1h, al
call io_delay


mov al, 1
out 021h, al
call io_delay ;8086/8088 system

out 0A1h, al
call io_delay

mov al, 0feh ;main chip open timer interrupt
out 021h, al
call io_delay
mov al, 0ffh ;follow chip close timer interrupt
out 0A1h, al
call io_delay
ret
Initial8253:
mov al, 036h
out 043h, al
mov ax, 11931
out 040h, al
mov ah, al
out 040h, al ;100Hz
ret


_NormalHandler:
NormalHandler equ _NormalHandler - $$
push edx
push ecx
push ebx
push eax
mov bx, SelectorData
mov ds, bx
mov ebx, dword [ds:Scr_loc]
shl ebx, 1
mov byte [gs:ebx],'C'
shr ebx, 1
inc ebx
mov dword [ds:Scr_loc], ebx
pop eax
pop ebx
pop ecx
pop edx
iretd
_ClockHandler:
ClockHandler equ _ClockHandler - $$
push ds
push edx
push ecx
push ebx
push eax
mov al, 20h
out 020h, al
mov ax, SelectorData
mov ds, ax
cmp byte[ds:Current],1
jmp .change
mov byte [ds:Current], 1
call SelectorTss1:0
jmp .call_back
.change:
mov byte [ds:Current], 0
call SelectorTss0:0
.call_back:
pop eax
pop ebx
pop ecx
pop edx
pop ds
iretd
_system_interrupt:
system_interrupt equ _system_interrupt - $$
push ds
push edx
push ecx
push ebx
push eax
mov bx, SelectorData ;use kernel data
mov ds, bx
call write_char
pop eax
pop ebx
pop ecx
pop edx
pop ds
iretd
write_char:
push ebx
mov bx, SelectorVideo
mov gs, bx
mov bx, SelectorData
mov ds, bx
mov ebx, dword [ds:Scr_loc]
shl ebx, 1
mov byte [gs:ebx], al
shr ebx, 1
inc ebx
mov dword [ds:Scr_loc], ebx
pop ebx
ret
io_delay:
nop
nop
nop
nop
ret


[SECTION .task0]
ALIGN 32
[BITS 32]
LABEL_SEGMENT_TASK0:
mov bx, SelectorVideo
mov gs, bx
mov byte[gs:(12*80+6)*2],'0'
mov eax, 65
int 80h
mov ecx, 0fffh
.0 loop .0
jmp SelectorTask0:0
;jmp SelectorTss1:0
jmp $

[SECTION .task1]
ALIGN 32
[BITS 32]
LABEL_SEGMENT_TASK1:
mov bx, SelectorVideo
mov gs, bx
mov byte[gs:(12*80+8)*2],'1'
mov eax, 66
int 80h
mov ecx, 0fffh
.1 loop .1
jmp SelectorTask1:0
;jmp SelectorTss0:0
jmp $

作者: bianzhuang09   发布时间: 2011-06-28