Re: [NILO-discuss] Zen and the art of running in real mode
Brought to you by:
marty_connor,
stefanhajnoczi
|
From: Michael B. <mb...@fe...> - 2005-03-08 15:01:41
|
Too many e-mail threads for me, so I've grouped everything I'm replying to in one message. There's an executive summary at the end. On Mon, 7 Mar 2005, Marty Connor wrote: > This real mode entry point seems to be and important issue. > > Could someone please explain what bad things might happen if we don't > get his right? (what might break, and how?). If we leave things as they currently are, then we're stuck with two main restrictions: 1. We cannot support the protected-mode entry point, for reasons previously described in excruciating detail. 2. We cannot support clients (NBPs, external BC etc.) that calls the real-mode entry point in V86 mode rather than real mode. Currently I know of no clients that attempt to use the protected-mode entry point, and only FreeBSD that uses the real-mode entry point in V86 mode. On Tue, 8 Mar 2005, Marty Connor wrote: > Perhaps some useful questions to ask are: > > - In what ways and to what degrees is our PXE implementation > compliant with the PXE specification v2.1? > > - Where do we diverge from the specification, and why? I can't give a definitive answer without going through the spec in detail, which I don't have time to do. Where we diverge, it's generally either because complying would have meant major structural changes to Etherboot (e.g. splitting BC and UNDI components) or because we have no known users of a particular feature and no way to test it (e.g. TFTM). In other places, we diverge in order to provide additional robustness: for example, you can call our initialisation routines in virtually any order, or even skip them completely and have the card automatically be initialised the first time a packet is transmitted or received. > - How and in what ways is our UNDI interface interoperable with PXE > loaders? The only known client that uses the UNDI interface is Etherboot itself, using its UNDI driver. It works with this client, though I accept that since I wrote both bits of code, that doesn't necessarily say anything about compliance with the spec. :) On Tue, 8 Mar 2005, H. Peter Anvin wrote: > > Indeed; according to *that* page we are allowed an arbitrary number of > > segments. However, according to page 92 (PDF page 94), the UNDI > > loader is allowed only one code and one data segment. This is a hard > > limit, since there are only two 16-bit fields in the UNDI loader > > parameter structure to specify the segments. Just one of the many > > entertaining inconsistencies in PXE. > > Page 92 only applies if you're building a modular ROM (BC+BUSD+UNDI). We claim to implement an UNDI ROM, so that clients can load us from ROM and use our UNDI interface. (OK, so we actually drag in our base code as well, but it never gets called.) Sufficiently sophisticated BIOSes should be able to load our UNDI driver and use us to communicate over the network. I have never encountered a BIOS that actually does this, but it's meant to be possible. If we go over two segments, then we lose the ability to support this. On Tue, 8 Mar 2005, H. Peter Anvin wrote: > A major problem is that the PXE spec appears to have been designed by an > infinite number of monkeys on LSD. After reading it over and over again > I'm convinced that Michael is right, there is no sane way to make it > compatible with 32-bit protected mode. This means, pretty much, that > the only possible way to make it compliant with the spec is to use > 16-bit code everywhere, and set up descriptors to cover the high memory > that whatever card uses. This is a painful way to program, and means > diverging drivers from Linux and Etherboot, which is a major lose. Even setting up descriptors to cover the high memory used by a card doesn't help us in the case of being called in V86 mode, in which case we really are constrained to base memory only. I think that providing a compile-time option to generate 16-bit code designed to run in real mode (as I described previously) is viable. There are restrictions: most significantly, drivers that use memory-mapped I/O (readX/writeX) rather than inX/outX probably won't work. Some drivers (e.g. prism2_pci) can probably be modified to use inX/outX. Some drivers (e.g. depca.c) seem to use readX/writeX to access normal in-memory data structures; I'm not quite sure what's going on here. Within these restrictions, it should be perfectly possible to have a compile-time option to generate 16-bit real-mode code. This code would then run properly in V86 mode, since it would never attempt a mode transition. The PXE protected-mode entry point is actually a hack designed to allow 16-bit real-mode code to be called in protected mode. Code capable of being run in real mode will work when called via the protected-mode entry point, provided that we load %ds etc from the !PXE structure on entry. Since our code is 32-bit code coerced into 16-bit opcodes using .code16gcc, we're already using %esp as the stack register, so supporting the EntryPointESP is a no-op, and we just need some glue logic to zero the high word of %esp in order to support the (mandatory) EntryPointSP with the same code. It's worth noting that the specification is incomplete with regard to protected-mode operation. In particular, it defines a "StatusCallout" field that must contain a far pointer to a routine to be used for printing status messages when in protected-mode (since BIOS interrupts will work only in real mode), but nothing I can find anywhere in the document describes what the parameters, actions or return value of this StatusCallout routine actually are. Since protected-mode operation is so poorly-defined, I strongly suspect that no existing programs ever attempt to call a PXE stack in protected mode. We could always cheat and simply refuse to print status messages to the video console unless StatusCallout==0 (indicating "use internal printing routines"). I appreciate that all this is quite involved, so I'm going to attempt a brief summary: o We can support genuine real-mode operation, V86-mode operation and the PXE-specified 16-bit protected-mode operation. o Doing this gives us compatibility with FreeBSD and with any as-yet-undiscovered program that uses the PM entry point. o Not all drivers will work when used in this way. This is a fundamental limitation and cannot be worked around. o We can do this simultaneously with supporting our normal 32-bit protected-mode operation. (Simultaneously in the sense of "with the same source code, using compile-time options", rather than "with the same binary ROM image"). Michael |