Advice needed immediately

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.
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

Hi people, can anybody explain the problem with following code?

   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   ;Load Task register.
   mov ax, SYSTEM_TSS
   ltr ax

   ; Initialize thread tss entries.
   lea eax, [thread1_code]      ; thread1 entry point
   mov dword [thread1_eip],eax


   mov dword [thread1_esp],esp

   lea eax, [thread2_code]      ; thread2 entry point
   mov dword [thread2_eip],eax


   mov dword [thread2_esp],esp

;call thread task
jmp THREAD1_TSS:0

   jmp $ ;HALT!!!


   thread1_code:
   mov esi, thread1_msg
   call PRINTMSG32
   ;jmp $
   jmp SYSTEM_TSS


   thread2_code:
   mov esi, thread2_msg
   call PRINTMSG32
   jmp $

This code should write thread1_msg onto screen and then swtich back to system_tss. It does write message onto screen but does not successfully swtich back to system_tss. In bochs it gives an error like:

...
00000506315e[HD ] device set to 1 which does not exist
00000713779p[CPU ] >>PANIC<< prefetch: running in bogus memory
00000713779i[SYS ] Last time is 1044879375
00000713779i[CPU ] protected mode
00000713779i[CPU ] CS.d_b = 32 bit
00000713779i[CPU ] SS.d_b = 32 bit
00000713779i[CPU ] | EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
00000713779i[CPU ] | ESP=0000fffb EBP=00000000 ESI=000039c5 EDI=00000000
00000713779i[CPU ] | IOPL=0 NV UP EI NG NZ NA PE NC
00000713779i[CPU ] | SEG selector base limit G D
00000713779i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00000713779i[CPU ] | DS:0010( 0002| 0| 0) 00001000 000fffff 1 1
00000713779i[CPU ] | ES:0010( 0002| 0| 0) 00001000 000fffff 1 1
00000713779i[CPU ] | FS:0010( 0002| 0| 0) 00001000 000fffff 1 1
00000713779i[CPU ] | GS:0010( 0002| 0| 0) 00001000 000fffff 1 1
00000713779i[CPU ] | SS:0010( 0002| 0| 0) 00001000 000fffff 1 1
00000713779i[CPU ] | CS:0018( 0003| 0| 0) 00001000 000fffff 1 1
00000713779i[CPU ] | EIP=3a23a23f (3a23a23f)
00000713779i[CPU ] | CR0=0x60000019 CR1=0x00000000 CR2=0x00000000
00000713779i[CPU ] | CR3=0x00000000 CR4=0x00000000
00000713779i[ ] restoring default signal behavior
00000713779i[CTRL ] quit_sim called with exit code 1

Any advice is welcome. Thanx...
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

I forgot to send tss's and desciptors. Code is running in pmode and no paging.
system_tss:
      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

thread1_tss:
      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
thread1_cr3:
      dd 0         ; CR3
thread1_eip:
      dd 0, 0x200      ; EIP, EFLAGS (EFLAGS=0x200 for ints)
      dd 0, 0, 0, 0      ; EAX, ECX, EDX, EBX
thread1_esp:
      dd 0xffff, 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


thread2_tss:
      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
thread2_cr3:
      dd 0         ; CR3
thread2_eip:
      dd 0, 0x200      ; EIP, EFLAGS (EFLAGS=0x200 for ints)
      dd 0, 0, 0, 0      ; EAX, ECX, EDX, EBX
thread2_esp:
      dd 0xffff, 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

and descriptors:
         SYSTEM_TSS   equ   $-gdt
system_tss_desc:   dw 103
         dw 0         ; set to System TSS.
         db 0
         db 0x89         ; present, ring 0, 32-bit available TSS
         db 0
         db 0

         THREAD1_TSS   equ   $-gdt
thread1_tss_desc:   dw 103
         dw 0
         db 0
         db 0x89         ; present, ring 0, 32-bit available TSS
         db 0
         db 0

         THREAD2_TSS   equ   $-gdt
thread2_tss_desc:   dw 103
         dw 0         
         db 0
         db 0x89         ; present, ring 0, 32-bit available TSS
         db 0
         db 0
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

Since there are no responses to my very long questions, today I realized that in fact I can switch back to system_tss by call-iret way. However, I still dont know why JMPing from switched task gives an error. I also realized that in fact I never needed to get control back to calling task like the way I did in that code. I mean since all swtiching is done by scheduler, application does not itself even know about if it will be preemted or not. (right?) Anyway... I need to go on... Any ideas are still very very appreciated. Thanx...
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

Hey cmon gurus how come could you not see my very very stupid mistake overthere? I am the very most stupid of all, I cannot believe it look at here:

Code: Select all

thread1_code:
   mov esi, thread1_msg
   call PRINTMSG32
   ;jmp $
   jmp SYSTEM_TSS 


   thread2_code:
   mov esi, thread2_msg
   call PRINTMSG32
