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.
Okay, so today i tried to make a multitasking system. When i tried it out nothing happened and what i mean by that is the computer freezes completely. There is no evidence of interrupts firing at all. I have looked over my code several times and i don't see any missing sti or misplaced cli.
struct PROCESS
{
char *name;
unsigned int eax;
unsigned int ebx;
unsigned int ecx;
unsigned int edx;
unsigned int esi;
unsigned int edi;
unsigned int cr0;
unsigned int cr3;
unsigned int eip;
unsigned int esp;
unsigned int ebp;
unsigned short pid;
unsigned char status;
unsigned int suspend;
unsigned char access;
};
After reading those links i realized that i wasn't properly changing the values in the stack to so when it popped all the registers the proper values weren't there. My problem now is that it Red Screens and tells me that eip=3 which obviously isn't right. I'm wondering why it's doing this because i thought that
You shouldn't need that eip value though, just setup a stack instead. I would convert to either of the code examples I showed you, as they work great for me.
did you read/look over either of the pages with code that I posted? You setup a stack with register values, including eip on it, and when you want to switch tasks, you just change ESP to the stack of the task you set up.
But that's pretty much what i'm doing already. When the timer interrupt fires and the switch_task function gets call, it changes the values that have been pushed onto the stack then when the code gets to iret as we all know the eip register gets popped off. The only difference is that the values are on the kernel stack.
Okay, i changed my code so that the registers are pushed onto each processes stack. And I still get an invalid opcode exception with eip=3
my process structure
struct REGS
{
unsigned int gs, fs, es, ds; /* pushed the segs last */
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */
unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */
unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */
}__attribute__((packed));
struct PROCESS
{
char *name;
struct REGS *r;
unsigned int *esp;
unsigned short pid;
unsigned char status;
unsigned int suspend;
unsigned char access;
};
The best way to do this is to set up the scheduler (switch_task, or whatever) as an interrupt handler, so that you can iret to a task, just like in my example.
edit: sorry for being frustrated. didn't know that your kmalloc() alloc'ed 4096.
My scheduler is the interrupt handler, and the scheduler calls the timer, not the other way around.
edit:
your switch_tasks function shouldn't be changing the values of registers.
Thats the purpose of the having a stack. Just pop the values off of the stack. look at the working examples I have posted.
the type of name is char * and "Idle process" is a string constant which should be in the .rodata section. It is perfectly legal (while not smart from a future planning perspective) to make a char * point to a string constant like that.