Im working on the multitasking in my kernel. If I understand correctly the manuals that I didn't really understand, I need an LDT for my process data & code. Important that my code has a descriptor, that's the way the processor know when to stop, sending (an interrupt? an exception? Im guessing an exception since interrupt are for hardware) to my kernel so it know to stop the process before it goes out of instructions?
Right now I don't have any LDT. My process is just an infinite loop counting and printing on screen, but I can't control what my future users will gives my kernel as code and say them to put loop in the end because the kernel can't handle it otherwise.
So, do I need something to say the limit of the code to the processor and does it gives an exception when it reach said limit? Because the code I saw in bonafide doesn't mention that.
What happens when the process hit the end?
- jerryleecooper
- Member
- Posts: 233
- Joined: Mon Aug 06, 2007 6:32 pm
- Location: Canada
- jerryleecooper
- Member
- Posts: 233
- Joined: Mon Aug 06, 2007 6:32 pm
- Location: Canada
I forgot to add, each program is supposed to end with a "ret" instruction? and programs not terminating by it generating a GPF exception?
Im reading the intel manual right now. It says that when it's tranfering from a code segment, transfering execution from a code segment that is, to another segment, it generate one. So that's the exception I was after, but what about the LDT?
Im reading the intel manual right now. It says that when it's tranfering from a code segment, transfering execution from a code segment that is, to another segment, it generate one. So that's the exception I was after, but what about the LDT?
-
- Member
- Posts: 2566
- Joined: Sun Jan 14, 2007 9:15 pm
- Libera.chat IRC: miselin
- Location: Sydney, Australia (I come from a land down under!)
- Contact:
"ret" pops a CS:EIP pair off the stack.
Usually you have an "exit" syscall that kills the process that calls it (hence that call never returns - even so, usually you would want a "jmp $" after it).
Usually you have an "exit" syscall that kills the process that calls it (hence that call never returns - even so, usually you would want a "jmp $" after it).
No, the descriptor is just a segment descriptor, its purpose is for privilege checking and the protection features of the processor. It'll just keep executing any code you give it until it hits a dud instruction (or worse) and then you'll fault. This is not a recommended way of ending a task .Important that my code has a descriptor, that's the way the processor know when to stop, sending (an interrupt? an exception? Im guessing an exception since interrupt are for hardware) to my kernel so it know to stop the process before it goes out of instructions?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
No. Everything you can put in an LDT can also be put in the GDT. Most people have one pair of userland code/data selectors in there.If I understand correctly the manuals that I didn't really understand, I need an LDT for my process data & code.
Many kernels use a system call to indicate the end of a process. That way you can stop a program without having to bother about specific code layouts or using special instructions to finish the job.Im guessing an exception since interrupt are for hardware) to my kernel so it know to stop the process before it goes out of instructions?
What happens under the hood is that there is a bit of runtime present that calls main. Consider:each program is supposed to end with a "ret" instruction?
Code: Select all
_start: call _getarguments
mov eax, [_argv]
push eax
mov eax, [_argc]
push eax
call main
add esp, 8
call _exitprocess
RET does not pop CS, only the instruction pointer. You'll need a far return to load CS as well."ret" pops a CS:EIP pair off the stack.
-
- Member
- Posts: 2566
- Joined: Sun Jan 14, 2007 9:15 pm
- Libera.chat IRC: miselin
- Location: Sydney, Australia (I come from a land down under!)
- Contact:
Oops, forgot that in early versions of my kernel (where returns led to a 'die' function) all I had was threads, all of which were in the same code segment and the same address space. That early version still pushed a CS:EIP pair to the stack for the 'die' function and I never thought to remove the CS.Combuster wrote:RET does not pop CS, only the instruction pointer. You'll need a far return to load CS as well."ret" pops a CS:EIP pair off the stack.
My bad
You dont need an ldt unless you was going to use segmentation to separate each process's address space.
You need to have a code and data descriptor in your gdt for both ring 0 and ring 3 (unless you only use ring 0) and if you use a flat model those will not change.
If you have already thrown in a system timer interrupt routine that switches your tasks, then making another isr to end your tasks should not be a problem (that or make a call gate that links to similar code).
Basically when the process wants to "do suicide" it needs to use the interrupt or call gate you created and your os will remove that process from the list of running processes and release frames allocated to it (if you have got that far). You can also make a similar interrupt or call gate that creates new processes using similar code.
Remember your processes cannot do anything unless you provide the interrupts or/and call gates to do it with.
You should make some header files that basically call these interrupts/call gates using inline asm or external asm so your c program can call KillMe() which may be a simple asm routine that does int ## and terminates your process.
You need to have a code and data descriptor in your gdt for both ring 0 and ring 3 (unless you only use ring 0) and if you use a flat model those will not change.
If you have already thrown in a system timer interrupt routine that switches your tasks, then making another isr to end your tasks should not be a problem (that or make a call gate that links to similar code).
Basically when the process wants to "do suicide" it needs to use the interrupt or call gate you created and your os will remove that process from the list of running processes and release frames allocated to it (if you have got that far). You can also make a similar interrupt or call gate that creates new processes using similar code.
Remember your processes cannot do anything unless you provide the interrupts or/and call gates to do it with.
You should make some header files that basically call these interrupts/call gates using inline asm or external asm so your c program can call KillMe() which may be a simple asm routine that does int ## and terminates your process.