OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Oct 26, 2020 7:39 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: Multitasking
PostPosted: Fri Jan 09, 2009 10:04 am 
Offline
Member
Member

Joined: Tue Dec 09, 2008 12:43 pm
Posts: 63
Well, I can't get multitasking work properly.
Qemu just quits (bochs restarts...bochsout: http://pastebin.com/m48c9e5ce)
here is task_t:
Code:
typedef struct task_t
{
   int pid; // task id
   unsigned int stack; // stack of the task
   unsigned char state; // is task alive?
   void (*thread_start)(void); // a pointer to the first function that will executed (eip) in the task
   struct task_t *next; // pointer to the next task
} task_t;



Code:
#include "task.h"
#include "mm.h"
#include "screen.h"
#include "hardware.h"

task_t *tasks;
unsigned int tasks_num, current_pid;

void initialize_multitasking(void)
{
   tasks = (task_t *)malloc(sizeof(task_t));
   tasks_num = 0;
   unsigned int divisor = 1193180 / 50;
   outport(0x43, 0x36);
   outport(0x40, divisor & 0xFF);
   outport(0x40, (divisor >> 8) & 0xFF);
   outport(0x21, 0x00); // enable interrupts from IRQ 0-7 (PIT will now start working)
   create_task(0, idle);
}

void idle(void)
{
   puts("\nIdling...\n");
   for(;;) ;
}

void clone_task(task_t *source, task_t *dest)
{
   dest->pid = source->pid;
   dest->stack = source->stack;
   dest->state = source->state;
   dest->thread_start = source->thread_start;
   dest->next = source->next;
}

void create_task(int id, void (*thread_start)(void))
{
   asm volatile("cli"); // no one should interrupt us
   task_t *temp_task = (task_t *)malloc(sizeof(task_t));
   temp_task->pid = id;
   temp_task->next = 0;
   temp_task->thread_start = thread_start;
   temp_task->stack = (unsigned int)malloc(0x1000);
   
   unsigned int *stack = (unsigned int *)(temp_task->stack + 0x1000/*stack grows downwards*/);
   /**--stack = 0; // ss
   *--stack = 0; // useresp*/
   
   *--stack = 0x202; // eflags
   *--stack = 0x08; // cs
   *--stack = (unsigned int)thread_start; // eip
   
   unsigned int i = 0;
   for(;i<8;i++) // pusha = 0
      *--stack = 0;
   
   for(i=0;i<4;i++) // gs, fs, es, ds
      *--stack = 0x10;
   
   temp_task->state = 1; // is avaiable
   temp_task->stack = (unsigned int)stack;
   clone_task(temp_task, &tasks[id]);
   
   current_pid = id;
   tasks_num++;
}

unsigned int schedule_tasks(unsigned int context)
{
   outport(0x20, 0x20); // it's IRQ0, we should inform the slave that we've got the message.
   return tasks[0].stack; // i just want to try 1 task for now
}


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Fri Jan 09, 2009 11:20 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9288
Location: On the balcony, where I can actually keep 1½m distance
Try tracking your stackpointer, its broken:
Quote:
ESP=ffffffff


Bochs debugger can help you with that

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Mon Jan 12, 2009 1:15 pm 
Offline
Member
Member

Joined: Tue Dec 09, 2008 12:43 pm
Posts: 63
Combuster wrote:
Try tracking your stackpointer, its broken:
Quote:
ESP=ffffffff


Bochs debugger can help you with that


I haven't tried the bochs debugger yet. how do I use it?


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Mon Jan 12, 2009 1:52 pm 
Offline
Member
Member

Joined: Tue Aug 21, 2007 1:41 am
Posts: 207
Location: Germany
I think your problem lies in the popa(d) instruction.
eXeCuTeR wrote:
unsigned int i = 0;
for(;i<8;i++) // pusha = 0
*--stack = 0;

You set everything to 0. If you execute the popa(d) instruction you overwrite esp with 0.
This is just a guess, but that is the only thing I can think of for now.


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Mon Jan 12, 2009 2:19 pm 
Offline
Member
Member

Joined: Tue Dec 09, 2008 12:43 pm
Posts: 63
cyr1x wrote:
I think your problem lies in the popa(d) instruction.
eXeCuTeR wrote:
unsigned int i = 0;
for(;i<8;i++) // pusha = 0
*--stack = 0;

You set everything to 0. If you execute the popa(d) instruction you overwrite esp with 0.
This is just a guess, but that is the only thing I can think of for now.


nope, this is not the problem, thanks anyways.
how do you i use the bochs debugger then guys? :P


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Tue Jan 13, 2009 7:54 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 01, 2008 11:18 am
Posts: 70
Location: Ukraine, Kiev
HI, anyone.

I'm trying to implement multitasking. I read about software-trask switching. As I understand current eip value needs be stored and new eip value needs be loaded. I'm writing according to BrokenThorn.com tutorial, that is written in MSVC++. I tried to use that asm (ex.: _asm mov eax, eip) and got an error: eip - unknown symbol. Something like this. So, if anyone know, what need I do?

Thanks.

_________________
Don't think a ****, but in ukrainian schools English is TOO BAD!


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Tue Jan 13, 2009 8:15 am 
Offline
Member
Member

Joined: Tue Nov 06, 2007 2:37 pm
Posts: 124
Location: Hungary
djsilence wrote:
I tried to use that asm (ex.: _asm mov eax, eip) and got an error: eip - unknown symbol. Something like this. So, if anyone know, what need I do?


You can't access the EIP register like any other general purpose register. I suggest you to check how interrupts are working and the IRET instruction (especially their effect on the stack) and after that you can easily figure out how you can change the value of EIP.

giszo


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Tue Jan 13, 2009 3:23 pm 
Offline
Member
Member

Joined: Tue Dec 09, 2008 12:43 pm
Posts: 63
berkus wrote:
Configure bochs with debugger, and run it.

This is configure line for bochs i'm using in osdev (the last 3 lines enable the debugger among other things):
Code:
  # --disable-readline is for bfe2 front-end
  ./configure --prefix=/usr --enable-vbe --without-wx --enable-cpu-level=6 \
        --enable-4meg-pages --enable-global-pages --enable-pae --enable-fpu \
        --enable-mmx --disable-3dnow --enable-sse --enable-sep \
        --enable-sb16=linux \
        --enable-iodebug --enable-debugger --enable-port-e9-hack --enable-disasm \
        --enable-x86-debugger --enable-instrumentation


As you may have guessed, there are debugger front-ends for you GUI lovers out there.


After I configure this way, and then running `make` I get:
Code:
cd iodev && \
   make  libiodev.a
make[1]: Entering directory `/home/executer/Desktop/bochs-20090111/iodev'
g++ -c  -I.. -I./.. -I../instrument/stubs -I./../instrument/stubs -g -O2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES    devices.cc -o devices.o
../instrument/stubs/instrument.h: In member function ‘void bx_devices_c::outp(Bit16u, Bit32u, unsigned int)’:
../instrument/stubs/instrument.h:97: error: too many arguments to function ‘void bx_instr_outp(Bit16u, unsigned int)’
devices.cc:958: error: at this point in file
make[1]: *** [devices.o] Error 1
make[1]: Leaving directory `/home/executer/Desktop/bochs-20090111/iodev'
make: *** [iodev/libiodev.a] Error 2


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Tue Jan 13, 2009 3:49 pm 
Offline
Member
Member

Joined: Sun Nov 09, 2008 2:55 am
Posts: 524
Location: Pennsylvania, USA
Quote:
--enable-instrumentation


Don't think you need this, I don't use it and my debugger runs fine.


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Wed Jan 14, 2009 11:46 am 
Offline
Member
Member

Joined: Tue Dec 09, 2008 12:43 pm
Posts: 63
JohnnyTheDon wrote:
Quote:
--enable-instrumentation


Don't think you need this, I don't use it and my debugger runs fine.


Still no effect.. :( I'm also having a lot of warnings.
Anyways...does anyone has any idea why I'm getting this god damn page fault on 0xFFFFB00A?!

this is so weird they are 0xFFFFFFFF: (the eip is pointing to the interrupt_handler function)
Code:
00108639062i[CPU  ] | EAX=ffffffdf  EBX=00000025  ECX=000002d9  EDX=ffffffff
00108639062i[CPU  ] | ESP=c0000004  EBP=00067ee0  ESI=ffffffff  EDI=ffffffff
00108639062i[CPU  ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf af PF cf
00108639062i[CPU  ] | SEG selector     base    limit G D
00108639062i[CPU  ] | SEG sltr(index|ti|rpl)     base    limit G D
00108639062i[CPU  ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00108639062i[CPU  ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00108639062i[CPU  ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00108639062i[CPU  ] |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
00108639062i[CPU  ] |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00108639062i[CPU  ] |  GS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00108639062i[CPU  ] | EIP=00100e15 (00100e15)
00108639062i[CPU  ] | CR0=0xe0000011 CR1=0 CR2=0xbffffffc
00108639062i[CPU  ] | CR3=0x00000000 CR4=0x00000000
00108639062i[CPU  ] >> pushad  : 60
00108639062e[CPU  ] exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Wed Jan 14, 2009 1:55 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9288
Location: On the balcony, where I can actually keep 1½m distance
Quote:
CR3=0x00000000
is this valid with paging enabled?

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Wed Jan 14, 2009 3:04 pm 
Offline
Member
Member

Joined: Tue Dec 09, 2008 12:43 pm
Posts: 63
Combuster wrote:
Quote:
CR3=0x00000000
is this valid with paging enabled?


Everything is just messed up somehow, that's totally weird.


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Thu Jan 15, 2009 3:31 pm 
Offline
Member
Member

Joined: Tue Dec 09, 2008 12:43 pm
Posts: 63
PLAESE HELP OUT distinguish the error in the code that causes a page faullt and messes the registers up!! =[

I also use these:
Code:
global writeto_cr3
writeto_cr3:
   mov eax, [esp+4]
   mov cr3, eax
   ret
   
global or_cr0
or_cr0:
   mov eax, cr0
   or eax, 0x80000000
   mov cr0, eax
   ret

global readfrom_cr2 ; for page faults
readfrom_cr2:
   mov eax, cr2
   ret


and my current code (i just copied this code now for a tutorial because im so exhausted =[)
Code:
#include "task.h"
#include "mm.h"
#include "screen.h"
#include "hardware.h"

typedef struct{        //Simple structure for a thread
  unsigned int esp0;   //Stack for kernel
  unsigned int esp3;   //Stack for process
} Thread;

Thread Threads[2];     //Space for our simple threads. Just 2!
int CurrentTask = -1;  //The thread currenlty running (-1 == none)
int first = 0;

void initialize_multitasking(void)
{
   CreateTask(0, idle);
   CreateTask(1, idle);
   unsigned int divisor = 1193180 / 50;
   outport(0x43, 0x36);
   outport(0x40, divisor & 0xFF);
   outport(0x40, (divisor >> 8) & 0xFF);
   outport(0x21, 0x00); // enable interrupts from IRQ 0-7 (PIT will now start working)
}

void idle()
{
   puts("IDLE");
   for(;;) ;
}

void idle2()
{
   puts("idle");
   for(;;) ;
}

//This will create a task
//It will make a stack that looks like it has all
//of the stuff of an IRQ handler 'pushed' on it
void CreateTask(int id, void (*thread)()){
unsigned int *stack;

Threads[id].esp0 = (unsigned int)malloc(0x1000) + 4096; //This allocates 4kb of memory, then puts the pointer at the end of it

stack = (unsigned int* )Threads[id].esp0; //This makes a pointer to the stack for us

//First, this stuff is pushed by the processor
*--stack = 0;
*--stack = 0;
*--stack = 0x0202; //This is EFLAGS
*--stack = 0x08;   //This is CS, our code segment
*--stack = (unsigned int)thread; //This is EIP

//Next, the stuff pushed by 'pusha'
*--stack = 0; //EDI
*--stack = 0; //ESI
*--stack = 0; //EBP
*--stack = 0; //Just an offset, no value
*--stack = 0; //EBX
*--stack = 0; //EDX
*--stack = 0; //ECX
*--stack = 0; //EAX

//Now these are the data segments pushed by the IRQ handler
*--stack = 0x10; //DS
*--stack = 0x10; //ES
*--stack = 0x10; //FS
*--stack = 0x10; //GS

Threads[id].esp0 = (unsigned int)stack; //Update the stack pointer
}

//Switch between our two tasks
//Notice how we get the old esp from the ASM code
//It's not a pointer, but we actually get the ESP value
//That way we can save it in our task structure
int TaskSwitch(unsigned int OldEsp){
if(CurrentTask != -1){ //Were we even running a task?
  Threads[CurrentTask].esp0 = OldEsp; //Save the new esp for the thread
 
  //Now switch what task we're on
  if(CurrentTask == 0) CurrentTask = 1;
  else CurrentTask = 0;
} else{
  CurrentTask = 0; //We just started multi-tasking, start with task 0
}
unsigned int a = Threads[CurrentTask].esp0;
   outport(0x20, 0x20);
   // return a;
return OldEsp; //Return new stack pointer to ASM
}


Code:
extern TaskSwitch
extern putdec
global IRQ0
IRQ0:
   pusha
   push ds
   push es
   push fs
   push gs

   mov ax, 0x10
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   push esp
   call TaskSwitch
   
   ;push eax
   ;call putdec
   ;pop eax
   
   mov esp, eax
   
   pop gs
   pop fs
   pop es
   pop ds
   popa
   
   iret


Top
 Profile  
 
 Post subject: Re: Multitasking
PostPosted: Fri Jan 16, 2009 3:14 pm 
Offline
Member
Member

Joined: Tue Dec 09, 2008 12:43 pm
Posts: 63
Got it working finally. thanks guys!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 23 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