Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

RM Mode interrupts for long mode

51 views
Skip to first unread message

Kristoffer

unread,
Feb 12, 2013, 8:00:10 PM2/12/13
to
So I got the framework / call to work for doing real mode interrupts
from long mode. It works for int 0x10 calls, not sure if int 13 calls
would work since they require IRQs and I have those remapped. Maybe I
can remap them before every x86 call but that seems a bit too much. Or
maybe copy the interrupt handlers from where they would go to the new
locations.

Anyway if anyones interested I can put the code up on my wiki and
provide a link.

Rod Pemberton

unread,
Feb 13, 2013, 1:06:27 AM2/13/13
to
"Kristoffer" <kri...@85138.tk> wrote in message
news:EJydnSrRo-IFeIfM...@giganews.com...

> So I got the framework / call to work for doing
> real mode interrupts from long mode.

By "long mode", you mean what Sandpile.org calls PM64, yes?
By "real mode", you mean what Sandpile.org calls RM16, yes?
http://www.sandpile.org/x86/mode.htm

Don't you have to switch out of long mode to get to "real mode"
a.k.a. RM16? It looks that way from the table. To get to RM16,
EFER.LMA must be zero for RM16, paging must be disabled, and PAE
disabled too... I can't imagine you doing all that just to get to
RM. Do you mean you switched to a CM16 segment while still in
long mode? I think that's called "compatibility mode".


Rod Pemberton


Kristoffer

unread,
Feb 13, 2013, 7:22:34 AM2/13/13
to
Actually, first I had to do a far jmp to a 32 segment, which put it into
compatibility mode, then disabled paging via cr0 which put it into old
fashioned protected mode, then disabled protected mode, again via cr0
and jmped to a 16 segment. Inside there I loaded values into all the
registers to set up for the interrupt call and loaded the idt. Also it
loads the interrupt number into memory ahead of itself, then finally
calls the interrupt. Then it copies all the register and eflags back to
their respective memory locales and then re enables paging and protected
mode at once via cr0 and jmps to a 64 segment where it loads the data
selectors (ds,es,fs,etc...) with 64 selectors and finally does a far jmp
back to the kernel.

Its a lot of work to do it, but it does work.

On an off topic, I think what would be really super pimp would be to
have a multi core processor that you could have one in real mode
servicing these interrupts while the rest did the real work. Not
necessarily useful for a real OS but a neat trick just to say you did it :)

http://cribix64.maricopacomputer.com/index.php/X86_Interrupt

I would get my butt kicked at work for all the magic numbers, but hey it
works.

Rod Pemberton

unread,
Feb 14, 2013, 5:14:32 AM2/14/13
to
"Kristoffer" <kri...@85138.tk> wrote in message
news:htCdnYv_Ha4UGIbM...@giganews.com...
> On 2/12/2013 11:06 PM, Rod Pemberton wrote:
> > "Kristoffer" <kri...@85138.tk> wrote in message
> > news:EJydnSrRo-IFeIfM...@giganews.com...
> >
> >> So I got the framework / call to work for doing
> >> real mode interrupts from long mode.
> >
> > By "long mode", you mean what Sandpile.org calls PM64, yes?
> > By "real mode", you mean what Sandpile.org calls RM16, yes?
> > http://www.sandpile.org/x86/mode.htm
> >
> > Don't you have to switch out of long mode to get to "real
> > mode" a.k.a. RM16? It looks that way from the table.
> > To get to RM16, EFER.LMA must be zero for RM16,
> > paging must be disabled, and PAE disabled too... I can't
> > imagine you doing all that just to get to RM. Do you
> > mean you switched to a CM16 segment while still in
> > long mode? I think that's called "compatibility mode".
> >
> Actually, first I had to do a far jmp to a 32 segment, which put
> it into compatibility mode, then disabled paging via cr0 which
> put it into old fashioned protected mode, then disabled
> protected mode, again via cr0 and jmped to a 16 segment.
> Inside there I loaded values into all the registers to set up
> for the interrupt call and loaded the idt. Also it loads the
> interrupt number into memory ahead of itself, then finally calls
> the interrupt. Then it copies all the register and eflags back
> to their respective memory locales and then re enables paging
> and protected mode at once via cr0 and jmps to a 64 segment
> where it loads the data selectors (ds,es,fs,etc...) with 64
> selectors and finally does a far jmp back to the kernel.
>
> Its a lot of work to do it, but it does work.
>

