Multitasking
Posted: Wed Jul 02, 2003 11:00 pm
I am begin programming the 'task manager' of my OS.
By now, I like to switch from the kernel to another task, both at ring 0.
My kernel is loaded at 0x50000 but the GDT and TSS(s) are outside the kernel. The GDT is at 0x3800 and the TSS(s) area is at 0x35800. I must use code to put data at these structures!
The OS define:
; Linear adresses
dir_GDT equ 0x3800 ; GDT
dir_LDT_ini equ 0x34800 ; LDT(s) for the tasks
dir_TSS_ini equ 0x35800 ; TSS(s) for the tasks
dir_KERNEL equ 0x50000 ; Kernel linear address
...
; Descriptors
desc_lineal equ 8 ; Lineal descriptor
desc_kernel_c equ 16 ; code's kernel descriptor
desc_kernel_d equ 24 ; data's kernel descriptor
desc_LDT_ini equ 32 ; 128 LDT descriptors (not used)
desc_TSS_ini equ 1056 ; 128 TSS descriptors
...
I use this code to load the TSS descriptors for the kernel and task_1,
'ebx' point to the first 'TSS descriptor'(ring 0), and 'gs' to the lineal descriptor:
; Kernel descriptor
mov eax, DWORD dir_TSS_ini ; First TSS
mov [gs:0 + ebx], WORD 0x67 ; Limit 0-15
mov [gs:2 + ebx], ax ; Base 0-15
shr eax, 16
mov [gs:4 + ebx], al ; Base 16-23
mov [gs:5 + ebx], BYTE 0x89 ; P=1, DPL=0, TSS32
mov [gs:6 + ebx], BYTE 0x00 ; G=0
mov [gs:7 + ebx], ah ; Base 24-31
add ebx, 8 ; Next descriptor
; task_1 descriptor
mov eax, DWORD dir_TSS_ini + 104 ; Second TSS
mov [gs:0 + ebx], WORD 0x67 ; Limit 0-15
mov [gs:2 + ebx], ax ; Base 0-15
shr eax, 16
mov [gs:4 + ebx], al ; Base 16-23
mov [gs:5 + ebx], BYTE 0x89 ; P=1, DPL=0, TSS32
mov [gs:6 + ebx], BYTE 0x00 ; G=0
mov [gs:7 + ebx], ah ; Base 24-31
The OS switchs to protected mode... Then fill the kernel's TSS with the LTR instruction:
mov ax, desc_TSS_ini ; first TSS descriptor
ltr ax
Then the OS fill the task_1's TSS with this code. 'gs' point to the lineal descriptor:
mov ebx, DWORD dir_TSS_ini ; first TSS
lea eax, [tarea_usuario] ; Entry point
; gs:ebx+104 points to the task_1' TSS. It is right?
mov [gs:ebx + 104 + 0x00], DWORD 0
mov [gs:ebx + 104 + 0x04], DWORD 0
mov [gs:ebx + 104 + 0x08], DWORD 0
mov [gs:ebx + 104 + 0x0C], DWORD 0
mov [gs:ebx + 104 + 0x10], DWORD 0
mov [gs:ebx + 104 + 0x14], DWORD 0
mov [gs:ebx + 104 + 0x18], DWORD 0
mov [gs:ebx + 104 + 0x1C], DWORD 0
mov [gs:ebx + 104 + 0x20], eax ; 'eip'
mov [gs:ebx + 104 + 0x24], DWORD 0
mov [gs:ebx + 104 + 0x28], DWORD 0
mov [gs:ebx + 104 + 0x2C], DWORD 0
mov [gs:ebx + 104 + 0x30], DWORD 0
mov [gs:ebx + 104 + 0x34], DWORD 0
mov [gs:ebx + 104 + 0x38], esp ; 'esp' (?)
mov [gs:ebx + 104 + 0x3C], DWORD 0
mov [gs:ebx + 104 + 0x40], DWORD 0
mov [gs:ebx + 104 + 0x44], DWORD 0
mov [gs:ebx + 104 + 0x48], WORD desc_kernel_d ; 'es'
mov [gs:ebx + 104 + 0x4C], WORD desc_kernel_c ; 'cs'
mov [gs:ebx + 104 + 0x50], WORD desc_kernel_d ; 'ss'
mov [gs:ebx + 104 + 0x54], WORD desc_kernel_d ; 'ds'
mov [gs:ebx + 104 + 0x58], WORD desc_kernel_d ; 'fs'
mov [gs:ebx + 104 + 0x5C], WORD desc_kernel_d ; 'gs'
mov [gs:ebx + 104 + 0x60], DWORD 0
mov [gs:ebx + 104 + 0x64], DWORD 0
Finally, the OS switch to task_1 with the code:
call desc_TSS_ini+8:0
This seems to run well, but with a second call the computer reset.
Somebody know where my error is...
Thank you very much!
pepito
By now, I like to switch from the kernel to another task, both at ring 0.
My kernel is loaded at 0x50000 but the GDT and TSS(s) are outside the kernel. The GDT is at 0x3800 and the TSS(s) area is at 0x35800. I must use code to put data at these structures!
The OS define:
; Linear adresses
dir_GDT equ 0x3800 ; GDT
dir_LDT_ini equ 0x34800 ; LDT(s) for the tasks
dir_TSS_ini equ 0x35800 ; TSS(s) for the tasks
dir_KERNEL equ 0x50000 ; Kernel linear address
...
; Descriptors
desc_lineal equ 8 ; Lineal descriptor
desc_kernel_c equ 16 ; code's kernel descriptor
desc_kernel_d equ 24 ; data's kernel descriptor
desc_LDT_ini equ 32 ; 128 LDT descriptors (not used)
desc_TSS_ini equ 1056 ; 128 TSS descriptors
...
I use this code to load the TSS descriptors for the kernel and task_1,
'ebx' point to the first 'TSS descriptor'(ring 0), and 'gs' to the lineal descriptor:
; Kernel descriptor
mov eax, DWORD dir_TSS_ini ; First TSS
mov [gs:0 + ebx], WORD 0x67 ; Limit 0-15
mov [gs:2 + ebx], ax ; Base 0-15
shr eax, 16
mov [gs:4 + ebx], al ; Base 16-23
mov [gs:5 + ebx], BYTE 0x89 ; P=1, DPL=0, TSS32
mov [gs:6 + ebx], BYTE 0x00 ; G=0
mov [gs:7 + ebx], ah ; Base 24-31
add ebx, 8 ; Next descriptor
; task_1 descriptor
mov eax, DWORD dir_TSS_ini + 104 ; Second TSS
mov [gs:0 + ebx], WORD 0x67 ; Limit 0-15
mov [gs:2 + ebx], ax ; Base 0-15
shr eax, 16
mov [gs:4 + ebx], al ; Base 16-23
mov [gs:5 + ebx], BYTE 0x89 ; P=1, DPL=0, TSS32
mov [gs:6 + ebx], BYTE 0x00 ; G=0
mov [gs:7 + ebx], ah ; Base 24-31
The OS switchs to protected mode... Then fill the kernel's TSS with the LTR instruction:
mov ax, desc_TSS_ini ; first TSS descriptor
ltr ax
Then the OS fill the task_1's TSS with this code. 'gs' point to the lineal descriptor:
mov ebx, DWORD dir_TSS_ini ; first TSS
lea eax, [tarea_usuario] ; Entry point
; gs:ebx+104 points to the task_1' TSS. It is right?
mov [gs:ebx + 104 + 0x00], DWORD 0
mov [gs:ebx + 104 + 0x04], DWORD 0
mov [gs:ebx + 104 + 0x08], DWORD 0
mov [gs:ebx + 104 + 0x0C], DWORD 0
mov [gs:ebx + 104 + 0x10], DWORD 0
mov [gs:ebx + 104 + 0x14], DWORD 0
mov [gs:ebx + 104 + 0x18], DWORD 0
mov [gs:ebx + 104 + 0x1C], DWORD 0
mov [gs:ebx + 104 + 0x20], eax ; 'eip'
mov [gs:ebx + 104 + 0x24], DWORD 0
mov [gs:ebx + 104 + 0x28], DWORD 0
mov [gs:ebx + 104 + 0x2C], DWORD 0
mov [gs:ebx + 104 + 0x30], DWORD 0
mov [gs:ebx + 104 + 0x34], DWORD 0
mov [gs:ebx + 104 + 0x38], esp ; 'esp' (?)
mov [gs:ebx + 104 + 0x3C], DWORD 0
mov [gs:ebx + 104 + 0x40], DWORD 0
mov [gs:ebx + 104 + 0x44], DWORD 0
mov [gs:ebx + 104 + 0x48], WORD desc_kernel_d ; 'es'
mov [gs:ebx + 104 + 0x4C], WORD desc_kernel_c ; 'cs'
mov [gs:ebx + 104 + 0x50], WORD desc_kernel_d ; 'ss'
mov [gs:ebx + 104 + 0x54], WORD desc_kernel_d ; 'ds'
mov [gs:ebx + 104 + 0x58], WORD desc_kernel_d ; 'fs'
mov [gs:ebx + 104 + 0x5C], WORD desc_kernel_d ; 'gs'
mov [gs:ebx + 104 + 0x60], DWORD 0
mov [gs:ebx + 104 + 0x64], DWORD 0
Finally, the OS switch to task_1 with the code:
call desc_TSS_ini+8:0
This seems to run well, but with a second call the computer reset.
Somebody know where my error is...
Thank you very much!
pepito