[contrib] Allow Network Protocol header to display in rom-o-matic
[gpxe.git] / src / arch / i386 / image / pxe_image.c
blob63429f877d24f26dd0bef2df7600d07805a2ab0a
1 /*
2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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.
19 FILE_LICENCE ( GPL2_OR_LATER );
21 /**
22 * @file
24 * PXE image format
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>
36 FEATURE ( FEATURE_IMAGE, "PXE", DHCP_EB_FEATURE_PXE, 1 );
38 struct image_type pxe_image_type __image_type ( PROBE_PXE );
40 /**
41 * Execute PXE image
43 * @v image PXE image
44 * @ret rc Return status code
46 static int pxe_exec ( struct image *image ) {
47 struct net_device *netdev;
48 int rc;
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;
57 /* Activate PXE */
58 pxe_activate ( netdev );
60 /* Start PXE NBP */
61 rc = pxe_start_nbp();
63 /* Deactivate PXE */
64 pxe_deactivate();
66 return rc;
69 /**
70 * Load PXE image into memory
72 * @v image PXE file
73 * @ret rc Return status code
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;
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.
86 if ( filesz > ( 0xa0000 - 0x7c00 ) )
87 return -ENOEXEC;
89 /* Rejecting zero-length images is also useful, since these
90 * end up looking to the user like bugs in gPXE.
92 if ( ! filesz )
93 return -ENOEXEC;
95 /* There are no signature checks for PXE; we will accept anything */
96 if ( ! image->type )
97 image->type = &pxe_image_type;
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;
106 /* Copy image to segment */
107 memcpy_user ( buffer, 0, image->data, 0, filesz );
109 return 0;
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,