problems about multitasking in diffrent rings
problems about multitasking in diffrent rings
I was trying to multitasking some process in ring3 and ring1. If there's only ring3 processes or ring1 processes, there's nothing at all.
But when I tried to make there's both ring1 and ring3 process, it'll cause a GP error, and the eflags register has turned into 0x96.
The lines causes error is main.c, line 36-37. (I'm pretty sure about that)
P.S.: I used a 64-bit elf toolchain under windows to compile
P.P.S: I tried to put the keyboard driver in ring3 too, but when I press the CapsLock/NumLock/ScrollLock, it gives me another GP
But when I tried to make there's both ring1 and ring3 process, it'll cause a GP error, and the eflags register has turned into 0x96.
The lines causes error is main.c, line 36-37. (I'm pretty sure about that)
P.S.: I used a 64-bit elf toolchain under windows to compile
P.P.S: I tried to put the keyboard driver in ring3 too, but when I press the CapsLock/NumLock/ScrollLock, it gives me another GP
- Attachments
-
- that's what happened when I put my driver in ring3
- SCREENSHOT2.png (4.68 KiB) Viewed 2292 times
-
- merge-os.zip
- here's my code (a bit messy sry)
- (58.15 KiB) Downloaded 120 times
-
- Here's the screenshot
- screenshot.png (4.15 KiB) Viewed 2301 times
Last edited by one737 on Tue Oct 11, 2022 4:41 am, edited 1 time in total.
Re: problems about multitasking in diffrent rings
Where is the irq handler of task scheduling (in whicj file from your project) ? process_start seems fine, it's probably something with your scheduler that is causing a GPF when running a usermode process.
Re: problems about multitasking in diffrent rings
task scheduling's irq handler is the hwint00() in kernel.asm, it turns out to be a wrapper of irq_table[0], and that's the clock_handler() in clock.c (set by init_clock() ). at the end of this function, it calls schedule() to do the actual task schedule.devc1 wrote:Where is the irq handler of task scheduling (in whicj file from your project) ? process_start seems fine, it's probably something with your scheduler that is causing a GPF when running a usermode process.
Re: problems about multitasking in diffrent rings
Code: Select all
%macro hwint_master 1
call save
in al, INT_M_CTLMASK
or al, (1 << %1)
out INT_M_CTLMASK, al
mov al, EOI
out INT_M_CTL, al
sti
push %1
call [irq_table + 4 * %1]
pop ecx
cli
in al, INT_M_CTLMASK
and al, ~(1 << %1)
out INT_M_CTLMASK, al
ret
%endmacro
You should return from an interrupt using the iret instruction to make a context switch and change the code segment, just imagine with me : An interrupt occurs and the current task is in user mode, the CPU switches to kernel mode and executes the ISR, it saves the previous EIP and the code segment along with other segments in the stack frame.
But an interrupt doesn't just push EIP : Instead it pushes EIP, CS, EFLAGS, ESP, SS.
You should use iret to context switch to user mode and set CS with the right segment.
I wrote an example in the forum of the "WinExperiment" guy who asked about a syscall problem.
You can find it here : viewtopic.php?f=1&t=56515&start=15
Note that this is a task scheduler ISR and you are not required to use the same mechanism with other ISRs.
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: problems about multitasking in diffrent rings
It's kernel.asm line 166. Looks like something is corrupting your stack.one737 wrote:The lines causes error is main.c, line 36-37. (I'm pretty sure about that)
Do you have one ring 0 stack per thread? If you do, your interrupt handling code is much more complicated than it needs to be.
Re: problems about multitasking in diffrent rings
In the save() function, I saved [esp] as restart (if interrupt reenter occured, then restart_reenter), and it finally calls iretd, then it'll goes like what you said.devc1 wrote: This is what gets called ?
You should return from an interrupt using the iret instruction to make a context switch and change the code segment, just imagine with me : An interrupt occurs and the current task is in user mode, the CPU switches to kernel mode and executes the ISR, it saves the previous EIP and the code segment along with other segments in the stack frame.
Re: problems about multitasking in diffrent rings
If there's only ring1 or ring3 processes, everything's ok, so I don't think is a stack problem.Octocontrabass wrote:Do you have one ring 0 stack per thread? If you do, your interrupt handling code is much more complicated than it needs to be.
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: problems about multitasking in diffrent rings
The instruction in kernel.asm at line 166 is "pop fs". It's a stack problem.one737 wrote:I don't think is a stack problem.
Re: problems about multitasking in diffrent rings
So why there's totally nothing happened while only ring1/ring3?
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: problems about multitasking in diffrent rings
You'll have to use a debugger to figure that out. Your code to manipulate the stack doesn't make sense to me.
Re: problems about multitasking in diffrent rings
But do you and how you save previous task's CS, EFLAGS, ESP and SS ?In the save() function, I saved [esp] as restart (if interrupt reenter occured, then restart_reenter), and it finally calls iretd, then it'll goes like what you said.
Re: problems about multitasking in diffrent rings
They're in the STACK_FRAME structure in the PCB (struct PROCESS).devc1 wrote:But do you and how you save previous task's CS, EFLAGS, ESP and SS ?
Re: problems about multitasking in diffrent rings
Good.
Now how do you build the stack frame before returning with iretd ?
You're doing it inside the function called with call instruction right ?
Intel manual : The call instruction sets the Nested Task flag(NT). Iret will generate a #GPF if the NT Flag is set. You must iret outside a function, it is not recommended to fix it by clearing the NT Flag manually though,
Now how do you build the stack frame before returning with iretd ?
You're doing it inside the function called with call instruction right ?
Intel manual : The call instruction sets the Nested Task flag(NT). Iret will generate a #GPF if the NT Flag is set. You must iret outside a function, it is not recommended to fix it by clearing the NT Flag manually though,
Re: problems about multitasking in diffrent rings
After fill in the PCBs, I call the restart(), it left the stack exactly with the eip, cs, eflags, esp and ss, then I use the iretd to enter into the process.devc1 wrote:How do you build the stack frame before returning with iretd ?
Last edited by one737 on Fri Oct 14, 2022 6:48 pm, edited 1 time in total.
Re: problems about multitasking in diffrent rings
I checked my code, and found out that I do allocated an unique stack to every process.Octocontrabass wrote:You'll have to use a debugger to figure that out. Your code to manipulate the stack doesn't make sense to me.