Is there any easy step-by-step tutorial of TSS? (v2)

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.
InsightSoft
Member
Member
Posts: 76
Joined: Mon Aug 18, 2008 6:17 am

Is there any easy step-by-step tutorial of TSS? (v2)

Post by InsightSoft »

Of course I'm reading all information I can get...
Anyway, I think that this kind of information can only help...
That's why a leave here this example:

Code: Select all

								; pm8.asm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	pm8.asm - protected-mode demo code
;	Christopher Giese <geezer[AT]execpc.com>
;
;	Release date 9/28/98. Distribute freely. ABSOLUTELY NO WARRANTY.
;	Assemble with NASM:	nasm -o pm8.com pm8.asm
;
; Demonstrates:
;	- Two ring 0 tasks preemptively multitasked via timer interrupt.
; Fixes/changes:
;	- IDT now contains true interrupt gates (type 0x8E) instead
;	  of trap gates (type 0x8F)
;	- Gave task1 its own stack and enlarged stacks to prevent task1
;	  dying (XXX - one task still dies when run on 486SX system).
;	- Byte 6 of descriptors (flags/limit 19:16) changed from
;	  0xFC to 0xCF
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[SECTION .text]
[ORG 0x100]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	16-bit real mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[BITS 16]
; set base of code/data descriptors to CS<<4/DS<<4 (CS=DS)
	xor ebx,ebx
	mov bx,cs		; EBX=segment
	shl ebx,4		;	<< 4
	lea eax,[ebx]		; EAX=linear address of segment base
	mov [gdt2 + 2],ax
	mov [gdt3 + 2],ax
	mov [gdt4 + 2],ax
	mov [gdt5 + 2],ax
	shr eax,16
	mov [gdt2 + 4],al
	mov [gdt3 + 4],al
	mov [gdt4 + 4],al
	mov [gdt5 + 4],al
	mov [gdt2 + 7],ah
	mov [gdt3 + 7],ah
	mov [gdt4 + 7],ah
	mov [gdt5 + 7],ah
; fix up TSS entries, too
	lea eax,[ebx + stss]	; EAX=linear address of stss
	mov [gdt6 + 2],ax
	shr eax,16
	mov [gdt6 + 4],al
	mov [gdt6 + 7],ah
	lea eax,[ebx + utss1]	; EAX=linear address of utss1
	mov [gdt7 + 2],ax
	shr eax,16
	mov [gdt7 + 4],al
	mov [gdt7 + 7],ah
	lea eax,[ebx + utss2]	; EAX=linear address of utss2
	mov [gdt8 + 2],ax
	shr eax,16
	mov [gdt8 + 4],al
	mov [gdt8 + 7],ah
; point gdtr to the gdt, idtr to the idt
	lea eax,[ebx + gdt]	; EAX=linear address of gdt
	mov [gdtr + 2],eax
	lea eax,[ebx + idt]	; EAX=linear address of idt
	mov [idtr + 2],eax
; disable interrupts
	cli
; load GDT and IDT for full protected mode
	lgdt [gdtr]
	lidt [idtr]
; save real-mode CS in BP
	mov bp,cs
; set PE [protected mode enable] bit and go
	mov eax,cr0
	or al,1
	mov cr0,eax
	jmp SYS_CODE_SEL:do_pm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	32-bit protected mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[BITS 32]
do_pm:	mov ax,SYS_DATA_SEL
	mov ds,ax
	mov ss,ax
	nop
	mov es,ax
	mov fs,ax
	mov gs,ax
; load task register. All registers from this task will be dumped
; into SYS_TSS after executing the CALL USERx_TSS:0
	mov ax,SYS_TSS
	ltr ax
; print starting msg
	lea esi,[st_msg]
	call wrstr
; initialize user TSSes
	lea eax,[user1]
	mov [utss1_eip],eax
	lea eax,[esp - 512]
	mov [utss1_esp],esp	; task1 stack 512 bytes below system
	lea eax,[user2]
	mov [utss2_eip],eax
	lea eax,[esp - 1024]	; task2 stack 1K bytes below system
	mov [utss2_esp],esp
; shut off interrupts at the 8259 PIC, except for timer interrupt.
; The switch to user task will enable interrupts at the CPU.
	mov al,0xFE
	out 0x21,al