Is there a possibility that jmp SYSTEM_TSS will work? It should be jmp SYSTEM_TSS:0. Anyway, I am sorry for taking up that much space, I still cannot believe that I made such a mistake...
K.J.

Re:Advice needed immediately

Post by K.J. »

I am the very most stupid of all, I cannot believe it look at here:
Heh, don't feal too bad, I can't count the number of times I've done stuff like that and thought there was a bug a my code.
Is there a possibility that jmp SYSTEM_TSS will work?
It should.

You might want to look into 'software taskswitching' which is what Curufir was describing. It's much faster than TSS taskswitching, and IMHO, easier. There's some "framework" code for it here:
http://osdev.neopages.net/tutorials/soft_ts.php

K.J.
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

Well, when I changed this expression into jmp SYSTEM_TSS:0 code started working. When I use jmp SYSTEM_TSS it jumps to a very strange place and causes page fault, and then eventually triple faults. BTW I have no reason for using hardware task switching, I think it is more suitable for standards, I mean hardware stuff. Anyway... :P
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Advice needed immediately

Post by Pype.Clicker »

for the assembler, jmp TSS_SELECTOR is just jmp (near) constant, so you'll jump to the 0x20 th byte, or 0x38, or whatever your selector is ...

Of course it's very unlikely to work.
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

Pype Clicker I hope you read this. I am quite confused on your explanation on scheduler calling time in "Task switch at interrupt" thread. I thought switching task was the only way to handle irq0 so that a task that will be preempted does not need to know about the time it will be switched. OK, to be more simpler: When we use a trap gate for handling irq0 then when a timer interrupt occurs the handler is called in context of current task. Which also means that we have to call scheduler in thje context of current task. However if scheduler decides that this task should be preempted, its state will be saved in the middle of handling a timer interrupt. Right? (Or is it?) So later when we try to switch back to this task then will it go on appropriately? But if we do a task switch on interrupt then at irq0 current task will be saved exactly where it will be running later when it again gets control. Any corrections? Thanx...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Advice needed immediately

Post by Pype.Clicker »

So basically, you would like to have IRQ0 calling task X (the scheduler) which will decide to switch to task B instead of task A ?

This implies too much switches for my tastes, but if you really want to do so, probably the best way is to change the current TSS's "back link" from TSS_A to TSS_B before your task X performs the IRET ...

trying to do a JMP TSS_B:0 in the IRQ0 handler (called by task gate to X) will change the EIP address and the register values of the TSS_X, while the IRET leave that state unmodified (so that the next interrupt also finds a clean state)
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

OK, this might be a very much specific quesition but I could not find it in the books. How is a new task's eflag initialized?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Advice needed immediately

Post by Pype.Clicker »

You should at least always have the "sticky bit" set (i think it should be BIT1 or something alike) : that bit is constantly set by the hardware, so you should set it as well, imho

For the other bits ... it just depends on what you wish. You can let all the "ALU" flags cleared, but i suppose your question is more about NT, IOPL and IF flags, right ?

I think the best policy is to set them accordingly to what would be their normal state if the program was simply called from another function rather than being started as a new task.

For instance, if your task starts somewhere in user code, just leave the IF bit set, while if you're starting from then end of an interrupt handler, you'll better clear it.
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

Hi, firstly thanx... ;D Would doing task switch in the way you(Pype Clicker) told in previous second thread cause any problems?(Other than doing many task switches on every irq0) I know that this is a very general question but I just wanted to take your ideas. I cannot think of any other way of calling scheduler without disturbing currently executing task. I am a little confused on how to implement it, I think a lot of people are doing software task switching which is much simpler, faster and easier. But I want to leave it for some time. Anyway, thanx in advance for any advice.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Advice needed immediately

Post by Pype.Clicker »

what i don't understand is why you want so hard to avoid IRQ0 to interrupt the user process ... That's what interrupts are designed for : interrupting a user process and then restore its state transparently to the underlying application ... So if you do the switch within a trap-based (handled within the current task) interrupt handler, it just appears to the application as if the IRQ it didn't see just took more time. period.
Peter_Vigren

Re:Advice needed immediately

Post by Peter_Vigren »

beyond infinity wrote: If you use hardware taskswitching, you might have multiple tss-selectors or just one (this is tricky - see john fines pages for how to do that), which you jump to at every task switch.
John Fines pages? May I ask where I find them?
Ozguxxx

Re:Advice needed immediately

Post by Ozguxxx »

John Fine's page:
http://my.execpc.com/CE/AC/geezer/johnfine/index.htm

I want to avoid irq0 interrupt user process becuase firstly I do not know why I want it that way ??? I mean, I just think that interrupts should be handled bylow level software only and by doing this os can give user process more logical services by making use of interrupts.(like irq0) Also I think ,as I said before, running scheduler in its context in an isolated environment ensures us that it does not interefere with other programs. Do you think that is logical? May I ask the way you implement this very low level task scheduling? Thanx...
Post Reply