2 * PXE image loader for Etherboot.
4 * Note: There is no signature check for PXE images because there is
5 * no signature. Well done, Intel! Consequently, pxe_probe() must be
6 * called last of all the image_probe() routines, because it will
7 * *always* claim the image.
11 #error PXE_IMAGE requires PXE_EXPORT
14 #include "etherboot.h"
15 #include "pxe_callbacks.h"
18 unsigned long pxe_load_offset;
20 static sector_t pxe_download ( unsigned char *data,
21 unsigned int len, int eof );
23 static inline os_download_t pxe_probe ( unsigned char *data __unused,
24 unsigned int len __unused ) {
30 static sector_t pxe_download ( unsigned char *data,
31 unsigned int len, int eof ) {
32 unsigned long block_address = PXE_LOAD_ADDRESS + pxe_load_offset;
33 PXENV_STATUS_t nbp_exit;
35 /* Check segment will fit. We can't do this in probe()
36 * because there's nothing in the non-existent header to tell
37 * us how long the image is.
39 if ( ! prep_segment ( block_address, block_address + len,
41 pxe_load_offset, pxe_load_offset + len ) ) {
42 longjmp ( restart_etherboot, -2 );
45 /* Load block into memory, continue loading until eof */
46 memcpy ( phys_to_virt ( block_address ), data, len );
47 pxe_load_offset += len;
52 /* Start up PXE NBP */
55 /* Install and activate a PXE stack */
56 pxe_stack = install_pxe_stack ( NULL );
57 if ( ensure_pxe_state ( READY ) ) {
59 nbp_exit = xstartpxe();
61 /* Fake success so we tear down the stack */
62 nbp_exit = PXENV_STATUS_SUCCESS;
65 /* NBP has three exit codes:
66 * PXENV_STATUS_KEEP_UNDI : keep UNDI and boot next device
67 * PXENV_STATUS_KEEP_ALL : keep all and boot next device
68 * anything else : remove all and boot next device
70 * Strictly, we're meant to hand back to the BIOS, but this
71 * would prevent the useful combination of "PXE NBP fails, so
72 * let Etherboot try to boot its next device". We therefore
75 if ( nbp_exit != PXENV_STATUS_KEEP_UNDI &&
76 nbp_exit != PXENV_STATUS_KEEP_ALL ) {
77 /* Tear down PXE stack */
81 /* Boot next device. Under strict PXE compliance, exit back
82 * to the BIOS, otherwise let Etherboot move to the next
86 longjmp ( restart_etherboot, 255 );
88 longjmp ( restart_etherboot, 4 );
91 /* Never reached; avoid compiler warning */