; 18 times...
mov ecx,18
;mov ecx,65537
	mov al,0x20
sched:
	jmp USER1_TSS:0
; timer interrupt returns us here. Reset 8259 PIC:
	out 0x20,al
; clear busy bit of user1 task
	mov [gdt7 + 5],byte 0x89

	jmp USER2_TSS:0
; timer interrupt returns us here. Reset 8259 PIC:
	out 0x20,al
; clear busy bit of user1 task
	mov [gdt8 + 5],byte 0x89

	loop sched
; print ending msg
	lea esi,[end_msg]
	call wrstr
; switch to 16-bit protected mode on your way to real mode
	jmp REAL_CODE_SEL:do_16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	user tasks
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
user1:	lea esi,[hi1_msg]
	call wrstr
	mov ecx,0xFFFFF
	loop $
	jmp user1		; infinite loop (until timer interrupt)

user2:	lea esi,[hi2_msg]
	call wrstr
	mov ecx,0xFFFFF
	loop $
	jmp user2		; infinite loop (until timer interrupt)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	character-output video routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
wrch:	pushf			; save IF bit
	push gs
	push ecx
	push ebx
	push eax
		cli		; disable interrupts
		mov ax,LINEAR_SEL
		mov gs,ax
; (Y * 80 + X) * 2 --> EAX
		movzx eax,byte [CsrY]
		mov cl,80
		mul cl
		add al,[CsrX]
		adc ah,0
		shl eax,1
; EAX + 0xB8000 --> EBX; store char
		lea ebx,[eax + 0xB8000]
		pop eax
		push eax
		mov [gs:ebx],al
; advance cursor
		mov cx,[CsrX]
		inc cl
		cmp cl,80	; cursor off right side of screen?
		jb wrch2
		xor cl,cl	; yes, wrap to left side...
		inc ch		; ...and down one line
		cmp ch,25	; cursor off bottom of screen?
		jb wrch2
		xor ch,ch	; yes, wrap to top left corner (no scroll)
wrch2:		mov [CsrX],cx
	pop eax
	pop ebx
	pop ecx
	pop gs
	popf			; re-enable interrupts (if they were enabled)
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	string-output video routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
wrstr:	push esi
	push eax
		cld
		jmp wrstr2
wrstr1:		call wrch
wrstr2:		lodsb
		or al,al
		jne wrstr1
	pop eax
	pop esi
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	default handler for interrupts/exceptions
;	prints " Unhandled interrupt!"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
unhand:	cli
	mov ax,SYS_DATA_SEL
	mov ss,ax
	mov ds,ax
	mov es,ax
	mov fs,ax
	lea esi,[unhand_msg]
	call wrstr
	jmp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	16-bit protected mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[BITS 16]
; switch to 16-bit stack and data
do_16:	mov ax,REAL_DATA_SEL
	mov ds,ax
	mov ss,ax
	nop
; push real-mode CS:IP
	lea bx,[do_rm]
	push bp
	push bx
; clear PE [protected mode enable] bit and return to real mode
		mov eax,cr0
		and al,0xFE
		mov cr0,eax
		retf		; jumps to do_rm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	16-bit real mode again
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; restore real-mode segment register values
do_rm:	mov ax,cs
	mov ds,ax
	mov ss,ax
	nop
	mov es,ax
	mov fs,ax
	mov gs,ax
; point to real-mode IDTR
	lidt [ridtr]
; re-enable interrupts (at CPU and at 8259).
; XXX - read old irq mask from port 0x21, save it, restore it here
	sti
	mov al,0xB8
	out 0x21,al
; exit to DOS with errorlevel 0
	mov ax,0x4C00
	int 0x21
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CsrX:	db 0
CsrY:	db 0

st_msg:	db "Scheduler starting. ", 0

hi1_msg:db "Hello from task 1. ", 0

hi2_msg:db "Greetings from task 2. ", 0

end_msg:db " Scheduler done.", 0

unhand_msg:
	db " Unhandled interrupt!", 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	16-bit limit/32-bit linear base address of GDT and IDT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
gdtr:	dw gdt_end - gdt - 1	; GDT limit
	dd gdt			; linear, physical address of GDT

