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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /**
27  * @file
28  *
29  * PXE image format
30  *
31  */
32 
33 #include <pxe.h>
34 #include <pxe_call.h>
35 #include <pic8259.h>
36 #include <ipxe/uaccess.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 */
48 const char *pxe_cmdline;
49 
50 /**
51  * Execute PXE image
52  *
53  * @v image PXE image
54  * @ret rc Return status code
55  */
56 static int pxe_exec ( struct image *image ) {
57  userptr_t buffer = real_to_user ( 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 %p could not prepare segment: %s\n",
64  image, strerror ( rc ) );
65  return rc;
66  }
67 
68  /* Copy image to segment */
69  memcpy_user ( buffer, 0, image->data, 0, image->len );
70 
71  /* Arbitrarily pick the most recently opened network device */
72  if ( ( netdev = last_opened_netdev() ) == NULL ) {
73  DBGC ( image, "IMAGE %p could not locate PXE net device\n",
74  image );
75  return -ENODEV;
76  }
77  netdev_get ( netdev );
78 
79  /* Activate PXE */
80  pxe_activate ( netdev );
81 
82  /* Construct fake DHCP packets */
84 
85  /* Set PXE command line */
87 
88  /* Reset console since PXE NBP will probably use it */
89  console_reset();
90 
91  /* Disable IRQ, if applicable */
94 
95  /* Start PXE NBP */
96  rc = pxe_start_nbp();
97 
98  /* Clear PXE command line */
99  pxe_cmdline = NULL;
100 
101  /* Deactivate PXE */
102  pxe_deactivate();
103 
104  /* Try to reopen network device. Ignore errors, since the NBP
105  * may have called PXENV_STOP_UNDI.
106  */
107  netdev_open ( netdev );
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  */
119 int 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  */
144 int pxe_probe_no_mz ( struct image *image ) {
145  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  copy_from_user ( &magic, image->data, 0, sizeof ( magic ) );
158  DBGC ( image, "IMAGE %p may be an EFI image\n",
159  image );
160  return -ENOTTY;
161  }
162  }
163 
164  return 0;
165 }
166 
167 /** PXE image type */
168 struct 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 };
void pxe_activate(struct net_device *netdev)
Activate PXE stack.
Definition: pxe_call.c:276
static int pxe_exec(struct image *image)
Execute PXE image.
Definition: pxe_image.c:56
int pxe_probe(struct image *image)
Probe PXE image.
Definition: pxe_image.c:119
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
userptr_t data
Raw file image.
Definition: image.h:41
#define ENOEXEC
Exec format error.
Definition: errno.h:519
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
An executable image type.
Definition: image.h:76
uint32_t magic
Magic signature.
Definition: fdt.h:12
#define disable_irq(x)
Definition: pic8259.h:52
#define EFI_IMAGE_DOS_SIGNATURE
Definition: PeImage.h:49
PXE API entry point.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
An executable image.
Definition: image.h:24
#define FEATURE_IMAGE
Image formats.
Definition: features.h:22
Access to external ("user") memory.
char * name
Name of this image type.
Definition: image.h:78
char * cmdline
Command line to pass to image.
Definition: image.h:39
struct image_type pxe_image_type [] __image_type(PROBE_PXE)
PXE image type.
Executable image segments.
void pxe_fake_cached_info(void)
Construct cached DHCP packets.
Definition: pxe_preboot.c:135
#define DHCP_EB_FEATURE_PXE
PXE format.
Definition: features.h:49
int pxe_deactivate(void)
Deactivate PXE stack.
Definition: pxe_call.c:307
int prep_segment(userptr_t segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition: segment.c:60
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:555
unsigned int irq
IRQ.
Definition: device.h:39
Executable images.
FEATURE(FEATURE_IMAGE, "PXE", DHCP_EB_FEATURE_PXE, 1)
const char * pxe_cmdline
PXE command line.
Definition: pxe_image.c:48
static struct net_device * netdev
Definition: gdbudp.c:52
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition: netdevice.c:973
Feature list.
int pxe_probe_no_mz(struct image *image)
Probe PXE image (with rejection of potential EFI images)
Definition: pxe_image.c:144
User interaction.
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
size_t len
Length of raw file image.
Definition: image.h:43
int pxe_start_nbp(void)
Start PXE NBP at 0000:7c00.
Definition: pxe_call.c:337
A network device.
Definition: netdevice.h:348
#define ENODEV
No such device.
Definition: errno.h:509
static void console_reset(void)
Reset console.
Definition: console.h:214
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:544
EFI image format for PE32, PE32+ and TE.
EFI API.
struct device * dev
Underlying hardware device.
Definition: netdevice.h:360
Network device management.
#define PROBE_PXE
PXE image probe priority.
Definition: image.h:137
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define cpu_to_le16(value)
Definition: byteswap.h:106
struct device_description desc
Device description.
Definition: device.h:79
static __always_inline userptr_t real_to_user(unsigned int segment, unsigned int offset)
Convert segment:offset address to user buffer.
Definition: realmode.h:75
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static int netdev_irq_supported(struct net_device *netdev)
Check whether or not network device supports interrupts.
Definition: netdevice.h:663
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:767
void memcpy_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers.
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33