OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 12:56 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 34 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Troubles implementing multitasking
PostPosted: Wed Aug 01, 2018 2:15 pm 
Offline
Member
Member

Joined: Wed Jul 25, 2018 2:47 pm
Posts: 38
Location: Pizzaland, Southern Europe
I'm having some troubles implementing supervisor multitasking...

Currently, my setup is as follows:
- A task is created:
- The memory manager allocates a new page directory, the kernel directory gets copied into the new one
- A new page gets allocated for the stack, and is mapped to a very high region (because the stack grows downwards I believe?)
- The task is initialized:
- The initial state is set so that the esp = ebp = bottom of the page that was allocated previously, eip = address of the routine to execute
- The task is enqueued.

Once the timer ticks, this happens:
- The interrupt handler is called, its argument is a pointer to the registers that were pushed by the processor
- The currently running task is updated with the state that is found on the registers, and then re-enqueued
- The new task is dequeued, the registers on the stack are updated with the state of the new task
- The handler returns

The problem is, the moment the handler returns, the OS starts executing random stuff, like launching interrupts, which makes me think it's executing instructions from random memory locations, which makes me believe I must be doing something wrong... Can anyone shed some light for me?


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Wed Aug 01, 2018 5:13 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1925
Location: Athens, GA, USA
Do you have an repo on a site such as Github or Sorceforge which you could give us a link to, so we can review the code?

Or conversely, could you please post the relevant code from the interrupt handler, scheduler, and so forth? This would give us a chance to see if there is some bug in it you might have missed.

_________________
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: Troubles implementing multitasking
PostPosted: Wed Aug 01, 2018 11:19 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

frabert wrote:
I'm having some troubles implementing supervisor multitasking...

Currently, my setup is as follows:
- A task is created:
- The memory manager allocates a new page directory, the kernel directory gets copied into the new one
- A new page gets allocated for the stack, and is mapped to a very high region (because the stack grows downwards I believe?)
- The task is initialized:
- The initial state is set so that the esp = ebp = bottom of the page that was allocated previously, eip = address of the routine to execute
- The task is enqueued.


The stack grows downwards, so you'd want "esp = top of the page that was allocated" so that the stack can grow down from the top.

frabert wrote:
The problem is, the moment the handler returns, the OS starts executing random stuff, like launching interrupts, which makes me think it's executing instructions from random memory locations, which makes me believe I must be doing something wrong... Can anyone shed some light for me?


I'd recommend using a debugger (e.g. single-step one instruction at a time in Bochs) to watch exactly what the CPU does at each step, starting from a breakpoint at the start of the low-level task switch code.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Thu Aug 02, 2018 1:26 am 
Offline
Member
Member

Joined: Wed Jul 25, 2018 2:47 pm
Posts: 38
Location: Pizzaland, Southern Europe
Schol-R-LEA wrote:
Do you have an repo on a site such as Github or Sorceforge which you could give us a link to, so we can review the code?

Here. I will now try and see stepping the code as Brendan suggested with Bochs

EDIT: I was able to fix the first of the issues, https://github.com/frabert/toy-os/blob/master/tasking.cpp#L82 should read (uintptr_t)m_func, not (uintptr_t)&m_func, though now I am able to only run two tasks, and I have to put an infinite loop at the end of the functions I call, but that's just because I am not setting up the stack with a proper return pad I guess. After a while the functions throw a page fault, so maybe now it's messing with the paging...


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Sat Aug 04, 2018 1:13 am 
Offline
Member
Member

Joined: Wed Jul 25, 2018 2:47 pm
Posts: 38
Location: Pizzaland, Southern Europe
Hey I managed to get it almost working! :D

But I have another problem now. Stepping through the code instruction by instruction, I noticed that when executing "iretd", the esp register does not get updated at the end of the interrupt handler... What's the correct way of setting a new stack for the tasks?


Attachments:
Screenshot from 2018-08-04 09-10-55.png
Screenshot from 2018-08-04 09-10-55.png [ 7.46 KiB | Viewed 2726 times ]
Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Sun Aug 05, 2018 5:41 pm 
Offline
User avatar

Joined: Fri Oct 14, 2016 7:37 pm
Posts: 24
Location: Canada
About your esp, iret does not change it. It's up to your OS to update the esp on a context switch. Don't forget the TSS too.

