iPXE
pxe_image.c
Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26/**
27 * @file
28 *
29 * PXE image format
30 *
31 */
32
33#include <string.h>
34#include <pxe.h>
35#include <pxe_call.h>
36#include <pic8259.h>
37#include <ipxe/image.h>
38#include <ipxe/segment.h>
39#include <ipxe/netdevice.h>
40#include <ipxe/features.h>
41#include <ipxe/console.h>
42#include <ipxe/efi/efi.h>
44
46
47/** PXE command line */
48const char *pxe_cmdline;
49
50/**
51 * Execute PXE image
52 *
53 * @v image PXE image
54 * @ret rc Return status code
55 */
56static int pxe_exec ( struct image *image ) {
57 void *buffer = real_to_virt ( 0, 0x7c00 );
58 struct net_device *netdev;
59 int rc;
60
61 /* Verify and prepare segment */
62 if ( ( rc = prep_segment ( buffer, image->len, image->len ) ) != 0 ) {
63 DBGC ( image, "IMAGE %s could not prepare segment: %s\n",
64 image->name, strerror ( rc ) );
65 return rc;
66 }
67
68 /* Copy image to segment */
70
71 /* Arbitrarily pick the most recently opened network device */
72 if ( ( netdev = last_opened_netdev() ) == NULL ) {
73 DBGC ( image, "IMAGE %s could not locate PXE net device\n",
74 image->name );
75 return -ENODEV;
76 }
78
79 /* Activate PXE */
81
82 /* Construct fake DHCP packets */
84
85 /* Set PXE command line */
87
88 /* Reset console since PXE NBP will probably use it */
90
91 /* Disable IRQ, if applicable */
92 if ( netdev_irq_supported ( netdev ) && netdev->dev->desc.irq )
93 disable_irq ( netdev->dev->desc.irq );
94
95 /* Start PXE NBP */
96 rc = pxe_start_nbp();
97
98 /* Clear PXE command line */
100
101 /* Deactivate PXE */
103
104 /* Try to reopen network device. Ignore errors, since the NBP
105 * may have called PXENV_STOP_UNDI.
106 */
108 netdev_put ( netdev );
109
110 return rc;
111}
112
113/**
114 * Probe PXE image
115 *
116 * @v image PXE file
117 * @ret rc Return status code
118 */
119int pxe_probe ( struct image *image ) {
120
121 /* Images too large to fit in base memory cannot be PXE
122 * images. We include this check to help prevent unrecognised
123 * images from being marked as PXE images, since PXE images
124 * have no signature we can check against.
125 */
126 if ( image->len > ( 0xa0000 - 0x7c00 ) )
127 return -ENOEXEC;
128
129 /* Rejecting zero-length images is also useful, since these
130 * end up looking to the user like bugs in iPXE.
131 */
132 if ( ! image->len )
133 return -ENOEXEC;
134
135 return 0;
136}
137
138/**
139 * Probe PXE image (with rejection of potential EFI images)
140 *
141 * @v image PXE file
142 * @ret rc Return status code
143 */
144int pxe_probe_no_mz ( struct image *image ) {
145 const uint16_t *magic;
146 int rc;
147
148 /* Probe PXE image */
149 if ( ( rc = pxe_probe ( image ) ) != 0 )
150 return rc;
151
152 /* Reject image with an "MZ" signature which may indicate an
153 * EFI image incorrectly handed out to a BIOS system.
154 */
155 if ( image->len >= sizeof ( *magic ) ) {
156 magic = image->data;
158 DBGC ( image, "IMAGE %s may be an EFI image\n",
159 image->name );
160 return -ENOTTY;
161 }
162 }
163
164 return 0;
165}
166
167/** PXE image type */
168struct image_type pxe_image_type[] __image_type ( PROBE_PXE ) = {
169 {
170 .name = "PXE-NBP",
171 .probe = pxe_probe_no_mz,
172 .exec = pxe_exec,
173 },
174 {
175 .name = "PXE-NBP (may be EFI?)",
176 .probe = pxe_probe,
177 .exec = pxe_exec,
178 },
179};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
EFI image format for PE32, PE32+ and TE.
#define EFI_IMAGE_DOS_SIGNATURE
Definition PeImage.h:50
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
uint16_t magic
Magic signature.
Definition bzimage.h:1
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC(...)
Definition compiler.h:505
#define DHCP_EB_FEATURE_PXE
PXE format.
Definition features.h:50
#define FEATURE_IMAGE
Image formats.
Definition features.h:23
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOEXEC
Exec format error.
Definition errno.h:520
#define ENODEV
No such device.
Definition errno.h:510
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
Executable images.
#define PROBE_PXE
PXE image probe priority.
Definition image.h:164
#define __image_type(probe_order)
An executable image type.
Definition image.h:170
#define cpu_to_le16(value)
Definition byteswap.h:107
User interaction.
static void console_reset(void)
Reset console.
Definition console.h:215
EFI API.
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
Feature list.
#define FEATURE(category, text, feature_opt, version)
Declare a feature.
Definition features.h:101
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition netdevice.c:1048
int netdev_open(struct net_device *netdev)
Open network device.
Definition netdevice.c:862
Network device management.
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:565
static int netdev_irq_supported(struct net_device *netdev)
Check whether or not network device supports interrupts.
Definition netdevice.h:673
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
void pxe_activate(struct net_device *netdev)
Activate PXE stack.
Definition pxe_call.c:269
int pxe_start_nbp(void)
Start PXE NBP at 0000:7c00.
Definition pxe_call.c:330
int pxe_deactivate(void)
Deactivate PXE stack.
Definition pxe_call.c:300
PXE API entry point.
const char * pxe_cmdline
PXE command line.
Definition pxe_image.c:48
int pxe_probe_no_mz(struct image *image)
Probe PXE image (with rejection of potential EFI images)
Definition pxe_image.c:144
int pxe_probe(struct image *image)
Probe PXE image.
Definition pxe_image.c:119
static int pxe_exec(struct image *image)
Execute PXE image.
Definition pxe_image.c:56
void pxe_fake_cached_info(void)
Construct cached DHCP packets.
static __always_inline void * real_to_virt(unsigned int segment, unsigned int offset)
Convert segment:offset address to virtual address.
Definition realmode.h:77
int prep_segment(void *segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition segment.c:61
Executable image segments.
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An executable image type.
Definition image.h:95
An executable image.
Definition image.h:24
const void * data
Read-only data.
Definition image.h:51
char * name
Name.
Definition image.h:38
size_t len
Length of raw file image.
Definition image.h:56
char * cmdline
Command line to pass to image.
Definition image.h:43
A network device.
Definition netdevice.h:353