Diskless Booting: Difference between revisions

Added link to PXE Spec, slight cleanups
[unchecked revision][unchecked revision]
(Added link to PXE Spec, slight cleanups)
Line 25:
Both of the options above involve using someone else's code to do the dirty work, which may be undesirable in some situations - licensing conflicts, technical problems (e.g. for "memdisk" the interrupt 0x13 hook won't work in protected mode) and possibly personal pride. Fortunately, writing your own PXE boot code isn't as difficult as it sounds.
 
The first step is to download the [http://download.intel.com/design/archives/wfm/downloads/pxespec.pdf PXE specification] from the internet and take a look at it. At first glance this specification can be rather daunting, but don't let that stop you - most of it relates to BIOS and network cards and can be safely ignored. The important part is in chapter 3, the PXE API.
 
Basically, "somehow" your PXE boot code gets into the client computer and it doesn't really matter how (networking code in the client machine's ROM arranges this with help from the DHCP server and TFTP server). Your code is loaded at 0x0007C00 and started in real mode, just like a normal floppy boot sector. The difference is that you don't need the "0xAA55" magic value and the size of your code can be up to 32 KB (no more trouble squeezing everything into 512 bytes).
 
When your code is started, the BIOS gives it a valid stack (with at least 1.5 KB of free stack space) and passes some parameters to your code on this stack and in registers. See section 4.4.5 "_ClientClient State at Bootstrap Execution Time (Remote.0)_" in the specification for details. There's only 2 things that are important here - the address of an older "PXENV+ structure" and the address of the newer "PXE structure". These structures are used to find the PXE API entry point/s and a few other things.
 
The PXE entry structure was introduced in version 2.1 of the specification, while the PXENV+ structure is becoming obsolete. This means that only one of these structures may be present depending on how old your ROM's code is. The specification states that if the !PXE structure is present then your code should use the PXE entry point (not the entry point from the PXENV+ structure, which may be present for backwards compatability). Both of these structures contain a _segment''segment:offset_offset'' for their own PXE API entry point. The calling conventions you need use to access the PXE API depend on which structure is are present.
 
For the PXE entry point you use "_Pascal_"''Pascal'' calling conventions (push the parameters on the stack, far call the entry point, then clean up the stack), while the older PXENV+ entry point uses registers instead. Apart from this the PXE API is the same, and fortunately all PXE API functions have the same parameters - the "_opcode_opcode" (or API function number) and the _segment''segment:offset_offset'' for a structure containing data for the function.
 
For the PXE entry point you'd use something like this:
Line 42:
push opcode
call far [PXEAPIentry]
add sp, 6
</source>
 
Line 48:
 
<source lang="asm">
mov ds, structureSegment
mov di, structureOffset
mov bx, opcode
call far [PXEAPIentry]
</source>
Line 58:
<source lang="asm">
callPXEAPI:
cmp [PXEAPItype], 0
je .olderAPI
push ds
Line 64:
push bx
call far [PXEAPIentry]
add sp, 6
ret
 
Line 92:
*[http://www.gnu.org/software/grub/manual/html_node/Diskless.html#Diskless Official GRUB FAQ]
*[http://www.elet.polimi.it/upload/fornacia/progetto_minazzi/index.html#HOW%20TO%20INSTALL%20A%20TFTP%20SERVER Setting up a TFTP server]
*[http://download.intel.com/design/archives/wfm/downloads/pxespec.pdf PXE Specification]
 
[[Category:Bootloaders]]
Anonymous user