Subject: need h/e/l/p: PM -> RM in machine_real_start


hello,

arch/i386/kernel/process.c exports a "machine_real_start" function, which
can be used to execute arbitary 16bit realmode code. I've got this to
work so far, by writing a small helper-module which copies 16bit code
supplied from userland and passes it to "machine_real_start", which in
turn, after switching to real mode, executes that particular code.

"machine_real_start" is currently only used to make real mode APM BIOS
calls to power off the machine. but as pointed out above, it can be
used to execute any 16bit code. of course, there's no way to go back to
linux, but that's not required (for me).

to show this approach works, I wrote some small assembly routines,
which do nothing but draw some characters on 0xb800 (text mode video),
hexdump the real mode interrupt vectors and so on. that's nice, but
that's not all I need.

what is needed is the BIOS. I wonder if it is at all possible to use
the BIOS again after linux once had run without jumping to 0xffff:0
does linux make use of the memory at 0x40? I'm pretty sure that it
will be possible to e.g. invoke 0x10 (video), since that is located
in ROM, but what about RAM. does linux make use of <1Mb area anyway,
that is, 2^20 (A20) the area which can be addresses with 20 bits of
address-lines (4bit segreg + 16bit offset).

well, BIOS is one thing, hardware is another. I seem not to be able
to get *any* interrupt, allthough I really tried in various ways.
write an ISR which increments a character in the upper left corner,
modify all 256 interrupt vectors to point to the ISR, re-enable interrupts,
(sti), unmask all interrupts (out 0x21,0; out 0xa1,0). but no matter
what I do - press a key (IRQ1) or program 8253 (IRQ0) - I just can't
see the ISR is being called.

is it neccessary to reset the pics? does linux change the operation
mode of the pics at all?

I also seem to have a very obsolete paper the port assignment of the
PC. do you know of any sources (perferrably on the web) which gives
a complete overview of portadresses used by the PC?

seveal years ago, I had an orignal bios listing for the IBM PC
directly from IBM. but not only have I lost that listing, it also
seems to be impossible to find any up-to-date bios listing ... well,
I guess the companies wont give them out, but at least I expected some
disassmbled code out there on the net... hm...!

any helpful response is welcome!
thanks in advance,
h.rosmanith














2002-10-31 16:45:27

by Richard B. Johnson

[permalink] [raw]
Subject: Re: need h/e/l/p: PM -> RM in machine_real_start

On Thu, 31 Oct 2002, H.Rosmanith (Kernel Mailing List) wrote:

>
> hello,
>
> arch/i386/kernel/process.c exports a "machine_real_start" function, which
> can be used to execute arbitary 16bit realmode code. I've got this to
> work so far, by writing a small helper-module which copies 16bit code
> supplied from userland and passes it to "machine_real_start", which in
> turn, after switching to real mode, executes that particular code.
[SNIPPED...]

>
> what is needed is the BIOS. I wonder if it is at all possible to use
> the BIOS again after linux once had run without jumping to 0xffff:0
> does linux make use of the memory at 0x40? I'm pretty sure that it
> will be possible to e.g. invoke 0x10 (video), since that is located
> in ROM, but what about RAM. does linux make use of <1Mb area anyway,
> that is, 2^20 (A20) the area which can be addresses with 20 bits of
> address-lines (4bit segreg + 16bit offset).
>

The BIOS is most-likely shadowed at 0x000f0000, what you see is
not the BIOS ROM. The BIOS ROM exists at 0xfffff000, on some
as low as 0xffffe000, to start execution at 0xfffffff0, and can only
be accessed in 32-bit mode or after a reset-event when the CS
descriptor cache contains 0xffff. The first load of the CS resets
these bits.

Linux leaves the BIOS area alone, but interrupts may not be directly
usable because Linux loads a different IDT and reprograms the IO-APIC,
which is used in place of the interrupt controller if it exists.

You need to reload the IDT once in real-mode. Documentation states
that it is "ignored", but the reload is necessary to get the default
interrupt-table to work. I think you can just reload with any memory
operand (reload junk). If you were transitioning from real to 32-bit
and back, you would save the current one "SIDT", before loading the
32-bit one "LIDT". Since you don't know where the previous one was saved,
(if ever) you can't reload it.


> well, BIOS is one thing, hardware is another. I seem not to be able
> to get *any* interrupt, allthough I really tried in various ways.
> write an ISR which increments a character in the upper left corner,
> modify all 256 interrupt vectors to point to the ISR, re-enable interrupts,
> (sti), unmask all interrupts (out 0x21,0; out 0xa1,0). but no matter
> what I do - press a key (IRQ1) or program 8253 (IRQ0) - I just can't
> see the ISR is being called.
>

Whatever interrupt controllers are used, they are programmed differently
in Linux than the BIOS expects. You would need to reprogram them, not
difficult, just a few instructions (check free-BIOS) or other references.

> I also seem to have a very obsolete paper the port assignment of the
> PC. do you know of any sources (perferrably on the web) which gives
> a complete overview of portadresses used by the PC?

Check free-BIOS


Cheers,
Dick Johnson
Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).
Bush : The Fourth Reich of America


Subject: Re: need h/e/l/p: PM -> RM in machine_real_start

>
> Linux leaves the BIOS area alone, but interrupts may not be directly
> usable because Linux loads a different IDT and reprograms the IO-APIC,
> which is used in place of the interrupt controller if it exists.
>
> You need to reload the IDT once in real-mode. Documentation states
> that it is "ignored", but the reload is necessary to get the default
> interrupt-table to work. I think you can just reload with any memory
> operand (reload junk). If you were transitioning from real to 32-bit
> and back, you would save the current one "SIDT", before loading the
> 32-bit one "LIDT". Since you don't know where the previous one was saved,
> (if ever) you can't reload it.

well, reloading the idt is already done in "machine_real_start", look
at line 255 (definition) and line 336 (execution).

what I've never heard of is the IO-APIC (allthough there's a file
named io_apic.c just in the same directory). there surely is a way to
"get rid of it" and have the 8259(A) or the emulating chipset(?) take
over again. do you have, or do you know where I can find, documention
about the IO-APIC? probably that's the reason why I don't see any
hardware interrupts.

> Whatever interrupt controllers are used, they are programmed differently
> in Linux than the BIOS expects. You would need to reprogram them, not
> difficult, just a few instructions (check free-BIOS) or other references.

I've been afraid of that :-) okay ... I'll try. So far, I've already
been checking linux-bios (didn't help much) and OpenBIOS. Hm, hm!
It looks like (just as I ask google for FreeBIOS) that FreeBIOS is
another different project.

> Check free-BIOS

thanks for the hint. It looks promising.

herbert

Subject: Re: need h/e/l/p: PM -> RM in machine_real_start

> >
> > Linux leaves the BIOS area alone, but interrupts may not be directly
> > usable because Linux loads a different IDT and reprograms the IO-APIC,
> > which is used in place of the interrupt controller if it exists.
> >
> what I've never heard of is the IO-APIC (allthough there's a file
> named io_apic.c just in the same directory).

ah, I see ... that's an enhanced interrupt controller which is used
on SMP boards. is it correct that this one is only configured/activated
when:

.config
[...]
# CONFIG_X86_UP_APIC is not set
# CONFIG_X86_UP_IOAPIC is not set

these options are set? therefore, since this options are off, the
IO-APIC is not being used, correct?

herbert