idtr:	dw idt_end - idt - 1	; IDT limit
	dd idt			; linear, physical address of IDT

; an IDTR 'appropriate' for real mode
ridtr:	dw 0xFFFF		; limit=0xFFFF
	dd 0			; base=0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	global descriptor table (GDT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; null descriptor
gdt:	dw 0			; limit 15:0
	dw 0			; base 15:0
	db 0			; base 23:16
	db 0			; type
	db 0			; limit 19:16, flags
	db 0			; base 31:24
; linear data segment descriptor
LINEAR_SEL	equ	$-gdt
	dw 0xFFFF		; limit 0xFFFFF
	dw 0			; base for this one is always 0
	db 0
	db 0x92			; present, ring 0, data, expand-up, writable
	db 0xCF			; page-granular, 32-bit
	db 0
; code segment descriptor
SYS_CODE_SEL	equ	$-gdt
gdt2:	dw 0xFFFF
	dw 0			; (base gets set above)
	db 0
	db 0x9A			; present, ring 0, code, non-conforming, readable
	db 0xCF
	db 0
; data segment descriptor
SYS_DATA_SEL	equ	$-gdt
gdt3:	dw 0xFFFF
	dw 0			; (base gets set above)
	db 0
	db 0x92			; present, ring 0, data, expand-up, writable
	db 0xCF
	db 0
; code segment descriptor that is 'appropriate' for real mode
; (16-bit, limit=0xFFFF)
REAL_CODE_SEL	equ	$-gdt
gdt4:	dw 0xFFFF
	dw 0			; (base gets set above)
	db 0
	db 0x9A			; present, ring 0, code, non-conforming, readable
	db 0			; byte-granular, 16-bit
	db 0
; data segment descriptor that is 'appropriate' for real mode
; (16-bit, limit=0xFFFF)
REAL_DATA_SEL	equ	$-gdt
gdt5:	dw 0xFFFF
	dw 0			; (base gets set above)
	db 0
	db 0x92			; present, ring 0, code, non-conforming, readable
	db 0			; byte-granular, 16-bit
	db 0
; system TSS
SYS_TSS		equ	$-gdt
gdt6:	dw 103
	dw 0			; set to stss
	db 0
	db 0x89			; present, ring 0, 32-bit available TSS
	db 0
	db 0
; user TSS 1
USER1_TSS	equ	$-gdt
gdt7:	dw 103
	dw 0			; set to utss1
	db 0
	db 0x89			; present, ring 0, 32-bit available TSS
	db 0
	db 0
; user TSS 2
USER2_TSS	equ	$-gdt
gdt8:	dw 103
	dw 0			; set to utss2
	db 0
	db 0x89			; present, ring 0, 32-bit available TSS
	db 0
	db 0
gdt_end:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	interrupt descriptor table (IDT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 32 reserved interrupts:
idt:	dw unhand		; entry point 15:0
	dw SYS_CODE_SEL		; selector
	db 0			; word count
	db 0x8E			; type (32-bit Ring 0 interrupt gate)
	dw 0			; entry point 31:16 (XXX - unhand >> 16)

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

;	dw unhand
;	dw SYS_CODE_SEL
;	db 0
;	db 0x8E
;	dw 0
; INT 8 is IRQ0 (timer interrupt). The 8259's can (and should) be
; reprogrammed to assign the IRQs to higher INTs, since the first
; 32 INTs are Intel-reserved. Didn't IBM or Microsoft RTFM?
	dw 0
	dw SYS_TSS
	db 0
	db 0x85			; Ring 0 task gate
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0

	dw unhand
	dw SYS_CODE_SEL
	db 0
	db 0x8E
	dw 0
idt_end:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	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 0, 0			; ES, reserved
	dw 0, 0			; CS, reserved
	dw 0, 0			; SS, reserved
	dw 0, 0			; DS, reserved
	dw 0, 0			; FS, reserved
	dw 0, 0			; GS, reserved
	dw 0, 0			; LDT, reserved
	dw 0, 0			; debug, IO perm. bitmap

utss1:	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
utss1_eip:
	dd 0, 0x200		; EIP, EFLAGS (EFLAGS=0x200 for ints)
	dd 0, 0, 0, 0		; EAX, ECX, EDX, EBX
utss1_esp:
	dd 0, 0, 0, 0		; ESP, EBP, ESI, EDI
	dw SYS_DATA_SEL, 0	; ES, reserved
	dw SYS_CODE_SEL, 0	; CS, reserved
	dw SYS_DATA_SEL, 0	; SS, reserved
	dw SYS_DATA_SEL, 0	; DS, reserved
	dw SYS_DATA_SEL, 0	; FS, reserved
	dw SYS_DATA_SEL, 0	; GS, reserved
	dw 0, 0			; LDT, reserved
	dw 0, 0			; debug, IO perm. bitmap

utss2:	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
utss2_eip:
	dd 0, 0x200		; EIP, EFLAGS (EFLAGS=0x200 for ints)
	dd 0, 0, 0, 0		; EAX, ECX, EDX, EBX
utss2_esp:
	dd 0, 0, 0, 0		; ESP, EBP, ESI, EDI
	dw SYS_DATA_SEL, 0	; ES, reserved
	dw SYS_CODE_SEL, 0	; CS, reserved
	dw SYS_DATA_SEL, 0	; SS, reserved
	dw SYS_DATA_SEL, 0	; DS, reserved
	dw SYS_DATA_SEL, 0	; FS, reserved
	dw SYS_DATA_SEL, 0	; GS, reserved
	dw 0, 0			; LDT, reserved
	dw 0, 0			; debug, IO perm. bitmap
end:
User avatar
JackScott
Member
Member
Posts: 1033
Joined: Thu Dec 21, 2006 3:03 am
Location: Hobart, Australia
Mastodon: https://aus.social/@jackscottau
Matrix: @JackScottAU:matrix.org
GitHub: https://github.com/JackScottAU
Contact:

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by JackScott »

IMHO, pasting random (large) code snippets with little to no background or explanation doesn't help anybody. The fact that it is somebody else's code doesn't make the fact any better.

I'd like to not lock this topic, if it can be helped. That doesn't solve much. So, to start on the road to intellectual recovery, I shall ask, what is that you want to know specifically about TSS's?

Do you want to know what they are?
Do you want to know what they can be used for?
Do you want to know how to construct one?
Do you want to know how to set one up and use one?

As you can see, each of these questions leads on from the other, step by step. Asking 'about TSSs' asks us to answer all of these questions, since we have no idea what you really want to know. If you wanted to know the answer to the third question, we would be completely wasting our time by answering the first one. It's also likely that you could have figured out the later steps yourself. Being more specific helps everybody.

As for places to look, the wiki is always good. And the Intel Manuals are gold. Example kernels, while extremely useful, are everywhere, and we can find them ourselves if need be.
InsightSoft
Member
Member
Posts: 76
Joined: Mon Aug 18, 2008 6:17 am

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by InsightSoft »

JackScott wrote:IMHO, pasting random (large) code snippets with little to no background or explanation doesn't help anybody. The fact that it is somebody else's code doesn't make the fact any better.

I'd like to not lock this topic, if it can be helped. That doesn't solve much. So, to start on the road to intellectual recovery, I shall ask, what is that you want to know specifically about TSS's?

Do you want to know what they are?
Do you want to know what they can be used for?
Do you want to know how to construct one?
Do you want to know how to set one up and use one?

As you can see, each of these questions leads on from the other, step by step. Asking 'about TSSs' asks us to answer all of these questions, since we have no idea what you really want to know. If you wanted to know the answer to the third question, we would be completely wasting our time by answering the first one. It's also likely that you could have figured out the later steps yourself. Being more specific helps everybody.

As for places to look, the wiki is always good. And the Intel Manuals are gold. Example kernels, while extremely useful, are everywhere, and we can find them ourselves if need be.

Ok. you are right...
But it is full program that explain, I think, a TSS usage... but, again, you are right
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by JamesM »

InsightSoft wrote:
JackScott wrote:IMHO, pasting random (large) code snippets with little to no background or explanation doesn't help anybody. The fact that it is somebody else's code doesn't make the fact any better.

I'd like to not lock this topic, if it can be helped. That doesn't solve much. So, to start on the road to intellectual recovery, I shall ask, what is that you want to know specifically about TSS's?

Do you want to know what they are?
Do you want to know what they can be used for?
Do you want to know how to construct one?
Do you want to know how to set one up and use one?

As you can see, each of these questions leads on from the other, step by step. Asking 'about TSSs' asks us to answer all of these questions, since we have no idea what you really want to know. If you wanted to know the answer to the third question, we would be completely wasting our time by answering the first one. It's also likely that you could have figured out the later steps yourself. Being more specific helps everybody.

As for places to look, the wiki is always good. And the Intel Manuals are gold. Example kernels, while extremely useful, are everywhere, and we can find them ourselves if need be.

Ok. you are right...
But it is full program that explain, I think, a TSS usage... but, again, you are right
It doesn't explain TSS usage, it is an entire operating system and is burdened with the 16-bit protected mode / 32-bit protected mode jump, plus setting up of an IDT etc.

A small, targeted code snippet, heavily commented, will always have more value than a "this is how you do it, just copy this" hit-and-run post of 1K of sparsely commented assembler.
gedd
Member
Member
Posts: 104
Joined: Thu Apr 10, 2008 1:47 am

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by gedd »

Did you try the os developper bible ?

Intel® 64 and IA-32 Architectures
Software Developer’s Manual
Volume 3A:
System Programming Guide, Part 1
[ Grub 2 | Visual Studio 2013 | PE File ]
The OsDev E.T.
Don't send OsDev MIB !
User avatar
xyjamepa
Member
Member
Posts: 397
Joined: Fri Sep 29, 2006 8:59 am

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by xyjamepa »

Hi,

I'm not sure if this is what you need,but anyway give it a try.

Godd luck.
The man who follows the crowd will usually get no further than the crowd.
The man who walks alone is likely to find himself in places
no one has ever been before.
InsightSoft
Member
Member
Posts: 76
Joined: Mon Aug 18, 2008 6:17 am

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by InsightSoft »

gedd wrote:Did you try the os developper bible ?

Intel® 64 and IA-32 Architectures
Software Developer’s Manual
Volume 3A:
System Programming Guide, Part 1


Yap... all of them...
Including Pentium Pro Family Developer's manual Vol3 Operating System Writer's Guide (very nice)
InsightSoft
Member
Member
Posts: 76
Joined: Mon Aug 18, 2008 6:17 am

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by InsightSoft »

HELP

Im receiving this error:

Code: Select all

call_protected(): gate.type(11) unsupported
Context:
1. There is a TSS structure
2. There is a GDT entry related to that TSS xt (its base address;

Code: Select all

gdt.SetEntry( 3, (tpUInteger32Bits)&sysTSS,	 sizeof(sysTSS)-1,		0x89,		0xC0);
3. The TSS is filled with values (address of function as EIP, etc)

Code: Select all

	sysTSS.EIP = (tpUInteger32Bits)&task_KeepRolling;
	__asm
	{
		//control and flags
		push eax
 		mov eax, cr3
		mov sysTSS.CR3, eax
		pushfd
	 	pop eax
		mov sysTSS.EFlags, eax
		pop eax
		//general
		mov sysTSS.EAX, eax
		mov sysTSS.EBX, ebx
		mov sysTSS.ECX, ecx
		mov sysTSS.EDX, edx
		mov sysTSS.ESP, esp
		mov sysTSS.EBP, ebp
		//indexes
		mov sysTSS.ESI, esi
		mov sysTSS.EDI, edi
		//segments
		mov sysTSS.ES, es
		mov sysTSS.CS, cs
		mov sysTSS.SS, ss
		mov sysTSS.DS, ds
		mov sysTSS.FS, fs
		mov sysTSS.GS, gs
	}
4. LTR AX (ax=GDT entry)
5. The the call


Any clue?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by Combuster »

your gdt is broken, containing an invalid type value.

Also, they way geezer's tutorials handle multitasking is generally considered a bad idea (using slow hardware task switching). Why are you even using a far call?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
InsightSoft
Member
Member
Posts: 76
Joined: Mon Aug 18, 2008 6:17 am

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by InsightSoft »

Combuster wrote:your gdt is broken, containing an invalid type value.

Also, they way geezer's tutorials handle multitasking is generally considered a bad idea (using slow hardware task switching). Why are you even using a far call?
Can you be more specific? (Please)

The value:

Code: Select all

               P    dpl       S     x    0     b    1  
0x89 = 1     0 0      0     1     0    1     1

b=1 running task
x=1 for 32 bits TSS
s=0 for a system task
dpl=00 (high level/system)
p=segment present  	
The call: Maybe is not the better idea... (a simple call or a jmp will fit better)

About geezer's tutorial: Well, your are right... But I'm considering all books, all tutorials, all small windows with incomplete codes to get a better pictures of everything. And believe or not, your comments like this one, make me better. Thanks again...

The exercise is to put running two different counting loops while the system preserve the ability to deal with interrupts...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by Combuster »

Why are you even using a far call?
The call: Maybe is not the better idea...
In other words, you are asking about something of which you don't even know what it is doing. Go back to what does work. What do you have, what do you want to do, what is the TSS doing in there, is the TSS even involved and then assert that you aren't involved in voodoo programming.

Think about it, do you think we can fix code if it already looks like runes for you? And if we can, does it help you?

Also consider if you were asking smart questions here, since I wouldn't say that you did.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
InsightSoft
Member
Member
Posts: 76
Joined: Mon Aug 18, 2008 6:17 am

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by InsightSoft »

Combuster wrote:
Why are you even using a far call?
The call: Maybe is not the better idea...
In other words, you are asking about something of which you don't even know what it is doing. Go back to what does work. What do you have, what do you want to do, what is the TSS doing in there, is the TSS even involved and then assert that you aren't involved in voodoo programming.

Think about it, do you think we can fix code if it already looks like runes for you? And if we can, does it help you?

Also consider if you were asking smart questions here, since I wouldn't say that you did.

Ok. sorry... next time will be diferent...
Anyway... this case is solved... thanks again
InsightSoft
Member
Member
Posts: 76
Joined: Mon Aug 18, 2008 6:17 am

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by InsightSoft »

oops... not yet (is not working as I expect)...

1). I have a GDT entry for the task

Code: Select all

0. reserved
1. code 4g
2. data 4g
3. for the task 0
4. for the task 1
2) definition for index 3
-at very first stages the indexes 3 and 4 are empty;
-after all initialization procedure the interrupts are allowed...;
-and take place the configuration of tss fields for task 0
-the eip is set to entry point for a endless function (with a simple count)
-cs is the pointing to index 1 (0x8)
-then this configuration is installed to the GDT (3)
-_Task00.Install(3, 0x89, 0xC0);
-the limit is the min required by intel (so i dont have any extra information to be used on the tss)
3) the call
-the I need to pass control to this task
- _Task00.Start()
-it perform the LTR (with GDT index) (for base address of tss, etc) and mark the task as busy

