OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 1:50 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 19 posts ]  Go to page Previous  1, 2
Author Message
 Post subject: Re: Something about multitasking
PostPosted: Fri Jan 27, 2017 11:47 am 
Offline
Member
Member
User avatar

Joined: Sun Nov 20, 2016 7:26 am
Posts: 155
Location: Somewhere
MollenOS wrote:
Exactly, you need to handle the timer that handles task-switching a bit differently than a irq_common.

While they can share the entry point of the interrupt, you need to code a different exit function for the one that does the task switching, instead of letting the interrupt handler return on a normal way, call a new function next_thread or whatever you want, where you do the special-exit routine

Thanks.

I've finally finished all of multitasking code, I have tested for 30 minutes, didn't have a problem. Also I have some questions.

While calling assembly code from c, all examples use:

Code:
push %ebp
mov %esp, %ebp


Why they use that? Using directly %esp should work also.

And what does C push before calling function? I googled it but somewhere says it is for return value, and somewhere says it is for eip.

I think it is for eip, because return value is already handled with eax. Also ret pops off eip, so C should push the eip before calling function.

That is my last switch_to_first_task.

Code:
switch_to_first_task:
    mov 4(%esp), %eax

    mov 4(%eax), %ebx
    mov 8(%eax), %ecx
    mov 12(%eax), %edx
    mov 16(%eax), %esi
    mov 20(%eax), %edi
    mov 24(%eax), %esp
    mov 28(%eax), %ebp

    push %eax
    mov 36(%eax), %eax
    mov %eax, %cr3
    pop %eax

    push %eax
    mov 32(%eax), %eax
    xchg (%esp), %eax
    mov (%eax), %eax

    ret

_________________
Keyboard not found!

Press F1 to run setup.
Press F2 to continue.


Top
 Profile  
 
 Post subject: Re: Something about multitasking
PostPosted: Fri Jan 27, 2017 4:52 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1925
Location: Athens, GA, USA
Agola wrote:
While calling assembly code from c, all examples use:

Code:
push %ebp
mov %esp, %ebp


Why they use that? Using directly %esp should work also.


That's to set up the stack frame for the function's activation record. I gave a detailed explanation of activation records here, and the wiki covers it well here, though to revisit the subject:

The activation record is the record of the function's local variables. In order to allow the function to be re-entrant (that is, to make it so that it could be called recursively), each call of the function has to have it's own activation record, which is created at the time the function is called and either freed or (for certain kinds of tail call optimization) reused. As a general rule, a stack is used to keep track of the order in which activation records are created, and in most modern systems where there is a process-wide stack pointer register (either dedicated or by convention), the activation records are pushed onto the system stack as the first thing the function does, and popped off it as the last thing it does.

The stack frame is a block of memory on the stack set up to hold the activation record (or at least a pointer to it). The process needs a pointer to the starting address of the stack frame in the stack, so it can find the local variables' addresses - the locals are accessed using that address plus an offset.

Most systems have a dedicated register (or one set aside by convention) for this base pointer (also called a frame pointer). However, before a function can set up it's own base pointer, either the caller or the callee has to save the caller's base pointer, and again, since this is supposed to be re-entrant, it uses the stack for this. So, for most calling conventions, this means pushing the current base pointer before the function's body starts, and popping it back when the function ends.

Who does this depends on the language and the calling convention. Most C-oriented conventions, such as cdecl, have the caller push their own frame pointer before the call, and pop it off afterwards. However, the Pascal-style conventions such as stdcall have the callee do this.

Quote:
And what does C push before calling function? I googled it but somewhere says it is for return value, and somewhere says it is for eip.

I think it is for eip, because return value is already handled with eax. Also ret pops off eip, so C should push the eip before calling function.


Again, it depends on the calling convention. At the very least, for x86, the CALL instruction will automatically push the return address (IP in early models, [(E|R)]IP + wordsize in later implementations) which the RET instruction uses later. However, if there are any function arguments, those have to be pushed first, and in C they are usually pushed in reverse order - for foo(x,y,z), the caller would push z first, then y, then x. This is to allow for variable argument sizes, such the printf() formatting arguments. Then (for a caller-cleaned convention such as cdecl) it would save the base pointer and stack pointer as already explained, then make the CALL operation. On return, it would then clear it's base pointer off the stack (the callee already had to restore caller's stack pointer in order to return, so all that it needs to do is increment the stack pointer by the word size).

This means that (assuming that the params are all of the system word size), the stack at the start of the function would be "z, y, x, caller's base pointer, return address". The function would then push it's own locals onto the stack, and use a positive offset to access arguments and negative offsets to access locals. If the locals are a and b, then (using AT&T mnemonics):

Code:
a == (%ebp)
b == -4(%ebp)

z == 8(%ebp)
y == 12(%ebp)
z == 16(%ebp)

_________________
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.


Top
 Profile  
 
 Post subject: Re: Something about multitasking
PostPosted: Sat Jan 28, 2017 5:26 am 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3192
You really need different setups of the frame for iretd based on the mode of task you return to. The stack frame differs between V86 (contains segment registers + ss/esp + flags and cs/eip), non-ring 0 (ss/esp + flags and cs/eip) and ring 0 (flags and cs/eip). You decide if it is V86 based on bit 17 in eflags, and if it is ring 0 by checking the RPL (bits 0..1) of the selector.

I still go with using iretd, but the stack needs to reflect the mode of the task.

In addition to that, I store all the registers (including current ss/esp and cs/eip) in the thread block, which makes it easier to read-out the context of a task without having to examine the stack.


Top
 Profile  
 
 Post subject: Re: Something about multitasking
PostPosted: Mon Jan 30, 2017 12:15 pm 
Offline
Member
Member

Joined: Sat Nov 07, 2015 3:12 pm
Posts: 145
Hi,
if task switch randomly stops, check this :
1. Disable PIT switching. Comment out all tasks creations you have for now. Do in a loop something like
task_switch(currentRegsPtr,currentRegsPtr)
Check if the end of this function changes NOTHING ( especially ESP ). Let it run for a while and observe.
2. If it works, you have an issue with your interrupts. Be sure Eoi is currently set .
3.Be sure your interrupt flag is OFF before every single task switch ( don't worry it will be restored with iret)
4. Be sure that it is actually set in the first place for the tasks you created
5. Remember that Sti takes time before being valid. some people use various techniques including nops, pauses and outb
6. Do the crash test: set your Pit to the max and quantum's to the min. if it crashes more often you are likely to saturate your stack when you are interrupted. Most likely you are doing some STI inappropriately


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page Previous  1, 2

All times are UTC - 6 hours


Who is online

Users browsing this forum: DotBot [Bot], Google [Bot], SemrushBot [Bot] and 170 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group