Wow, you really did do all that work just for RM ...

Currently, my (incomplete) OS doesn't use any BIOS calls. I
probably would've implemented or used a 16-bit x86 emulator or
perhaps a binary translator. Yes, that's alot of work too, if
done from scratch, but then I wouldn't need a mode switch. The RM
code would run regardless of the presence of RM or not, i.e.,
perhaps removed in the future. I'd hope that most BIOSes only use
86 or 286 or 386 or 486 instructions, so the emulator/translator
wouldn't need to support newer instructions...

Just how dependent is your OS on RM or BIOS at this point?
File I/O? Video? Interrupts?


Rod Pemberton



Kristoffer

unread,
Feb 14, 2013, 7:43:40 AM2/14/13
to
The main use I was going to use it for was switching graphics modes via
int10

Rod Pemberton

unread,
Feb 15, 2013, 6:27:25 AM2/15/13
to
"Kristoffer" <kri...@85138.tk> wrote in message
news:BM2dneOJr6tkRoHM...@giganews.com...

> The main use I was going to use [RM] for was
> switching graphics modes via int10.

Well, I program the video controller from scratch for a single
text video mode. I used info from the Internet. The routine is
neither small nor simple. IIRC, there is lots of info on
programming for VGA modes too. I wouldn't bother with EGA or CGA.
(Is that consensus here?) SVGA modes may require calling the BIOS
... (custom registers ?)

Along the way, I also found Chris Giese's vm86.c to be interesting
(for DOS, in C, for DJGPP or OpenWatcom). It's a v86 monitor that
blocks I/O ports by default, when trapped unblocks and reissues
them. The code can be slightly modified and recompiled to emit
the ports called. So, you can "see" what ports that BIOS routine
calls. I.e., you can check that registers you programmed match
what the BIOS call is actually using, or that the sequence is
correct. That only works for the tested machine's BIOS, though.
I.e., one machine may use a few special registers while another
may not...

A novel use for v86 mode would be for someone to use it to build a
used port map of BIOS routines across multiple BIOSes. A while
back, I suggested a program to test a bunch of RM BIOS routines
and save the output for a setup file for the OS, e.g., results of
E820h memory, A20 methods, etc. That way the host OS wouldn't
need RM support. It could just read the saved results in that
file. A more in depth BIOS tester program could also save the
ports used for a variety of BIOS calls. The advantage to this is
someone could run the program in DOS and it would save the I/O
ports and values, e.g., for setting a specific SVGA mode, or for
disk I/O. E.g., this should allow the host OS to set any tested
video mode without needing a routine. Write the same values to
the same I/O ports.

I know James did some testing on the availability and
functionality of A20 routines in the BIOS. As a hobbyist OS
developer, it'd be really nice to have much more info than I do
have on the capabilities of various BIOS calls on various BIOSes.
Basically, all I have is RBIL and some very useless info I collect
on 32-bit PM BIOS...


Rod Pemberton



Alexei A. Frounze

unread,
Feb 15, 2013, 7:31:10 AM2/15/13
to
On Feb 15, 3:27 am, "Rod Pemberton" <do_not_h...@notemailnotz.cnm>
wrote:
> "Kristoffer" <kris...@85138.tk> wrote in message
...

I have thought of that. The problem here is that you don't always know
when and why some port or memory is accessed. I mean, the fact that
you detect a port write does not tell you that the value being written
to the port is not dependent on some other information, perhaps also
coming from a port (ultimately, from the device) and it doesn't tell
you that this write is a response to some event and it cannot occur,
say, too early.

Alex
0 new messages