It's your OS so do whatever makes sense (but be warned, bad design decisions come back to haunt you).
In my IRQ handler, I had in order:
Code:
irq_return:
    pop gs
    pop fs
    pop es
    pop ds
    popa
    add esp, 8 ; Error code and other shenanigans
    iret
And so I set up the stack like:
Code:
uint32_t *stack = (uint32_t *)malloc(4096);
stack = (uint32_t *)((int)stack + 4096);
stack -= 16; // Padding
*--stack = 0x10;        // ss
*--stack = 0x00;        // esp
*--stack = 0x202;       // eflags
*--stack = 0x08;        // cs
*--stack = entry_point; // eip
*--stack = 0x00;        // err_code
*--stack = 0x00;        // int_no
/* pushad */
*--stack = 0xCAFEBABE; // eax
*--stack = 0x00;       // ecx
*--stack = 0x00;       // edx
*--stack = 0x00;       // ebx
*--stack = 0x00;       // esp_dummy
*--stack = 0x00;       // ebp
*--stack = 0x00;       // esi
*--stack = 0x00;       // edi
/* Push segment registers */
*--stack = 0x10; // ds
*--stack = 0x10; // es
*--stack = 0x10; // fs
*--stack = 0x10; // gs
proc->thread.regs.registers = (void *)stack; // Top of stack

Then to switch tasks, I switch the ESP/page directories and jump to "irq_return" and let the cpu handle the rest. And so to run the task, I set up the task's stack and queue it, where the scheduler then changes the stack and the cpu pops the return address and runs the code. Not sure if it's THE way, but it works and so far nothing bad has happened.
Looking at your code, you do almost the same thing, except that your "switchTasks" works differently. It can't be that bad.

_________________
LiquiDOS, my weird hobbyist OS.
"Strive for progress, not perfection" - Anonymous


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Mon Aug 06, 2018 8:24 am 
Offline
Member
Member

Joined: Wed Jul 25, 2018 2:47 pm
Posts: 38
Location: Pizzaland, Southern Europe
What I can't wrap my head around is how to change the esp _after_ the iret, since if I change it before it would break the iret behavior, right?
But, if I can't do it before, how am I going to tell the newly created task where to look for its fresh stack?


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Mon Aug 06, 2018 9:14 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
After a task switch where do you want the iret to return to? Think about it.


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Mon Aug 06, 2018 10:20 am 
Offline
Member
Member

Joined: Wed Jul 25, 2018 2:47 pm
Posts: 38
Location: Pizzaland, Southern Europe
Well, to the eip of the resumed task as it was saved on suspension, right?


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Mon Aug 06, 2018 10:51 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
Right. Which stack is that going to be on?


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Mon Aug 06, 2018 11:03 am 
Offline
Member
Member

Joined: Wed Jul 25, 2018 2:47 pm
Posts: 38
Location: Pizzaland, Southern Europe
Its own, the one I have allocated when I initially created the task (in my case it's a whole page for simplicity)


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Mon Aug 06, 2018 11:15 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
So you change the stack pointer before the iret, so that it points to the correct stack (where the return address was pushed last time the task relinquished control).


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Mon Aug 06, 2018 11:25 am 
Offline
Member
Member

Joined: Wed Jul 25, 2018 2:47 pm
Posts: 38
Location: Pizzaland, Southern Europe
But if I change the esp before the iret, what is iret going to pop into the eflags and all of that? Or am I supposed to save all of that inside the task's stack too?


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Mon Aug 06, 2018 11:57 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
All that was saved when you called the interrupt that originally switched away from the task. Restoring cr3 and the stack pointer (plus all the other registers you have saved) returns the task to the state it was in before you switched.


Top
 Profile  
 
 Post subject: Re: Troubles implementing multitasking
PostPosted: Mon Aug 06, 2018 12:09 pm 
Offline
User avatar

Joined: Fri Oct 14, 2016 7:37 pm
Posts: 24
Location: Canada
yes. The interrupt handler should save all the registers (segment registers included); then when you switch tasks, you point esp to the new task's stack, and the interrupt handler should popa and pop the segment registers too. When iret is executed, the CPU pops the EIP and off you go.
Quote:
Restoring cr3 and the stack pointer (plus all the other registers you have saved)

CR3 does not get restored. Neither does ESP.

Also I should note that after you switch stacks, you should jump directly to your popa/iret instructions to avoid breaking the stack.

_________________
LiquiDOS, my weird hobbyist OS.
"Strive for progress, not perfection" - Anonymous


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: 8infy, Google [Bot] and 50 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