Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

pxe_loader.c 2.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * PXE image loader for Etherboot.
  3. *
  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.
  8. */
  9. #ifndef PXE_EXPORT
  10. #error PXE_IMAGE requires PXE_EXPORT
  11. #endif
  12. #include "etherboot.h"
  13. #include "pxe_callbacks.h"
  14. #include "pxe_export.h"
  15. #include "pxe.h"
  16. unsigned long pxe_load_offset;
  17. static sector_t pxe_download ( unsigned char *data,
  18. unsigned int len, int eof );
  19. static inline os_download_t pxe_probe ( unsigned char *data __unused,
  20. unsigned int len __unused ) {
  21. printf("(PXE)");
  22. pxe_load_offset = 0;
  23. return pxe_download;
  24. }
  25. static sector_t pxe_download ( unsigned char *data,
  26. unsigned int len, int eof ) {
  27. unsigned long block_address = PXE_LOAD_ADDRESS + pxe_load_offset;
  28. PXENV_STATUS_t nbp_exit;
  29. /* Check segment will fit. We can't do this in probe()
  30. * because there's nothing in the non-existent header to tell
  31. * us how long the image is.
  32. */
  33. if ( ! prep_segment ( block_address, block_address + len,
  34. block_address + len,
  35. pxe_load_offset, pxe_load_offset + len ) ) {
  36. longjmp ( restart_etherboot, -2 );
  37. }
  38. /* Load block into memory, continue loading until eof */
  39. memcpy ( phys_to_virt ( block_address ), data, len );
  40. pxe_load_offset += len;
  41. if ( ! eof ) {
  42. return 0;
  43. }
  44. /* Start up PXE NBP */
  45. done ( 0 );
  46. /* Install and activate a PXE stack */
  47. pxe_stack = install_pxe_stack ( NULL );
  48. if ( ensure_pxe_state ( READY ) ) {
  49. /* Invoke the NBP */
  50. nbp_exit = xstartpxe();
  51. } else {
  52. /* Fake success so we tear down the stack */
  53. nbp_exit = PXENV_STATUS_SUCCESS;
  54. }
  55. /* NBP has three exit codes:
  56. * PXENV_STATUS_KEEP_UNDI : keep UNDI and boot next device
  57. * PXENV_STATUS_KEEP_ALL : keep all and boot next device
  58. * anything else : remove all and boot next device
  59. *
  60. * Strictly, we're meant to hand back to the BIOS, but this
  61. * would prevent the useful combination of "PXE NBP fails, so
  62. * let Etherboot try to boot its next device". We therefore
  63. * take liberties.
  64. */
  65. if ( nbp_exit != PXENV_STATUS_KEEP_UNDI &&
  66. nbp_exit != PXENV_STATUS_KEEP_ALL ) {
  67. /* Tear down PXE stack */
  68. remove_pxe_stack();
  69. }
  70. /* Boot next device. Under strict PXE compliance, exit back
  71. * to the BIOS, otherwise let Etherboot move to the next
  72. * device.
  73. */
  74. #ifdef PXE_STRICT
  75. longjmp ( restart_etherboot, 255 );
  76. #else
  77. longjmp ( restart_etherboot, 4 );
  78. #endif
  79. /* Never reached; avoid compiler warning */
  80. return ( 0 );
  81. }