OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 8:22 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 59 posts ]  Go to page Previous  1, 2, 3, 4
Author Message
 Post subject: Re: Multitasking problem
PostPosted: Sat Aug 06, 2022 4:14 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
Here's one way to do it:

Code:
uint32_t phys_addr = pte & ~0xFFF;


You'll have a hard time writing an OS if you're not already familiar with this sort of thing.


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Thu Sep 01, 2022 5:23 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Hello, again!
I have problem with implementing child waiting, after i run program twice, first run works but state of parent are always are "running", but second process after exit, throws to me the #PF, what is reason?
Here how i implement the process waiting:
Code:
if (runningTask->pid == 0 || pid < 0) return;
   if (!process_getProcess(pid)) {
       printf("process_wait: no such process %d, system halted\n",pid);
       return;
   }
   struct process *p = process_getProcess(pid);
   p->state = 2;
   // update pointer
   process_yield();

process_exit:
Code:
void process_exit(int pid,int exitCode) {
   process_getProcess(pid)->state = 1;
}

process_getProcess:
Code:
struct process *process_getProcess(int pid) {
   return process_findID(pid);
}

process_findID:
Code:
struct process *process_findID(int id) {
   clist_head_t *c = clist_find(task_list,process_findIdDispatcher,id);
   if (c) {
      return (struct process *)c->data;
   }
   return NULL;
}

And finally, the schedule function:
Code:
// send end of interrupt to interrupt controller
   io_writePort(PIC_SLAVE_COMMAND , 0x20);
   io_writePort(PIC_MASTER_COMMAND , 0x20);
   struct process *next_task = NULL;
   // update clocks
   clocks++;
   // don't save context on first switch
   if (!fswitch || runningTask->state == PROCESS_RUNNING) {
      runningTask->esp = stack;
   }
   if (!fswitch) {
      if (!runningTask) {
         next_task = process_findByStatus(PROCESS_RUNNING);
      } else {
         next_task = process_findNextByStatus(PROCESS_RUNNING,runningTask->lAddr);
      }
   }
   if (next_task == NULL) {
      // first switch
      next_task = process_findByStatus(PROCESS_RUNNING);
   }
   if (next_task == NULL) {
      printf("Next task null\n");
      return stack;
   }
   if (runningTask->state == PROCESS_KILLING) {
      if (runningTask->parent != 0) { // idle task hasn't waiting for any pid
         struct process *parent = process_findID(runningTask->parent);
         if (parent->state != PROCESS_WAIPID) {
            printf("Cannot unlock parent: Parent didn't waiting for any child PID: %d\n",runningTask->pid);
         } else {
            parent->state = PROCESS_RUNNING;
            fswitch = true;
            return  idle->esp;
         }
         curTasks--;
         arch_destroyStack(runningTask->esp);
         pmml_free(runningTask->esp);
         pmml_free((void *)runningTask->dir);
         if (runningTask->kernelESP != 0) {
            pmml_free((void *)runningTask->kernelESP);
         }
         if (runningTask->page_start != 0) {
            pmml_freePages((void *)runningTask->page_start,runningTask->pages);
         }
         clist_delete_entry(task_list,(clist_head_t *)runningTask->lAddr);
         pmml_free(runningTask);
      }
   }
   if (next_task->wait_time != 0) {
      next_task->wait_time--;
      fswitch = true;
      return stack;
   }
   tss_set_stack(0x10,next_task->kernelESP);
   vmm_switch((int *)next_task->dir);
   fswitch = false;
   runningTask = next_task;
   return runningTask->esp;
}

Screenshot of error in attachments.
EDIT: I fixed #PF, but now i have #GP with error code 1, i just replace process_yield code to waiting for next interrupt, also i fixed the "ready" state bug
UPDATE 2: I fixed the #GP, but now tasks always points to idle, maybe problem in context saving in process_schedule?


