Right. I've spent over three hours today trying to understand why you can't call a bios ISR when in protected mode. I get that once you set and IDT it wont necessarily be in the usual address for the IVT plus segments dont have a fixed size in Protected mode, etc.. But I still don't get why can't you jsut create a single 4GB segment, map your IDT segments to the BIOS IVT, set everything in ring 0 and call them. Shouldn't that work?
Most articles either say: "Remember you cant use BIOS interrupts in protected mode!" without exploring the subject or are extremely descriptive and cite traps, exceptions, pics remmaping, lack of rights and problems with segment registers as the reason behind it.
It would be extremely helpful if someone could come up with a more human-friendly explanation... I'm not doubting what the articles say, I just want to understand why it is such a 'pain'!
Thanks in advance!
I think the biggest problem is that the BIOS routines were written assuming the processor is in real mode. If you call them from an unsupported context, you can't be sure the BIOS routines will behave as expected. They could fail on their own, or they could mess up the processor state and kick you out of protected mode.
Max, you could possibly create the device driver running in ring 0 that calls a simpler BIOS ISR, if the OS is running in 16-bit protected mode. But in 32-bit mode, the first 16- or 32-bit address offset or immediate value would be interpreted incorrectly and the instruction stream would get out of sync. In real or 16-bit protected mode, the immediate and offset values are by default 16 bits long, in 32-bit protected mode they are 32 bits long, and in 64-bit (long) mode, they are either 32 or 64 bits long. So only offsets represented as bytes (< 128, if I remember correctly) and byte immediate values can be used in the ISR.
Further, any segment register load (other than zero) will behave differently in real mode than it does in any protected mode. Again, the real mode code and the protected mode code can work together to make it possible to write code that works, but it is not at all easy.
For example,`
mov ah, 0B8h
mov al, 000h
mov es, ax
mov byte ptr es:0, 'o'
mov byte ptr es:2, 'k'`
will put the letters 'ok' in the upper left corner of a text mode screen in real mode, but to have that work in 16-bit or 32-bit protected mode, a global descriptor table entry at offset 0xB800 has to have a base address of 0x000B8000.
But if you are satisfied with running only in 16-bit protected mode the more common code:`
mov ax, 0B800h
mov es, ax
mov dword ptr es:0, 0076b076fh`
should work just as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With