1 /*
2 * Copyright (C) 2007 Michael Brown <mbrown@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 */
pxe_exec(struct image * image)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 */
pxe_load(struct image * image)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