Context switch disabling interrupts
Posted: Wed May 06, 2009 12:32 am
Hi,
I'm quite a newbie to OS programming, and tried to get a context switch (on x86) to work. My "context switch" (for now) works like this:
1. Push EIP and EBP to the (current) stack.
2. Save the current ESP in the current process's structure
3. Load the ESP of the context to switch to from that process's structure
4. Pop EBP & EIP from the stack (we just switched to)
5. jmp to the EIP just popped
Since I don't have any "userspace" yet, I don't have to mess with changing segments or the TSS (at least I think so). Now my problem is: After the first context switch, my interrupts just stop firing. The Interrupt Enable flag is still set, the timer interrupt is not being masked out, the IDT has not been overwritten...
From what I found by searching, I think that "usually", iret is used to perform context switches - is that correct? Is that perhaps the flaw? In the Sections of the Intel Developer's Manual that I read they were only talking about using iret for returning from procedures, so I think this is nothing more than a shortcut for popping certain values from the stack and restoring these registers - or are there any sideeffects in using iret instead of unsing pop and moving the stuff into the registers by hand?
Or do I perhaps have to restore anything beyond ESP, EBP and EIP? I mean, of course I know that there is a lot more to do, like CR3, Segments, TSS, etc., but since I'm not switching between user- and kernelspace, or even different "processes" (everything runs directly within the kernel), Paging, Segments and the TSS should not have to change, right?
I mean, it could very well be that I trash some stack or whatever by context switching (as I said, I'm quite new to OS and *that* low-level programming, and I messed a lot with that code lately to get it running...), but then at least the interrupts should fire (and produce some page fault or whatever).
I'm quite a newbie to OS programming, and tried to get a context switch (on x86) to work. My "context switch" (for now) works like this:
1. Push EIP and EBP to the (current) stack.
2. Save the current ESP in the current process's structure
3. Load the ESP of the context to switch to from that process's structure
4. Pop EBP & EIP from the stack (we just switched to)
5. jmp to the EIP just popped
Since I don't have any "userspace" yet, I don't have to mess with changing segments or the TSS (at least I think so). Now my problem is: After the first context switch, my interrupts just stop firing. The Interrupt Enable flag is still set, the timer interrupt is not being masked out, the IDT has not been overwritten...
From what I found by searching, I think that "usually", iret is used to perform context switches - is that correct? Is that perhaps the flaw? In the Sections of the Intel Developer's Manual that I read they were only talking about using iret for returning from procedures, so I think this is nothing more than a shortcut for popping certain values from the stack and restoring these registers - or are there any sideeffects in using iret instead of unsing pop and moving the stuff into the registers by hand?
Or do I perhaps have to restore anything beyond ESP, EBP and EIP? I mean, of course I know that there is a lot more to do, like CR3, Segments, TSS, etc., but since I'm not switching between user- and kernelspace, or even different "processes" (everything runs directly within the kernel), Paging, Segments and the TSS should not have to change, right?
I mean, it could very well be that I trash some stack or whatever by context switching (as I said, I'm quite new to OS and *that* low-level programming, and I messed a lot with that code lately to get it running...), but then at least the interrupts should fire (and produce some page fault or whatever).