Page 2 of 2

Re: Realmode Switch Being Nasty

Posted: Wed Sep 16, 2009 1:33 pm
by ahmedhalawa
Hello every body
i think this problem was happening with me the reason was loading worrning values
let's say your kernel run in first 1mg so when we want to switch to real mode we should
load real mode values

Code: Select all

example to load idt
lidt [ (RealModeIDT - 0x100000) ]
RealModeIDT:
   dw 0x03FF
   dd 0x0000
/*****************/
to run our code just load CS:ip by right values
that was the reason for my code
and mybe there is other reasons

Re: Realmode Switch Being Nasty

Posted: Wed Sep 16, 2009 1:50 pm
by Creature
You are right, I've tried acknowledging the IRQ separately after returning to protected mode, and interrupts are received again. After that, I noticed I had accidently re-enabled interrupts before performing the IRQ (some of the tutorials did it, but I was wondering why, because it isn't needed at all to perform a software interrupt, damn that faulty information).

It's working now ;).

Thanks,
Creature

Re: Realmode Switch Being Nasty

Posted: Wed Sep 16, 2009 3:04 pm
by Brendan
Hi,
Creature wrote:You are right, I've tried acknowledging the IRQ separately after returning to protected mode, and interrupts are received again. After that, I noticed I had accidently re-enabled interrupts before performing the IRQ (some of the tutorials did it, but I was wondering why, because it isn't needed at all to perform a software interrupt, damn that faulty information).

It's working now ;).
Are you sure? There's a difference between "working reliably in all situations" and "working most of the time on one computer".

If some BIOS code is running and carry is clear, and the CPU is about to do "jnc somewhere"; then if an IRQ occurs (making the BIOS execute an unsupported software interrupt handler which sets the carry flag), then how many unpredictable/random crashes could that cause? An average of one crash per 10000 video mode switches? What if the BIOS's software interrupt handler sets "AH = unsupported function"? That'd be a lot worse than just setting the carry flag - maybe an average of one crash per 1000 video mode switches?

What if the BIOS function isn't unsupported? What if, when an IRQ occurs the BIOS executes some random function? Ouch. Don't forget that one day you might want to add support for I/O APICs and MSI (message signalled interrupts) and instead of having 16 potential IRQs (e.g. interrupts 0x20 to 0x2F) you might have 100 of them (e.g. interrupts 0x20 to 0x84); plus maybe some more for multi-CPU IPIs.

Also, what if no IRQ occured while you're in real mode and you send an EOI anyway? For multi-CPU that can cause serious problems because you can't guarantee than a different CPU isn't in the middle of handling an IRQ. What if 10 IRQs occur while you're in real mode? You'd need to send 10 EOIs after you return to protected mode.

So, how do you prevent random undefined behavior (and the other problems)?

You could try to disable interrupts while running BIOS code, but that won't work. In real mode all interrupts are like "interrupt gates" in protected mode - interrupts are disabled automatically be the CPU when the interrupt is started. This means that BIOS code that takes a little time needs to enable interrupts again to avoid IRQs from being missed; so you can expect that good video cards will do "STI" before switching video modes (which does take a relatively long time).

You could try masking all the IRQs in the PIC. That will cause IRQs to be lost. It might not matter in some cases. For e.g. the PIT timer has enough drift that you wouldn't notice if a few lost PIT IRQs cause your OS to lose a few ms per day; and for PCI devices the device will just keep trying until it's IRQ is handled. For other cases (most ISA devices), if the IRQ is lost then that device won't send it's IRQ again, and you're screwed.

The way to do it properly is to install your own IRQ handlers in real mode. For example, if an IRQ does occur while you're in real mode then your IRQ handler will switch back to protected mode and execute the correct protected mode IRQ handler (then switch back to real mode after the protected mode IRQ handler has completed). No lost IRQs, no missed EOIs, no problem for I/O APICs and MSI, and no problem with multi-CPU.


Cheers,

Brendan

Re: Realmode Switch Being Nasty

Posted: Thu Sep 17, 2009 8:14 am
by Creature
Brendan wrote:The way to do it properly is to install your own IRQ handlers in real mode. For example, if an IRQ does occur while you're in real mode then your IRQ handler will switch back to protected mode and execute the correct protected mode IRQ handler (then switch back to real mode after the protected mode IRQ handler has completed). No lost IRQs, no missed EOIs, no problem for I/O APICs and MSI, and no problem with multi-CPU.
This does seem like a good solution, but it also sounds pretty expensive. The whole reason to do BIOS interrupts is to switch back to real mode and then go back to protected mode. But if you were to switch back and forth multiple times inside the switcher itself to handle IRQ's, wouldn't that decrease performance a lot (at the benefit of stability, of course)?

I also meant 'working' as in the emulator and I was about to test it on real hardware today, so I haven't completely tested all cases yet.

Re: Realmode Switch Being Nasty

Posted: Thu Sep 17, 2009 1:19 pm
by Brendan
Hi,
Creature wrote:
Brendan wrote:The way to do it properly is to install your own IRQ handlers in real mode. For example, if an IRQ does occur while you're in real mode then your IRQ handler will switch back to protected mode and execute the correct protected mode IRQ handler (then switch back to real mode after the protected mode IRQ handler has completed). No lost IRQs, no missed EOIs, no problem for I/O APICs and MSI, and no problem with multi-CPU.
This does seem like a good solution, but it also sounds pretty expensive. The whole reason to do BIOS interrupts is to switch back to real mode and then go back to protected mode. But if you were to switch back and forth multiple times inside the switcher itself to handle IRQ's, wouldn't that decrease performance a lot (at the benefit of stability, of course)?
That would depend on how many IRQs occur while you're in real mode, and which part of "performance" matters more. For example, does the performance of a video mode switch (which would be a slower) matter more than the performance of your device drivers (networking, disk I/O, etc; which would be faster with lower IRQ latency)?

The amount of overhead would mainly depend on whether or not your OS uses paging. If you're not using paging then the overhead won't be too bad (maybe around 100 cycles per IRQ, plus the IRQ handler itself). If you are using paging it's a lot worse - each time you switch to real mode (including returning from an IRQ to real mode) you'll flush all of the TLB entries; and you'd end up with lots of TLB misses after returning to protected mode (including when handling an IRQ that occurred in real mode).

Of course you could use the V86 mode instead, which would reduce the overhead in both cases (and completely avoid the "flushing all TLB entries" problem). There's other benefits too - you could recover if the BIOS crashes, and restrict the BIOS so it can only use certain I/O ports and memory areas (and you could use it to create a log of every I/O port access that the video card does while changing video modes, which could make reverse engineering the video card much easier).
Creature wrote:I also meant 'working' as in the emulator and I was about to test it on real hardware today, so I haven't completely tested all cases yet.
For intermittent faults, you could do 1 million tests without crashing and you'll still never know if it will crash or not on the next test (you'd only have a better idea of the probability of a crash). Also, if you are testing to get a better idea of the probability of random behavior then you'd want to do the tests while there's lots of IRQs happening - for example, setup a high speed serial and/or ethernet transfer and do the testing while these devices are causing as many IRQs as possible.


Cheers,

Brendan