Page 1 of 1

Into multitasking ... (splitted)

Posted: Thu May 04, 2006 2:12 pm
by LongHorn
Thanks
Well i chosed to implement multitasking and read some documents mainly Viridis and BI's tut. Now i have some doubt's in BI's tutorial.

Code: Select all

  typedef struct {
          uint_t prozess_esp;    //actual position of esp
          uint_t prozess_ss;     //actual stack segment.

Code: Select all

 %macro REG_SAVE 0
      ;save all registers in the kernel-level stack of the process and switch to the kernel stack
        cld
        pushad
        push ds
        push es
        push fs
        push gs
        mov eax,[p]
        mov [eax],esp
        lea eax,[kstackend] ; switch to the kernel's own stack.
        mov esp,eax
        %endmacro
Here the current process p has the member prozess_esp. When interrupt occurs esp will be filled with tss.esp0 where the current context is pushed off.

Code: Select all

        %macro REG_RESTORE_MASTER 0
        mov eax,[p] ;put adress of struct of current process in eax.
        mov esp,[eax] ;restore adress of esp.
        mov ebx,[eax+8];put content of the k-stack field into ebx.
        mov [sys_tss+4],ebx ;update system tss.
        mov al,0x20
        out 0x20,al
        pop gs
        pop fs
        pop es
        pop ds
        popad
        iretd
        %endmacro
Here while returning the currentprocess p's esp is restored and user program is continued.

Code: Select all

 stacksetup=&kstacks[d][KSTACKTOP];
        *stacksetup--;
        *stacksetup--=0x0202;
        *stacksetup--=0x08;
         ................................
        *stacksetup=  0x10; //gs

        processes[f].prozess_esp=(uint_t)stacksetup;
        processes[f].prozess_ss=0x10;
        processes[f].prozess_kstack=(uint_t)&kstacks[d][KSTACKTOP];
        processes[f].prozess_ustack=(uint_t)&stacks[d][USTACKTOP];
prozess_esp is filled with pointer inside processes kernel stack.
So here comes my doubt.
So while returning you are filling current processes esp with the pointer into kernel stack. Then it means if we are going to push or pop something in our user program it is going to affect the kernel's stack and eventually at some instant it is going to fail. That's what happening in my case. Here what is the need of user stack?
p.s: i do know that i have something misuderstood. So somebody help me with it. Another thing i don't want to start a new thread as the topic is related and i have quoted so much quotes from BI's tut bcoz u should know what i am trying to ask.

Re:multitasking or I/O

Posted: Fri May 05, 2006 6:00 am
by distantvoices
so you have read my text (the one at bonafide or the one on my own site, which is more accurate and worked over quite a bit)

The point in having a kernel stack per tcb is because of context saving ere doing kernel stuff.

If you are by any chance experiencing stack overflows, consider other methods than the one I have presented in that tutorial. That's so simple and lacking of security it's no wonder it runs afoul under certain conditions. But alas if I took my current kernel for the tutorial, no one 'd get the point for it's in a way complex.

all registers are saved on that stack and then stacks might be switched after kernel has done its work.

If you do a ring3->ring0->ring3 transition, esp0:ss0 tupel is taken form the system tss. ring3 stack:ring3 stack segment is pushed on the kernel stack. That's automagically done by cpu microcode.

when returning to ring3 from ring0 the old ring3 stackpointer:segment is restored (they 're popped off the kernel stack. These two pops are the very last operations done by iret microcode) Transition to ring3 happens by loading cs with a ring3 segment iirc.

That's why one needs ring0 and ring3 stacks at least.

Well -- at the time when I've written that tutorial, I 've buildt in loads of hooks for later use - and they 've been of use whilst introducing ring3 processes.

Stay safe and don't hesitate to bug me in case of a question.

Re:multitasking or I/O

Posted: Fri May 05, 2006 4:13 pm
by LongHorn
I haven't made any CPL=3 process, therefore there is no way my stack pointer is going to be changed. It should have worked fine if i have allocated kernel stack a reasonable size. Kernel stack's size is exactly equal to the context of the process. No wonder why my stack screwed up.

Re:multitasking or I/O

Posted: Sat May 06, 2006 12:42 pm
by LongHorn
Finally i got my multitasking working. Wait it's not capable of running process at ring3.
should i push the SS & ESP for ring3 process? I read in previous posts of you that EFLAGS should be 0x3202. What else should i do?
ring3 process won't(shouldn't) be able to access the kernel. But now i am having all the tasks in kernel only. So should i copy it to some other address < kernel.
How will you stop the process from accessing kernel?
->By setting kernel pages to cpl=0
->Can we load user cs,ds descriptors with limit = 2GB.

Re:multitasking or I/O

Posted: Sat May 06, 2006 2:25 pm
by paulbarker
How will you stop the process from accessing kernel?
->By setting kernel pages to cpl=0
->Can we load user cs,ds descriptors with limit = 2GB.
I see no reason to combine the 2, most systems use just the first but using the 2nd or both should work fine. For the 2nd choice, you would have a kernel cs & ds as well as a user cs & ds. The kernel segments would have privilige (sp?) level of 0 and the user ones 3 (I'm not sure about conforming segments and all that, I haven't read the manuals in a while).

(Proof that even us english have problems with the language, that last sentence is horrible).

Re:multitasking or I/O

Posted: Sun May 07, 2006 12:57 am
by LongHorn
[edit] I am getting General Protection Exception when trying to return to a user segment.[/edit]
Well it's not true, after having a hard debugging session i finally found the problem (not the solution). loading segment registers with DPL3 data segment causes a fault(i.e) pop gs results in error. Does it mean that my user data segment descriptor is not correct or have i messed up with privilege rules.

Code: Select all

???*--stacksetup=USER_DATA_SEG|3; //SS
???*--stacksetup=processes[numprocess].prozess_ustack; //ESP
???*--stacksetup=0x3202;
???*--stacksetup=USER_CODE_SEG|3;
???*--stacksetup=(unsigned int) entry;
???*--stacksetup=0;
???*--stacksetup=0;
???*--stacksetup=0;
???*--stacksetup=0;
???*--stacksetup=0;
???*--stacksetup=argv;
???*--stacksetup=0;
???*--stacksetup=0;
???*--stacksetup=USER_DATA_SEG|3;
???*--stacksetup=USER_DATA_SEG|3;
???*--stacksetup=USER_DATA_SEG|3;
???*--stacksetup=USER_DATA_SEG|3;
???processes[numprocess].prozess_type=USER;
???processes[numprocess].prozess_esp=(unsigned int)stacksetup;
???processes[numprocess].prozess_ss=USER_DATA_SEG;

Code: Select all

gdt_set_gate( TSS_GDT, (unsigned long)&sys_tss, sizeof(tss_t) - 1, 0x89, 0xCF);
gdt_set_gate( USER_CODE_GDT, 0, 0xFFFFFFFF ,0xFA ,0xCF);
gdt_set_gate( USER_DATA_GDT, 0, 0xFFFFFFFF ,0xF2 ,0xCF);
(Proof that even us english have problems with the language, that last sentence is horrible).
What do you meant by this? My english is horrible i do know that. :P

Re:Into multitasking ... (splitted)

Posted: Wed May 10, 2006 4:06 am
by LongHorn
Now i am able to jump into user mode tasks, i changed cr3 also and i have the required pages and page tables for the user task. But i am getting page fault. An odd behaviour i noticed was that as soon as it jumps to user task, it is interrupted by timer interrupt and when it resumes the process, it shows page fault. In bochs debugger i got the following information before page fault happens.
eax:0x00000000, ebx:0x00000000, ecx:0x00000000, edx:0x00000000
ebp:0x00000000, esp:0xbfffffff, esi:0x00000000, edi:0x00000000
eip:0x00500000, eflags:0x00000202, inhibit_mask:0
cs:s=0x0023, dl=0x0000ffff, dh=0x00cffa00, valid=1
ss:s=0x002b, dl=0x0000ffff, dh=0x00cff300, valid=1
ds:s=0x002b, dl=0x0000ffff, dh=0x00cff300, valid=1
es:s=0x002b, dl=0x0000ffff, dh=0x00cff300, valid=1
fs:s=0x002b, dl=0x0000ffff, dh=0x00cff300, valid=1
gs:s=0x002b, dl=0x0000ffff, dh=0x00cff200, valid=1
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0018, dl=0x85200067, dh=0xc0808910, valid=1
gdtr:base=0xc0105040, limit=0x2f
idtr:base=0xc0105080, limit=0x7ff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x80000011, cr1:0x00000000, cr2:0x00000000
cr3:0x03ff4000, cr4:0x00000000
in debugger the disassembly shows this information
00500000: ( ): nop ; 90
00500001: ( ): jmp .+0xfffffffe ; ebfe
page fault handler shows this information
cr3=0x3ff4000
page fault exception : 0x500000
pagedir[1] : 0x3ff3003
pagetable[0x100] : 0x3ff2007