Task & DPL3

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.
Post Reply
Guest

Task & DPL3

Post by Guest »

Hello, i have problems running a task within ring3.

Code: Select all

           
   SetGdtEntry(0,0,0,0,0);                            // 0x00
   SetGdtEntry(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);             // 0x08
   SetGdtEntry(2, 0, 0xFFFFFFFF, 0x92, 0xCF);             // 0x10
   SetGdtEntry(3, 0x0B8000, 0x0FFFFF, 0x92, 0xCF);          // 0x18
    SetGdtEntry(4, &tss[0], sizeof(struct TSS), 0x89, 0x5F); // 0x20
    SetGdtEntry(5, &tss[1], sizeof(struct TSS), 0x89, 0x5F); // 0x28
    SetGdtEntry(6, &tss[2], sizeof(struct TSS), 0x89, 0x5F); // 0x30
    SetGdtEntry(7, 0, 0xFFFFFFFF, 0xFA, 0xCF);               // 0x38  code / dpl3
    SetGdtEntry(8, 0, 0xFFFFFFFF, 0xF2, 0xCF);             // 0x40  data / dpl3

   tss[[0]].EFlags = 0x202;
   tss[[0]].Cs = 0x38;
   tss[[0]].Ss = 0x40;
   tss[[0]].Esp = 0x95000;
   tss[[0]].Ds = 0x40;
   tss[[0]].Eip = &task;
   tss[[0]].Trace = 0;
   tss[[0]].IoMap = sizeof(struct TSS);


             
             void task()
             {
         for (;;);
             }



void main()
{
   ReprogramPics();
   SetupGdt();

   asm("ljmp 0x20,0\n");

   for (;;);
}
When i jump in segment 0x20 i get exception 0.
But when i change the descriptor 0x38 & 0x40 to dpl0 i dont get an exeption. Pls Help !
AR

Re:Task & DPL3

Post by AR »

I can't remember with any certainty but I think CPL0 code cannot jump/call DPL3, people usually use an IRET hack (push CS,EIP,SS[IIRC] and execute IRET)
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:Task & DPL3

Post by Pype.Clicker »

the 'no call to DPL3' code restriction does not apply when you perform a hardware-assisted task switch. However, as soon as you enter level 3 code, you *need* a valid stack pointer in SS0:ESP0 to handle exception.

You should also load a proper TSS selector in TR register *prior* you jump/call another TSS so that the current state of the processor can be saved somewhere. If you're not concerned about being able to *return* to that state, just use a "dummy" TSS that you'll never jump to (also known as "trash" TSS)
Guest

Re:Task & DPL3

Post by Guest »

Hi, it still doesnt work.

Code: Select all

   tss[0].EFlags = 0x202;
   tss[0].Cs = 0x38;
   tss[0].Ss = 0x40;
   tss[0].Esp = 0x95000;
   tss[0].Ds = 0x40;
   tss[0].Eip = &task;
   tss[0].Trace = 0;
   tss[0].IoMap = sizeof(struct TSS);
   tss[0].Ss0 = 0x10;
   tss[0].Esp0 = 0x90000;


void main()
{
   ReprogramPics();
   SetupGdt();

   asm("ltr ax\n"::"a"(0x30));
   asm("ljmp 0x20,0\n");

   for (;;);
}
[edit by candy] Use the code tags [/edit]
proxy

Re:Task & DPL3

Post by proxy »

do you have the access level of the tasks pages accessible to ring3 code?

if not, i imagine that's part of the problem

proxy
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:Task & DPL3

Post by Pype.Clicker »

do you have paging enabled ? if yes, you're not filling the "CR3" value of the TSS, which may explain why it works so bad.

Also, i'm not sure i got right what that "5F" argument means, but it looks weird to me (bits 16..19 of TSS limit set ??? and 'AVL' bit set ??? what's the point ... )
Guest

Re:Task & DPL3

Post by Guest »

Hello, oh yes 5F is wrong. I changed to 4F but i still get the exception. Paging is disabled. With DPL0 code & data segment all work fine. But i want DPL3 :-\

Help!
mystran

Re:Task & DPL3

Post by mystran »

They way I've always done the switch to userspace is to setup everything, have a kernel-level task, then build a "fake" interrupt stack (that is, have the stuff in stack that you would have if you were serving an interrupt request) and then simply "restore" all registers and finally "IRET" to userspace, like if you were coming from a system call.

I like the method because I can use the same code for going into userspace whether or not we've actually ever been there. Another nice thing is that it handles loading SS automatically at the same time with CS, so userspace has a valid stack from the start.

Oh, and if you are using GCC for your inline assembly, you realize that you need % before registers, and $ before immediates.

So, basicly, what you probably want is (IIRC, didn't test):

Code: Select all

asm("ltr %ax;"::"a"(0x30));
asm("ljmp $0x20, $0");
Guest

Re:Task & DPL3

Post by Guest »

Hi, i am using the -masm=intel option to use intel syntax.
Guest

Re:Task & DPL3

Post by Guest »

Heya, i have it ! I forgot to set the RPL bits in the selector to 3 ;D

Code: Select all

tss[0].EFlags = 0x202;
tss[0].Cs = 0x38|3;
tss[0].Ss = 0x40|3;
tss[0].Esp = 0x95000;
tss[0].Ds = 0x40|3;
Post Reply