[Main menu]

Initial Tests

Multitasking

Get multitasking working


The Mission

This document contain all information relevant to this initial test.

Mission Goal

The mission goal is inspired by a similar example code written by John S. Fine. The mission goal is to have 26 individual tasks running at the same time. Each task will advance its individual letter on the screen. The speed that each letter moves with is different from task to task.

Runtime Enviroment

The runtime enviroment is described in the MultiBoot Standard. The binary image file is loaded by a bootmanager compatible with this standard and executed.


Elements

This is a list of elements which are required by the test. Each element has a short description of what it does.

Test Elements
Element Description
Globalt Descriptor TableContains TSS, segment and data descriptors.
Interrupt Descriptor Table
ISR DispatcherThis code respond to all interrupts and start the right ISR routine.
Multitask ISRThis is the code which actually shifts the tasks.
Task CodeThis the task code. The same code segment is used by all tasks.
TSS ATask State Segment for task A
......
TSS ZTask State Segment for task Z


Global Descriptor Table

The Global Descriptor Table (GDT) contain generally segment and system descriptors. There are three code segments in this test and one data segment. The following is a list of the descriptors in the GDT:

Global Descriptor Table
Desc # Location Type Description
0000h0000NullRequired null descriptor
0001h30000hDataGlobal Descriptor Table
0002h38000hDataInterrupt Descriptor Table
0003h40000hCodeISR Dispatcher code
0004h41000hCodeMultitask ISR code
0005h42000hCodeDump State code
0006h43000hCodeTask code
0007h50000hSystemTask State Segment for task A
............
0021h6A000hSystemTask State Segment for task Z
0022hB8000hDataScreen Location


Interrupt Descriptor Table

The only reason the Interrupt Descriptor Table (IDT) is used in this is because we need to have the Multitask ISR routine called each time the PIT send an interrupt signal. We don't have any handlers for CPU exceptions so these will just dump system state information on the screen, and if any of the other interrupts are called, except the Multitask ISR (IDT[50h]), the system state will also be dumped.

Interrupt Descriptor Table
INT Vector #Desc #DescriptionGroup
00h - 1Fh 0005h Just dump state information if called. CPU Exceptions
20h - 3Fh 0005h Just dump state information if called. OS Reserved
40h 0004h Systemtimer - Execute 'Multitask ISR' IRQ Service Routines
41h - FFh 0005h Just dump state information if called. OS Reserved


ISR Dispatcher

The ISR Dispatcher is especially usefull when multiple have been installed on the same IRQ. But for testing purposes it is used in this test. The code will call each ISR which has been installed for the interrupt number. This is what the code will do:


; Each interrupt points to a different offset for each IDT entry. At this
; this offset there will be the following three commands.
push    eax
push    
jmp	  ISR_Dispatcher



; This is the actual ISR Dispatcher.
ISR_Dispatcher:
	pusha				;Save registers
	push	ds
	push	ss			;Set up ds (note ss is always valid)
	pop	ds

	mov	al, EOI			;Tell 8259 that interrupt is done
	out	M_PIC, al

	inc dword [diag_events]		;Diagnostic
	mov	esi, [pri_heap]		;Get current task
	mov	eax, [esi+EVT_defer]	;Get its defer value
	add	[esi+EVT_time], eax	;Advance its time value
	call	sift_heap		;Update priority heap
dispatch_task:
	mov	esi, [pri_heap]		;Get next task

	mov	al, [esi+EVT_quantum]	;Program 8254 for next quantum
	out	TMR_CNT0, al
	mov	al, [esi+EVT_quantum+1]
	out	TMR_CNT0, al

	lea	eax, [esi+EVT_tss]	;Get its tss address
	shr	eax, 8			;Just the interesting bits
	mov	[tss_dsc+3], ax		;Change tss descriptor in gdt
;;;	mov byte [tss_dsc+5], (D_TSS+D_PRESENT)>>8  ;Pretend it isn't busy
	jmp	tss_sel:0		;Switch tasks
;Switching tasks saves context in the old tss.  When some other task switches
;back to us, it will continue from after the above JMP.
	pop	ds			;Restore registers
	popa
	iret				;Exit interrupt

pop     eax
pop     eax
iret


Multitask ISR

This is an ISR which is installed, to handle switches between different processes. In this test it is started when ever a IRQ is received from the PIT This specific ISR uses a round-robin algorithm to dispatch the next task.


; No code yet, sorry!


Task Code

This is the code which actually advances the letter on screen. The same code segment is used by all 26 tasks, only the x/y position and the letter is different. These values are in the AL and DX registers.

segment TaskCode use32

UpdateLetter:
        mov     ds:[ebx], 0
        add     ebx, 2
        mov     ds:[ebx], al
        cmp     ebx, 80*25*2
        jnz     .Continue
        xor     ebx, ebx

.Continue:
        hlt
        jmp     UpdateLetter

Task State Segments

All fields, except AL, DX, CS and EIP, are the same in each of the 26 task state segments (TSS).