Task Switching using ( TSS ) ?
Task Switching using ( TSS ) ?
I implement now task switching without "setjmp" , "longjmp" functions. I would like to use TSS. I have successfully define a TSS Structure and
and load the initial value for the first Task "init" in the TR Register and I have not receive any error. that mean the CPU has accepted my TSS.
now I have define a second task, but I don't know how to make far call or jmp to that task " tss_sekector:tss->eip" with inline assembly in gcc.
I save the value of "tr" in the task_struct and also the TSS.
in gcc I have done that :
__asm__(
" ljmp %0, %1 \n"
::"m"(current_task->tr), "m"(current_task->tss->eip)
)
then I receive this compiler error:
"too many memory references for `ljmp"
and when I use for "c" for the second operand I receive this :
"suffix or operands invalid for `ljmp'".
:-[
and load the initial value for the first Task "init" in the TR Register and I have not receive any error. that mean the CPU has accepted my TSS.
now I have define a second task, but I don't know how to make far call or jmp to that task " tss_sekector:tss->eip" with inline assembly in gcc.
I save the value of "tr" in the task_struct and also the TSS.
in gcc I have done that :
__asm__(
" ljmp %0, %1 \n"
::"m"(current_task->tr), "m"(current_task->tss->eip)
)
then I receive this compiler error:
"too many memory references for `ljmp"
and when I use for "c" for the second operand I receive this :
"suffix or operands invalid for `ljmp'".
:-[
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Task Switching using ( TSS ) ?
i think you should take back your opcode list and check what "ljmp" expects as arguments. afaik, you have the choice between JMP <constant segment>:<constant offset> or JMP [<memory>] where <memory> is the address of a far pointer (segment & offset where you'd like to jump to).
Re:Task Switching using ( TSS ) ?
the syntax for ljmp in AT&T syntax is :
ljmp segment, offset
example:
ljmp $0x18, $0x10080
ljmp segment, offset
example:
ljmp $0x18, $0x10080
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Task Switching using ( TSS ) ?
and these are constants. That's why your compiler complains when you give him 2 "m" instead
and he doesn't like "c" (which is %ecx, iirc) aswell.
and he doesn't like "c" (which is %ecx, iirc) aswell.
Re:Task Switching using ( TSS ) ?
then have a solution ? I have search the internet, but no solutions found.
Re:Task Switching using ( TSS ) ?
could somebody declare me, why this code work to switch to the new TSS :
__asm__(
" ljmp %0 \n"
::"m"(*(((char *)?t_task->tss->tr)-4))
);
I have found something like this in the first linux version, but there is no declaration.
change the address of current_task->tss->tr to (char *) and then minus 4, then took the value at that address. is right what that code does?
__asm__(
" ljmp %0 \n"
::"m"(*(((char *)?t_task->tss->tr)-4))
);
I have found something like this in the first linux version, but there is no declaration.
change the address of current_task->tss->tr to (char *) and then minus 4, then took the value at that address. is right what that code does?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Task Switching using ( TSS ) ?
You should try to find out what that 'TR' field is about. afaik, there is no TR field in a TSS. what i suppose is that the TSS structure has an undocumented field (which has no name) 4 bytes before the "tr" field (maybe this is "BACK" link ?), so they took the address of tss->tr, cast it as a char* (so that pointer arithmetics now have a 1-byte increment) and pick the value at that place to be a far-pointer to the next task.amirsadig wrote: __asm__(
" ljmp %0 \n"
::"m"(*(((char *)?t_task->tss->tr)-4))
);
I have found something like this in the first linux version, but there is no declaration.
is right what that code does?
then a "ljmp [tr-address]" is performed.
Re:Task Switching using ( TSS ) ?
my TSS structure has all TSS information plus the pointer to 33 byte (IO Bitmap) and the tr.
therefor the above code the point to the TOP of the TSS ( bitmap). This what I dont't understand, how the CPU then know the TSS Selector?
--------------
struct tss_struct {
unsigned short back_link,__blh;
unsigned long esp0;
unsigned short ss0,__ss0h;
unsigned long esp1;
unsigned short ss1,__ss1h;
unsigned long esp2;
unsigned short ss2,__ss2h;
unsigned long cr3;
unsigned long eip;
unsigned long eflags;
unsigned long eax,ecx,edx,ebx;
unsigned long esp;
unsigned long ebp;
unsigned long esi;
unsigned long edi;
unsigned short es, __esh;
unsigned short cs, __csh;
unsigned short ss, __ssh;
unsigned short ds, __dsh;
unsigned short fs, __fsh;
unsigned short gs, __gsh;
unsigned short ldt, __ldth;
unsigned short trace, bitmap;
unsigned long io_bitmap[IO_BITMAP_SIZE+1];
unsigned long tr; // save the TSS selector (the Kernel change it during task init..)
unsigned long cr2, trap_no, error_code;
};
therefor the above code the point to the TOP of the TSS ( bitmap). This what I dont't understand, how the CPU then know the TSS Selector?
--------------
struct tss_struct {
unsigned short back_link,__blh;
unsigned long esp0;
unsigned short ss0,__ss0h;
unsigned long esp1;
unsigned short ss1,__ss1h;
unsigned long esp2;
unsigned short ss2,__ss2h;
unsigned long cr3;
unsigned long eip;
unsigned long eflags;
unsigned long eax,ecx,edx,ebx;
unsigned long esp;
unsigned long ebp;
unsigned long esi;
unsigned long edi;
unsigned short es, __esh;
unsigned short cs, __csh;
unsigned short ss, __ssh;
unsigned short ds, __dsh;
unsigned short fs, __fsh;
unsigned short gs, __gsh;
unsigned short ldt, __ldth;
unsigned short trace, bitmap;
unsigned long io_bitmap[IO_BITMAP_SIZE+1];
unsigned long tr; // save the TSS selector (the Kernel change it during task init..)
unsigned long cr2, trap_no, error_code;
};
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Task Switching using ( TSS ) ?
okay. This is because ljmp expects a "far pointer" :
is equivalent to
In our case, the segment is a task gate, which means the offset will be just dropped. So what Linus&co made is to let the offset be some garbage (in the IO map) and have the segment being TR.
hence the "-4" which goes backward to have iomap[N-3..N] as the offset part.
Code: Select all
fp: db 78,56,34,12,CD,AB
jmp far [fp]
Code: Select all
jmp far ABCD:12345678
hence the "-4" which goes backward to have iomap[N-3..N] as the offset part.