bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

UNDI/PXE driver for GRUB


From: Patrick J. LoPresti
Subject: UNDI/PXE driver for GRUB
Date: 12 Aug 2002 12:46:49 -0400
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

(Note: To understand this message, it helps to have read the PXE 2.1
specification, especially chapter 3.  You can download it from
<http://www.intel.com/labs/manage/wfm/wfmspecs.htm>.)

With hardware for which no Etherboot driver is available, it would be
nice if pxegrub could use the UNDI stack which is included with all
PXE-compliant network cards.  In principle, this would allow pxegrub
to support any such card, current or future.

Since I have some hardware (mostly laptops) which Etherboot does not
support, I decided to take a crack at writing UNDI/PXE support this
weekend.

Let me describe what little I got working.

I began by adding a "pxe_trampoline" function to stage2/asm.S.  This
function translates a protected-mode call to the real-mode call
required by the UNDI stack.  (The PXE specification says that the UNDI
stack should work from protected mode, but that may mean 16-bit
protected mode (?).  Anyway, I was unable to invoke the stack
successfully from protected mode.)

The trampoline function is pretty short, so I include it here:

    /* Trampoline to call real-mode PXE functions.

       pxe_trampoline(SEGOFF16 entry, int opcode, SEGOFF16 argptr)

    */

    ENTRY(pxe_trampoline)
            pushl %ebp

            /* Copy arguments to scratch space */
            movl    0x8(%esp), %eax
            movl    %eax, SCRATCHADDR
            movl    0xc(%esp), %eax
            movl    %eax, SCRATCHADDR+4
            movl    0x10(%esp), %eax
            movl    %eax, SCRATCHADDR+8

            /* Drop to real mode */
            call    EXT_C(prot_to_real)
            .code16

            /* Get arguments from scratch segment */
            movw    $SCRATCHSEG, %ax
            movw    %ax, %es
            /* segment of parameter block */
            pushw   %es:(10)
            /* offset of parameter block */
            pushw   %es:(8)
            /* PXE opcode (throwing away the high word) */
            pushw   %es:(4)
            /* call PXE entry point */
            lcall   *%es:0
            /* pop arguments */
            addw    $6, %sp
            /* remember return value */
            movw    %ax, %dx

            /* Return to protected mode */
            DATA32  call    EXT_C(real_to_prot)
            .code32

            /* Recover return value */
            xorl    %eax, %eax
            movw    %dx, %ax
            popl    %ebp
            ret


Next, I began writing an "fsys_pxe" filesystem module.  My idea was to
use the high-level TFTP support in the UNDI stack, ignoring most of
the existing netboot code since it depends on low-level polling
drivers.  The low-level UNDI interface uses an interrupt-driven model.
I figured it would be easier to use the high-level UNDI TFTP interface
directly than to simulate the Etherboot polling model using the UNDI
interrupt-driven one.

The first thing my fsys_pxe module does is scan memory to find the
"!PXE" structure, which provides (among other things) the entry point
to the UNDI stack.

The next thing fsys_pxe does is call the PXENV_GET_CACHED_INFO routine
using the trampoline, requesting the DHCP ACK packet.  This actually
works!  It returns a valid and correct DHCP packet, complete with
gateway IP address, server IP address, client IP address, vendor
options, and so on.  In other words, my pxe_trampoline function works,
which is the good news.

The bad news is that almost nothing else works.  Most UNDI calls are
returning a failure code with the status field set to 0x01 ("general
failure").  Some calls (e.g., PXENV_TFTP_OPEN) pause for a while
before returning failure, but they do not actually emit any packets as
far as I can tell.  Without anything more telling than "general
failure", I am at a bit of a loss for how to proceed.

I would be happy to make the rest of my code available to anybody who
is interested.  I myself may end up using syslinux/pxelinux instead...

 - Pat




reply via email to

[Prev in Thread] Current Thread [Next in Thread]