Good way to end a beginning process.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
stonedzealot

Good way to end a beginning process.

Post by stonedzealot »

My OS can handle jumping a new task but it can't handle one dying. Right now, I'm essentially injecting the assembly code with a pointer and the first process I created was just CD21F4 (interrupt 33, hlt) so I made a pointer to the new page (temp) and set

Code: Select all

temp[0] = 0xF421CD;
When the scheduler decides to switch from the kernel to the task, I get the interrupt 33 call, it prints a message, but then refuses to halt on return. If I remove the message from the interrupt, it will just return from the interrupt and continue to execute until it crosses the page barrier and gives a page fault. If the message is retained within the interrupt, then it does some really weird **** when it hits the instruction after the hlt (which it should never do anyway). So why isn't it halting at the hlt, or how should I loop the process at the end, since I can't handle one dying yet (and won't, until I make sure that I can sustain them)?
mystran

Re:Good way to end a beginning process.

Post by mystran »

If this is usermode task, then remember that halt cannot be used in ring3 and IIRC trying to do so results in general protection fault.
Ytinasni

Re:Good way to end a beginning process.

Post by Ytinasni »

The HLT instruction waits for one interrupt to occur, then continues.
stonedzealot

Re:Good way to end a beginning process.

Post by stonedzealot »

I'll be damned, I didn't know that. I should've guessed. Anyway, I've been trying to avoid the HLT instruction now by looping so I wrote this little NASM program:

Code: Select all

[BITS 32]
[ORG 0x800000] <-- That's the address we're running from.
   int 33
   jmp 0x800000

and it generates CD 21 E9 F9 FF FF FF which I insert like this:

Code: Select all

temp = (int *) 0x800000;
temp[0] = 0xF9E921CD; 
temp[1] = 0xFFFFFF;
and when I execute it goes totally haywire (still fires the interrupt all right, but doesn't loop correctly or something). So what would a better loop strategy be? Or, at least, what am I doing wrong?
mystran

Re:Good way to end a beginning process.

Post by mystran »

Ok, so you have a relative jump here with 32-bit offset, which makes little sense since 8 bit offset would do just as well. But other than that, it _seems_ ok.

Anyway, are you sure you return everything into such a state that the interrupt can be safely fired again? I find it quite likely that the problem is somewhere else.

Anyway, I'd try to find a way to include your assembler generated code directly into your kernel. One option is to simply put a label before and after the asm-code (maybe compile it into .data section?) then link it normally, and use the labels to find it and copy it where you want it. That way you avoid manually typing bytes.
Dreamsmith

Re:Good way to end a beginning process.

Post by Dreamsmith »

If you meant to simply loop in place rather than call INT 33 over and over and over again, you might want to use:

Code: Select all

    jmp $
...which assembles as EB FE. Add the INT instruction (CD 21) so you get *temp = 0xFEEB21CD, a lovely little 4 byte program. ;D
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Good way to end a beginning process.

Post by Candy »

Dreamsmith wrote: If you meant to simply loop in place rather than call INT 33 over and over and over again, you might want to use:

Code: Select all

    jmp $
...which assembles as EB FE. Add the INT instruction (CD 21) so you get *temp = 0xFEEB21CD, a lovely little 4 byte program. ;D
If you do want to call the function again, adjust the 1-byte offset two backwards, to EB FC. Giving:

*temp = 0xFCEB21CD

for the same result, but in less code...

Are we optimizing a 7-byte program to a 4-byte program now? What's gotten into us? The point was that it didn't work...

My personal guess is that you wreck the stack in some way, or don't realise that your program is in fact doing as it should (might not apply, but I have seen numerous people doing that).
Dreamsmith

Re:Good way to end a beginning process.

Post by Dreamsmith »

Candy wrote:Are we optimizing a 7-byte program to a 4-byte program now? What's gotten into us? The point was that it didn't work...
Heh. Well, I thought the problem might be he wasn't expecting a continuous stream of INT 33's -- the fact that the code could also be optimized was supposed to be secondary.

I'm sure the fact that I'm obsessive-compulsive about wasted RAM has nothing to do with it... ;) [You try squeezing useful programs into 64K of address space for a few years, see how your sanity stands up...]
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:Good way to end a beginning process.

Post by Colonel Kernel »

Maybe I'm missing something here, but why is it necessary to modify the instruction stream just to kill a process? Why not implement a system call for this purpose? The process makes the system call, the kernel gets control and realizes that it shouldn't schedule that process any more, cleans it up, and it never runs again... Your user-mode run-time library should be responsible for making the call after "main" (or its equivalent) returns.
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
stonedzealot

Re:Good way to end a beginning process.

Post by stonedzealot »

Sure, that'd be ideal, but right now I want to focus on the scheduler and making sure that's in usable condition before I worry about process death.
Post Reply