Attachments:
QEMU 01.09.2022 14_20_27.png
QEMU 01.09.2022 14_20_27.png [ 10.39 KiB | Viewed 969 times ]
Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Sat Sep 03, 2022 9:31 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Hello!
And first about previous post, after this post i edited my scheduler method and add context save/switch.
And i have some problem: when i receive keyboard interrupt, the handler correctly returns to the process wait key function, but if this function returns(it's must return key if it pressed) it's jumps to 0x0000010 why?


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Sat Sep 03, 2022 10:28 am 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
WinExperements wrote:
but if this function returns(it's must return key if it pressed) it's jumps to 0x0000010 why?


It jumps to 0x10 because that's the "last" thing that was stored on the stack. Inspect it to make sure it's not corrupted.

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Oct 05, 2022 1:14 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Hello again! How i can add switching to user mode for user's tasks using Brendan's multitasking tutorial?


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Oct 05, 2022 1:24 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
When you initialize the task, fill the stack with values that will make the task return to ring 3 when you switch to it.


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Oct 05, 2022 1:51 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Octocontrabass wrote:
When you initialize the task, fill the stack with values that will make the task return to ring 3 when you switch to it.

How i can fill correctly it, because i fill it with some parameters to my user startup function, that switches to user mode and jumps to the entry point, but after the restoring it from the saved state, it's switches to kernel mode. Do i need to change my switch function?


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Oct 05, 2022 2:01 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
Task switches only happen in ring 0. If the task itself is meant to run in ring 3, then the saved/restored state should be inside an IRQ or syscall handler that will eventually return to ring 3.

If that's not happening, something is wrong with how you're switching tasks.


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Oct 05, 2022 2:11 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Octocontrabass wrote:
Task switches only happen in ring 0. If the task itself is meant to run in ring 3, then the saved/restored state should be inside an IRQ or syscall handler that will eventually return to ring 3.

As I understand it, the context switch should be called in an IRQ or system call that will return to ring 3? Or what?


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Oct 05, 2022 2:29 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
A ring 3 task can only get to ring 0 by a syscall or an IRQ, so a ring 3 task can only call the context switch in a syscall or IRQ handler.

When some other task calls the context switch, the ring 3 task will resume in ring 0 in the syscall or IRQ handler.


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Oct 05, 2022 2:49 pm 
Offline
Member
Member

Joined: Fri Feb 11, 2022 4:55 am
Posts: 435
Location: behind the keyboard
To switch to a user mode task from an IRQ you simply must save and restore the page table and segment registers CS, DS, SS, ES, GS, FS. When you select your task you must build a stack frame then "iret" and congrats, you have made it to user mode.

This must happen when CPL=0 (kernel mode), probably inside an IRQ handler.


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Thu Oct 06, 2022 6:36 am 
Offline
Member
Member

Joined: Sat Nov 21, 2009 5:11 pm
Posts: 852
There is a type of design called a single stack kernel, sometimes used for microkernels. In this case, the task switching code operates on the interrupt return frame. This is not by definition "wrong", but comes with its own set of challenges. On the plus side, it saves memory. There is a version of the L4 Pistachio kernel that does this, as does the Playstation 1 BIOS. Most kernels uses a separate stack for each thread, and task switching only involves switching stacks and saving and loading a few registers.


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Oct 12, 2022 6:16 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Hello! I am have again problem, that my keyboard wait key function returns to 0x10. How i can correctly save the ESP for tasks?
Here the saving code:
Code:
void arch_saveContext(struct process *forWho,registers_t *stack) {
    registers_t *f = (registers_t *)forWho->esp;
    f->eax = stack->eax;
    f->ecx = stack->ecx;
    f->edx = stack->edx;
    f->ebx = stack->ebx;
    f->ebp = stack->ebp;
    f->esi = stack->esi;
    f->edi = stack->edi;
    f->eip = stack->eip;
    f->eflags = stack->eflags;
    f->useresp = stack->useresp;
}

My context switching function used iret instruction and useresp field to switch to task, before it i only loads register values from the registers_t structure.


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Oct 12, 2022 11:33 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
I already gave you an example of how to perform a context switch in another thread. The code simultaneously saves the current task's ring 0 stack pointer to the provided location and sets ESP to the new task's ring 0 stack pointer.

When you have one ring 0 stack per thread, you don't need to save or restore anything except the ring 0 stack pointer.


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

All times are UTC - 6 hours


Who is online

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