Hi this is my first post at Osdev.org
I've been developing an operating system for the past three months as a hobby. My initial plan was to develop a 32 bit protected mode and following some research i found that if I did so I would not be able to use BIOS interrupts. I wondered why but most answers were quite brief and meaningless ("because real mode and protected mode address memory in different ways", "because God said so", etc...) so I started learning about how protected mode works. After a week of researching I'm yet struggling to understand why using BIOS interrupts is such a no-no!?
If I got it right, in Protected mode you use an IDT rather than the IVT and the IDT can be placed anywhere in memory. OK... But couldn't we map the IDT to the usual BIOS IVT address? In protected mode you dont deal with segments but segment descriptors so when you put an address on the segment register it doesnt point to the register but rather to an entry in the Segment Descriptor which than points to a segment right? Plus registers are 32 bit and not 16 bit... OK... But i guess one could still map the IDT and GDT entries so that should you make a call to int 13h it loads the IDT entry that points to the GDT entry which points to the address of the BIOS int 13h ISR, or would that not be possible? Why can't one use 16-bit protected mode then?
I've asked a similar question in stack overflow and was told it wasnt possible due to the different levels implemented by protected mode so apps cant call BIOS code because they are sitting in different rings. Well.. Not if you have everything in ring 0! Or if you create system calls that then make calls to the appropriate BIOS functions (whose addresses will be marked as kernel level code)
I guess all I'm asking is for a descent explanation as to why this is not possible. 'No, it's not only very hard and stupid to implement. It is IMPOSSIBLE because of such and so!' is what I'm looking for
I heard of vmem mode and all that but I wonder what does make protected mode (be it 16 or 32 bit) and BIOS ISRs definitely incompatible!
Thanks in advance!
Using BIOS interrupts in protected mode. Is it impossible??
- 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:
Re: Using BIOS interrupts in protected mode. Is it impossibl
-1 for asking this in two distinct threads.
No you can't run the average real-mode code in protected mode, because the address translation schemes are different and incompatible. Real mode uses the value in a segment register as the base, while protected mode uses a subset of that register as an index into the GDT. Since several values for a segment register point to the same table entry it is impossible to emulate real-mode addressing where every value has distinct offsets. If you need to run real-mode code, use real mode, Virtual 8086 mode (or any other form of VM) or emulation.
Apart from the technical part, the bios expects total control over the system, and expects the system to be the way it originally set it up. If you do anything to disturb that, you break the specifications of the BIOS and it might stop working even if you do execute the code properly. The moment you have a driver touch the hardware directly, the BIOS is to be considered off-limits. (The video bios is a different story however. Since the card must fit in any computer, the video bios should not depend on other system resources. That means if you don't poke the video hardware beyond its normal use, you should still be able to use int 0x10, just not in protected mode)
No you can't run the average real-mode code in protected mode, because the address translation schemes are different and incompatible. Real mode uses the value in a segment register as the base, while protected mode uses a subset of that register as an index into the GDT. Since several values for a segment register point to the same table entry it is impossible to emulate real-mode addressing where every value has distinct offsets. If you need to run real-mode code, use real mode, Virtual 8086 mode (or any other form of VM) or emulation.
Apart from the technical part, the bios expects total control over the system, and expects the system to be the way it originally set it up. If you do anything to disturb that, you break the specifications of the BIOS and it might stop working even if you do execute the code properly. The moment you have a driver touch the hardware directly, the BIOS is to be considered off-limits. (The video bios is a different story however. Since the card must fit in any computer, the video bios should not depend on other system resources. That means if you don't poke the video hardware beyond its normal use, you should still be able to use int 0x10, just not in protected mode)
Re: Using BIOS interrupts in protected mode. Is it impossibl
Thanks for your explanation Combuster, it was very helpful. I think I got the gist of it now!
I guess even if by miracle the IDT and GDT were configured to a point all interrupts reached the appropriate BIOS ISRs those functions would still map memory in the segment:offset model so regardless of priviledge level as soon as the ISR code attempts to access a memory location the GDT will be consulted and it will either generate an exception or jump to some random address in memory!
Cheers!
I guess even if by miracle the IDT and GDT were configured to a point all interrupts reached the appropriate BIOS ISRs those functions would still map memory in the segment:offset model so regardless of priviledge level as soon as the ISR code attempts to access a memory location the GDT will be consulted and it will either generate an exception or jump to some random address in memory!
Cheers!
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Re: Using BIOS interrupts in protected mode. Is it impossibl
IIRC, the opcodes for protected mode an real mode code are also slightly different (I believe it has to do with the size of immediate operands.)
Re: Using BIOS interrupts in protected mode. Is it impossibl
No, that has to do with the default operand size, not with real-address mode versus protected mode, although you have to be operating in protected mode to change it.
It would be possible to have all segment descriptors as invalid except a few that you know the BIOS won't use, and trap all segment register loads with the GPF handler. However, there would be a problem with reading the segment values back. There is no way for the GPF handler to ensure that the same value is read back from the segment register that was written to it. For example, consider a far jump to a segment divisible by 4. Afterwards, CS will have to contain a value divisible by 4, still having CPL different from 0 so that exceptions cause stack switches, so that ESP is predictable and can be used to determine if the source of exceptions 8 through 15 is a processor exception or an external interrupt. But to do this you have to enter real-address mode, change the segment register and enter protected mode again, which you can't because CPL isn't 0. So, this wouldn't work out very well. I think you'd do yourself a favour by using Virtual 8086 mode or hypervisor extensions.
It would be possible to have all segment descriptors as invalid except a few that you know the BIOS won't use, and trap all segment register loads with the GPF handler. However, there would be a problem with reading the segment values back. There is no way for the GPF handler to ensure that the same value is read back from the segment register that was written to it. For example, consider a far jump to a segment divisible by 4. Afterwards, CS will have to contain a value divisible by 4, still having CPL different from 0 so that exceptions cause stack switches, so that ESP is predictable and can be used to determine if the source of exceptions 8 through 15 is a processor exception or an external interrupt. But to do this you have to enter real-address mode, change the segment register and enter protected mode again, which you can't because CPL isn't 0. So, this wouldn't work out very well. I think you'd do yourself a favour by using Virtual 8086 mode or hypervisor extensions.