Page 1 of 1
real mode interrupts in protected mode?
Posted: Tue Aug 07, 2007 12:34 pm
by sancho1980
hi
i just had this idea, dont even know if its good/new/possible, but id like to know what you think:
would it be possible to write a kernel that, instead of switching to pm after installing its own interrupt handlers, simply translates the real mode bios interrupts from 16 into 32 bit procedures and then rehooks them before turning on pm? i know this is probably not a solution for a real world 32 bit pm operating system, but mightnt it be useful for a bootloader?
Posted: Tue Aug 07, 2007 5:19 pm
by LaurensR1983
You should look into virtual 8086 mode (aka v86). It's a way to call interrupts in protected mode.
I'm still pretty new to this stuff myself, but I do know that making realmode calls/interrupts in PM is pretty slow.
Posted: Wed Aug 08, 2007 2:08 am
by sancho1980
but thats not what im talking about:
i mean a kernel that takes a look at the real mode interrupt procedure, translates them into 32 bit protected mode instructions and then rehooks them in protected mode...that way you wouldnt have to worry about the hardware, you just cheat from the bios
Posted: Wed Aug 08, 2007 5:17 am
by LaurensR1983
ok, I now see what you mean.
In that case I can't help you... not enough experience on that field (yet
)
Instead of wondering if it's possible and/or usefull, why don't you try to make a prototype/research project? Just to see if it works! And if you succeed you can show it off and we can all be amazed by your work
(worshipping and all that stuff)
Posted: Wed Aug 08, 2007 7:58 am
by Brendan
Hi,
It is possible - it'd be just like writing a compiler, except the "source code" is binary instead of ASCII. It'd be a huge amount of work to make sure it works correctly in all cases (but it's possible).
The main problem is that the BIOS functions are crappy single-threaded functions designed 30 years ago that are hacked together with lots of crud for backwards compatability, that happen to run in real mode. After a lot of work, the best you could hope for is crappy single-threaded functions designed 30 years ago that are hacked together with lots of crud for backwards compatability, that happen to run in protected mode. It's not a big improvement IMHO....
Cheers,
Brendan
Posted: Wed Aug 08, 2007 8:17 am
by JamesM
Hi,
I work for a company called Transitive
http://www.transitive.com. We make Dynamic Binary Translators (we made Rosetta for the intel macs), and this is exactly what you are trying to do here. Unfortunately translating something like that isn't quite so simple, and here's one reason why.
In x86, an instruction can jump to
any other instruction. That is, you can have a register containing a jump position and then jump to it.
I'm not too hot with the actual x86 opcodes, so I'm going to assume that every 32bit instruction is the same size as it's 16bit counterpart, except when immediate values or addesses are specified, where they are 2 bytes bigger (32bit addresses instead of 16bit). This is not exactly correct, but it illustrates my point.
16-bit code:
Code: Select all
0x00: mov bx, ax ; some general instruction
0x02: mov ax, 0x0007 ; 0x0007 = [.func]
0x04: push bx ; another general instruction
0x05: call *ax
0x06: hlt
.func:
0x07: push bp ; function prolog
0x08: int 0x80 ; do a syscall
0x0a: pop bp ; function epilog
0x0b: ret
OK, now you try and translate this to 32bit code:
Code: Select all
0x00: mov ebx, eax ; some general instruction
0x02: mov eax, 0x00000007 ; 0x000000?? = [.func]
0x06: push ebx ; another general instruction
0x07: call *eax
0x09: hlt
.func:
0x0a: push ebp ; function prolog
0x0b: int 0x80 ; do a syscall
0x0c: pop ebp ; function epilog
0x0d: ret
Do you see the problem? the
call *ax is calling the address specified by the contents of ax, which is given in a previous line as an immediate. When translating to 32-bit, the instruction alignment gets changed, so that instead of
.func being at address 0x07,
call *eax is, so we get an infinite loop! Granted, with the halt as the next instruction, this has the same outward effect as before, but internally something is seriously wrong.
This is why dynamic binary translation is seriously nontrivial - we have run-time support to deal with this. I can't say anything about it, but I would say this - Beware! and
do not try and program the translator in assembler!!!
JamesM
Posted: Wed Aug 08, 2007 8:33 am
by sancho1980
ok
it was just a thought i had
probably what you would need to do is make a semantic analysis of the binary code, so that everytime an instruction like
call [ax]
is is issued, the compiler would need to find out what was the last value moved into ax and adjust it accordingly
im not going to do this, thanks for your feedback...
Posted: Wed Aug 08, 2007 8:42 am
by JamesM
Hi,
haha, yes, but then what about a case statement:
Code: Select all
0x00: mov eax, 0x2 ; size of each case option
0x02: mlt eax, ebx ; ebx stored the case option number to select
0x04: add eax, 0x6 ; offset to start of case statement
0x06: jmp my_option_1
0x08: jmp my_option_2
0x0a: jmp my_option_3
That one is
dynamically computed! Try solving that semantically...
(actually it is probably a little possible if you look at pattern recognition and have some kind of abstract high level intermediate representation, but in the general case it can't be done. Volatile variables, for example, where they can be modified by another thread. Ain't happening)
Doesn't stop you dreaming though....
JamesM
Posted: Thu Aug 09, 2007 3:56 am
by sancho1980
honestly, what i dont uderstand is the following:
a good deal of interrupts implemented for real mode werent really written 30 years ago but much more recently, like in the 90s when protected mode was already around...so why are all these interrupt routines still written for real mode...wouldnt it be handier to implement a set of interrupt routines for protected mode as well in the bios, so that after switching over to pm the programmer wouldnt have to worry about having to program the communication with stuff like the keyboard..i mean, i understand there are many code examples of pm interrupts around, so it isnt *really* a problem but to keep on coming up with ever more new bios interrupts for real mode is like saying that real mode is the mode youre supposed to run your system on...are you with me?
Posted: Thu Aug 09, 2007 4:20 am
by AJ
I suppose the issue is one of space, backwards compatibility and bloody-mindedness.
For a start, if real-mode BIOS ints were also available in PMode, the BDA would need to be bigger (ok - that doesn't have to be a problem), but what about paging, interrupt numbers and so on. Each OS implements some of the basic stuff in a different way - the BIOS code would have to make certain assumptions and possibly force the design of existing software to change. For backwards compatibilities' sake, you can't chenge too much in one go.
As for the bloody-mindedness side of it, BIOS services are there to some extent to provide a uniform interface between hardware and the OS. Now, whose responsibility should it be to write that code; the OS devver or the BIOS designer? The big OSes have a plentiful supply of drivers too, so at the end of the day, the BIOS designer would be writing code that only hobby OS devvers will use - why bother?
Also, where do you stop? If you add enough services to the BIOS, why do you need and OS at all (ok - taking it to the extreme, but you get the point)?
Maybe there will come a point where there's so much time and effort put in backwards-compatible code that the answer will be a completely new architecture...
Cheers,
Adam