after that, if used, for example:

Code: Select all

push 0x18        (index->3,ti->0,cpl->00)
push tss.eip
iretd
it returns a invalid cs (0x18)... have I missed some thing?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by Combuster »

iret takes more than two (double)words off the stack
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
InsightSoft
Member
Member
Posts: 76
Joined: Mon Aug 18, 2008 6:17 am

Re: Is there any easy step-by-step tutorial of TSS? (v2)

Post by InsightSoft »

Yap... you are right... (cs, eip, eflags, etc)

But Im struggling with TSS. Im concerning more about the steps taken.

::start task1

Code: Select all

1. LTR ax (ax=index on GDT)
2. a far jmp to that gdt index (offset ignored)
3. tss -> registers
4. task is running
then/for next task ::start task2

Code: Select all

5. LTR ax (ax =new index on GDT)
6. a far jmp to that gdt index (offset ignored)
7. currently task is suspended (registers -> tss)
8. new tss -> registers
9. new task is running
then/for next task (for example, the first one) ::resume task1

Code: Select all

10. LTR ax (ax =new index on GDT)
11. a far jmp to that gdt index (offset ignored)
12. currently task is suspended (registers -> tss)
13. new tss -> registers
14. new task is running

Is it correct?
-my problem is
- if I use IRETD
-starts well all tasks;
-on resuming the task1 I get "LTR: doesn't point to an available TSS descriptor!"
- if I use a far call (or far jmp)
-does not starts the task
call_protected(): gate.type(11) unsupported
check_cs(0x0b34): not a valid code segment !
I'm trying to figure it out the reason
Post Reply