[syslinux] PXE stack access via com32

jesse barker jessebarker5 at yahoo.com
Sat Jan 6 10:32:06 PST 2007


Apologies in advance for the shoddy quoting of your reply (I've put '>> ' in front of your reply sections)....

----- Original Message ----
From: H. Peter Anvin <hpa at zytor.com>
To: jesse barker <jessebarker5 at yahoo.com>
Cc: syslinux at zytor.com
Sent: Friday, January 5, 2007 9:26:06 PM
Subject: Re: [syslinux] PXE stack access via com32

jesse barker wrote:
> Hi,
> 
> I've checked the archives for my issue, and while there is relevant discussion, the problem the original poster was asking about didn't seem to have been resolved then either (~2 years ago).  At any rate, basically what I'm trying to do is send (possibly receive) UDP packets via the PXE stack using the com32 API (using version 3.11 of syslinux).  I have followed both the comboot API doc and the aforementioned thread; however they disagree on which registers are used for which bits of data in the setup for __intcall().  According to the comboot doc, to call the PXE stack's 'get cached info' function:
> 
>  Input: AX 0009h
>          BX PXE function number
>          ES:DI PXE data buffer
> Output: AX PXE return status code
> 
> or, in com32 terms (the PXE call argument struct has been copied into the
> bounce buffer and the buffer field of the PXE call argument struct is setup to
> point into the bounce buffer as well):
> 
>  inputRegs.es         = SEG(__com32.cs_bounce);
> inputRegs.edi.w[0] = OFFS(__com32.cs_bounce);
> inputRegs.eax.w[0] = 0x0009; /* call PXE stack */
>  inputRegs.ebx.w[0] = 0x0071; /* PXENV_GET_CACHED_INFO opcode */
> 
> __intcall(0x22, &inputRegs, &outputRegs);
> 
> However, when setup this way, 'outputRegs.eax.w[0]' contains 'PXENV_EXIT_FAILURE' (and the status field of the PXE call argument struct indicates failure as well).  The instructions from the previous thread on this topic are contrary to that documentation and indicate something more
> like (not sure about the PXE opcode being in edi, of course, but that wasn't specified in the thread)

>> What's in __com32.cs_bounce at this point?  It's expected to point to a 
>> s_PXENV_GET_CACHED_INFO (PXE 2.1 spec page 49) structure, which has been 
>> filled in by the caller.  It is NOT the buffer in which you expect the 
>> data to be stored!

I started with a PXENV_GET_CACHED_INFO struct as described in the spec (version 2.1).  I filled it out like this:

s_PXENV_GET_CACHED_INFO args;
BOOTPLAYER cachedInfo; /* As described on page 50 of PXE 2.1 */

memset(&args, 0, sizeof(args));
memset(&cachedInfo, 0, sizeof(cachedInfo));

args.PacketType = PXENV_PACKET_TYPE_DHCP_ACK; /* 2 */
args.BufferSize = sizeof(cachedInfo);
args.Buffer.segment = SEG(&cachedInfo);
args.Buffer.offset = OFFS(&cachedInfo);

memcpy(__com32.cs_bounce, &args, sizeof(args);

inputRegs.es         = SEG(__com32.cs_bounce);
inputRegs.edi.w[0] = OFFS(__com32.cs_bounce);
inputRegs.eax.w[0] = 0x0009; /* call PXE stack */
inputRegs.ebx.w[0] = 0x0071; /* PXENV_GET_CACHED_INFO opcode */

__intcall(0x22, &inputRegs, &outputRegs);

And then, as I say, eax contains 'PXENV_EXIT_FAILURE' (and the status field contains 'PXENV_STATUS_FAILURE').  While debugging this, I noticed that the pointer to the BOOTPLAYER struct (&cachedInfo) had some more significant bits than could be used by 'SEG()' and 'OFFS()' (i.e. the original pointer could not be reconstructed from the segment and offset values in the argument struct), so I moved to using the bounce buffer to contain both structs and copied appropriately, though, that did not seem to have made a difference.

> 
>  inputRegs.es          = SEG(__com32.cs_bounce);
> inputRegs.ebx.w[0] = OFFS(__com32.cs_bounce);
> inputRegs.eax.w[0] = 0x0009; /* call PXE stack */
>  inputRegs.edi.w[0]  = 0x0071; /* PXENV_GET_CACHED_INFO opcode */
> 
> __intcall(0x22, &inputRegs, &outputRegs);
> 
> In this case, the call claims to succeed (eax contains 'PXENV_EXIT_SUCCESS' and the status field of the argument struct claims 'PXENV_STATUS_SUCCESS'), however the buffer that would receive the cached info (the BOOTPLAYER struct) seems to have all 0's.

>> This is just plain wrong.  You're with a very high likelihood calling 
>> PXE function zero (PXENV_START_UNDI), which is a totally different ball 
>> of wax.

This was just an experiment.  I felt I had to try both permutations given the difference between the comboot API documentation and your feedback on the prior thread on this topic (which was contrary to the docs).

Thanks again for your feedback,
Jesse




__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




More information about the Syslinux mailing list