Multitasking works... for only two tasks.

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
yoshi65
Posts: 11
Joined: Sun Mar 11, 2012 8:49 pm

Multitasking works... for only two tasks.

Post by yoshi65 »

Hey guys I have been trying to figure this out for a long while now. I have multitasking code but it only works for two tasks the kernel and one other task. Any other one gives me a properly caught gpf interrupt. I call new_task() twice and then start_task with each task created before. Here is my code. Is it something stupid I am missing? If you need to see anymore let me know. Thank you so much.

Code: Select all

[global irq0]
irq0:
	cli
	pusha
	
	push ds
	push es
	push fs
	push gs
	
	mov eax, GDT32.Kernel_Data
	mov ds, eax
	mov es, eax
	mov fs, eax
	mov gs, eax

	;mov eax, cr3
	;push eax

	push esp
	call schedule
	mov esp, eax
	
		
	;pop eax
	;mov cr3, eax
	
	mov   al, 0x20
	out 0x20, al
	
	pop gs
	pop fs
	pop es
	pop ds
	
	popa
	sti
	iret
And then my task related code:

Code: Select all



uint32_t schedule(uint32_t stack){
	
	system_ticks++;
	if(!tasking) return stack;
	task_t * t = sleep;
	
	current_task->esp0 = stack;
	do{
		if(current_task->next)
			current_task =  current_task->next;
		else
			current_task = ready;
			
		if (current_task->waiting_sem )
			if (current_task->waiting_sem->n == 0)
				continue;
	}while(current_task->sleep > system_ticks);
	
	if(current_task->magic != 0xDEADC0DE){
		kprintf("Corrupted task!!\n");
		for(;;);
	}
	//kprintf("Task: %s\n", current_task->name);
	//BOCHS_MAGIC
	write_cr3(current_task->dir->phys_tables);
	return current_task->esp0;
	
}

void start_task(task_t *t){
	task_t * temp = ready;
	while(temp->next) temp = temp->next;
	temp->next = t;
	t->prev = temp;


}


task_t * new_task(char * name, void (*start)()){
	asm volatile("cli");

	task_t *new_task = (task_t*)kmalloc(sizeof(task_t),0,0);
	memset(new_task, 0, sizeof(task_t));
	
	strcpy(new_task->name, name);
	
	new_task->dir = copy_page_directory(current_directory);
	
	new_task->pid = npid++;
	new_task->start = (uint32_t)&start;
	new_task->sleep = 0;
	new_task->in_buff = cb_new(64);
	
	
	new_task->files[0].used = 1;
	new_task->files[0].node = &stdin_node;
	
	new_task->files[1].used = 1;
	new_task->files[1].node = &stdout_node;
	
	new_task->magic = 0xDEADC0DE;
	
	claim_frame(get_page(new_task->dir, kstack, 0), 0, 1);
	claim_frame(get_page(new_task->dir, ustack, 0), 1, 1);
	uint32_t * new_stack = (uint32_t*)(kstack + 0x1000);
	*--new_stack = 0x202; // eflags
	*--new_stack = 0x08;  // Kerenel code
	*--new_stack = (uint32_t)&run;
	
	*--new_stack = 0x00;  // edi
	*--new_stack = 0x00;  // esi
	*--new_stack = 0x00;  // ebp
	*--new_stack = 0x00;  // empty
	
	*--new_stack = 0x00;  // ebx
	*--new_stack = 0x00;  // edx
	*--new_stack = 0x00;  // ecx
	*--new_stack = 0x00;  // eax
	

	// data segments
    *--new_stack = 0x10;  // ds
    *--new_stack = 0x10;  // es
    *--new_stack = 0x10;  // fs
    *--new_stack = 0x10;  // gs
	
	new_task->esp0 = (uint32_t)new_stack;
	new_task->esp3 = (uint32_t)ustack;
	
	asm volatile("sti");
	return new_task;


}


User avatar
eryjus
Member
Member
Posts: 286
Joined: Fri Oct 21, 2011 9:47 pm
Libera.chat IRC: eryjus
Location: Tustin, CA USA

Re: Multitasking works... for only two tasks.

Post by eryjus »

yoshi65 wrote:

Code: Select all

task_t * new_task(char * name, void (*start)()){
   ...
	new_task->start = (uint32_t)&start;
	...
	*--new_stack = (uint32_t)&run;
   ...	
}
Where does &run come from?

Also, note that the declaration void (*start)() is already an address. No need to use &start.
Adam

The name is fitting: Century Hobby OS -- At this rate, it's gonna take me that long!
Read about my mistakes and missteps with this iteration: Journal

"Sometimes things just don't make sense until you figure them out." -- Phil Stahlheber
yoshi65
Posts: 11
Joined: Sun Mar 11, 2012 8:49 pm

Re: Multitasking works... for only two tasks.

Post by yoshi65 »

Thank you Adam for your reply! The run that you see is just a function that calls task->start so when start exits it can trap it.
Post Reply