1 /* 2 * Copyright (C) 2007 Michael Brown <mbrown (at) fensystems.co.uk>. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 FILE_LICENCE ( GPL2_OR_LATER ); 20 21 /** 22 * @file 23 * 24 * PXE image format 25 * 26 */ 27 28 #include <pxe.h> 29 #include <pxe_call.h> 30 #include <gpxe/uaccess.h> 31 #include <gpxe/image.h> 32 #include <gpxe/segment.h> 33 #include <gpxe/netdevice.h> 34 #include <gpxe/features.h> 35 36 FEATURE ( FEATURE_IMAGE, "PXE", DHCP_EB_FEATURE_PXE, 1 ); 37 38 struct image_type pxe_image_type __image_type ( PROBE_PXE ); 39 40 /** 41 * Execute PXE image 42 * 43 * @v image PXE image 44 * @ret rc Return status code 45 */ 46 static int pxe_exec ( struct image *image ) { 47 struct net_device *netdev; 48 int rc; 49 50 /* Arbitrarily pick the most recently opened network device */ 51 if ( ( netdev = last_opened_netdev() ) == NULL ) { 52 DBGC ( image, "IMAGE %p could not locate PXE net device\n", 53 image ); 54 return -ENODEV; 55 } 56 57 /* Activate PXE */ 58 pxe_activate ( netdev ); 59 60 /* Start PXE NBP */ 61 rc = pxe_start_nbp(); 62 63 /* Deactivate PXE */ 64 pxe_deactivate(); 65 66 return rc; 67 } 68 69 /** 70 * Load PXE image into memory 71 * 72 * @v image PXE file 73 * @ret rc Return status code 74 */ 75 int pxe_load ( struct image *image ) { 76 userptr_t buffer = real_to_user ( 0, 0x7c00 ); 77 size_t filesz = image->len; 78 size_t memsz = image->len; 79 int rc; 80 81 /* Images too large to fit in base memory cannot be PXE 82 * images. We include this check to help prevent unrecognised 83 * images from being marked as PXE images, since PXE images 84 * have no signature we can check against. 85 */ 86 if ( filesz > ( 0xa0000 - 0x7c00 ) ) 87 return -ENOEXEC; 88 89 /* Rejecting zero-length images is also useful, since these 90 * end up looking to the user like bugs in gPXE. 91 */ 92 if ( ! filesz ) 93 return -ENOEXEC; 94 95 /* There are no signature checks for PXE; we will accept anything */ 96 if ( ! image->type ) 97 image->type = &pxe_image_type; 98 99 /* Verify and prepare segment */ 100 if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) { 101 DBGC ( image, "IMAGE %p could not prepare segment: %s\n", 102 image, strerror ( rc ) ); 103 return rc; 104 } 105 106 /* Copy image to segment */ 107 memcpy_user ( buffer, 0, image->data, 0, filesz ); 108 109 return 0; 110 } 111 112 /** PXE image type */ 113 struct image_type pxe_image_type __image_type ( PROBE_PXE ) = { 114 .name = "PXE", 115 .load = pxe_load, 116 .exec = pxe_exec, 117 }; 118