OSDev.org https://forum.osdev.org/ |
|
Multitasking https://forum.osdev.org/viewtopic.php?f=1&t=18842 |
Page 1 of 1 |
Author: | eXeCuTeR [ Fri Jan 09, 2009 10:04 am ] |
Post subject: | Multitasking |
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 } |
Author: | Combuster [ Fri Jan 09, 2009 11:20 am ] |
Post subject: | Re: Multitasking |
Try tracking your stackpointer, its broken: Quote: ESP=ffffffff Bochs debugger can help you with that |
Author: | eXeCuTeR [ Mon Jan 12, 2009 1:15 pm ] |
Post subject: | Re: Multitasking |
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? |
Author: | cyr1x [ Mon Jan 12, 2009 1:52 pm ] |
Post subject: | Re: Multitasking |
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. |
Author: | eXeCuTeR [ Mon Jan 12, 2009 2:19 pm ] |
Post subject: | Re: Multitasking |
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? |
Author: | djsilence [ Tue Jan 13, 2009 7:54 am ] |
Post subject: | Re: Multitasking |
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. |
Author: | giszo [ Tue Jan 13, 2009 8:15 am ] |
Post subject: | Re: Multitasking |
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 |
Author: | eXeCuTeR [ Tue Jan 13, 2009 3:23 pm ] |
Post subject: | Re: Multitasking |
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 |
Author: | JohnnyTheDon [ Tue Jan 13, 2009 3:49 pm ] |
Post subject: | Re: Multitasking |
Quote: --enable-instrumentation Don't think you need this, I don't use it and my debugger runs fine. |
Author: | eXeCuTeR [ Wed Jan 14, 2009 11:46 am ] |
Post subject: | Re: Multitasking |
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 |
Author: | Combuster [ Wed Jan 14, 2009 1:55 pm ] |
Post subject: | Re: Multitasking |
Quote: CR3=0x00000000 is this valid with paging enabled?
|
Author: | eXeCuTeR [ Wed Jan 14, 2009 3:04 pm ] |
Post subject: | Re: Multitasking |
Combuster wrote: Quote: CR3=0x00000000 is this valid with paging enabled?Everything is just messed up somehow, that's totally weird. |
Author: | eXeCuTeR [ Thu Jan 15, 2009 3:31 pm ] |
Post subject: | Re: Multitasking |
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 |
Author: | eXeCuTeR [ Fri Jan 16, 2009 3:14 pm ] |
Post subject: | Re: Multitasking |
Got it working finally. thanks guys! |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |