Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I call BIOS interrupts from protected mode?

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!

like image 612
Max Avatar asked Apr 26 '11 18:04

Max


2 Answers

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.

like image 196
myron-semack Avatar answered Jan 04 '23 08:01

myron-semack


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.

like image 37
cmarslett Avatar answered Jan 04 '23 08:01

cmarslett