iPXE
pxe_file.c
Go to the documentation of this file.
1/** @file
2 *
3 * PXE FILE API
4 *
5 */
6
7#include <stdlib.h>
8#include <stdio.h>
9#include <errno.h>
10#include <byteswap.h>
11#include <ipxe/posix_io.h>
12#include <ipxe/features.h>
13#include <pxe.h>
14#include <realmode.h>
15
16/*
17 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License as
21 * published by the Free Software Foundation; either version 2 of the
22 * License, or any later version.
23 *
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
32 * 02110-1301, USA.
33 *
34 * You can also choose to distribute this program under the terms of
35 * the Unmodified Binary Distribution Licence (as given in the file
36 * COPYING.UBDL), provided that you have satisfied its requirements.
37 */
38
39FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
40
42
43/**
44 * FILE OPEN
45 *
46 * @v file_open Pointer to a struct s_PXENV_FILE_OPEN
47 * @v s_PXENV_FILE_OPEN::FileName URL of file to open
48 * @ret #PXENV_EXIT_SUCCESS File was opened
49 * @ret #PXENV_EXIT_FAILURE File was not opened
50 * @ret s_PXENV_FILE_OPEN::Status PXE status code
51 * @ret s_PXENV_FILE_OPEN::FileHandle Handle of opened file
52 *
53 */
54static PXENV_EXIT_t pxenv_file_open ( struct s_PXENV_FILE_OPEN *file_open ) {
55 const char *filename;
56 int fd;
57
58 DBG ( "PXENV_FILE_OPEN" );
59
60 /* Open specified filename */
61 filename = real_to_virt ( file_open->FileName.segment,
62 file_open->FileName.offset );
63 DBG ( " %s", filename );
64 fd = open ( filename );
65 if ( fd < 0 ) {
66 file_open->Status = PXENV_STATUS ( fd );
67 return PXENV_EXIT_FAILURE;
68 }
69 DBG ( " as file %d", fd );
70
71 file_open->FileHandle = fd;
72 file_open->Status = PXENV_STATUS_SUCCESS;
73 return PXENV_EXIT_SUCCESS;
74}
75
76/**
77 * FILE CLOSE
78 *
79 * @v file_close Pointer to a struct s_PXENV_FILE_CLOSE
80 * @v s_PXENV_FILE_CLOSE::FileHandle File handle
81 * @ret #PXENV_EXIT_SUCCESS File was closed
82 * @ret #PXENV_EXIT_FAILURE File was not closed
83 * @ret s_PXENV_FILE_CLOSE::Status PXE status code
84 *
85 */
86static PXENV_EXIT_t pxenv_file_close ( struct s_PXENV_FILE_CLOSE *file_close ) {
87
88 DBG ( "PXENV_FILE_CLOSE %d", file_close->FileHandle );
89
90 close ( file_close->FileHandle );
91 file_close->Status = PXENV_STATUS_SUCCESS;
92 return PXENV_EXIT_SUCCESS;
93}
94
95/**
96 * FILE SELECT
97 *
98 * @v file_select Pointer to a struct s_PXENV_FILE_SELECT
99 * @v s_PXENV_FILE_SELECT::FileHandle File handle
100 * @ret #PXENV_EXIT_SUCCESS File has been checked for readiness
101 * @ret #PXENV_EXIT_FAILURE File has not been checked for readiness
102 * @ret s_PXENV_FILE_SELECT::Status PXE status code
103 * @ret s_PXENV_FILE_SELECT::Ready Indication of readiness
104 *
105 */
106static PXENV_EXIT_t
107pxenv_file_select ( struct s_PXENV_FILE_SELECT *file_select ) {
108 fd_set fdset;
109 int ready;
110
111 DBG ( "PXENV_FILE_SELECT %d", file_select->FileHandle );
112
113 FD_ZERO ( &fdset );
114 FD_SET ( file_select->FileHandle, &fdset );
115 if ( ( ready = select ( &fdset, 0 ) ) < 0 ) {
116 file_select->Status = PXENV_STATUS ( ready );
117 return PXENV_EXIT_FAILURE;
118 }
119
120 file_select->Ready = ( ready ? RDY_READ : 0 );
121 file_select->Status = PXENV_STATUS_SUCCESS;
122 return PXENV_EXIT_SUCCESS;
123}
124
125/**
126 * FILE READ
127 *
128 * @v file_read Pointer to a struct s_PXENV_FILE_READ
129 * @v s_PXENV_FILE_READ::FileHandle File handle
130 * @v s_PXENV_FILE_READ::BufferSize Size of data buffer
131 * @v s_PXENV_FILE_READ::Buffer Data buffer
132 * @ret #PXENV_EXIT_SUCCESS Data has been read from file
133 * @ret #PXENV_EXIT_FAILURE Data has not been read from file
134 * @ret s_PXENV_FILE_READ::Status PXE status code
135 * @ret s_PXENV_FILE_READ::Ready Indication of readiness
136 * @ret s_PXENV_FILE_READ::BufferSize Length of data read
137 *
138 */
139static PXENV_EXIT_t pxenv_file_read ( struct s_PXENV_FILE_READ *file_read ) {
140 void *buffer;
141 ssize_t len;
142
143 DBG ( "PXENV_FILE_READ %d to %04x:%04x+%04x", file_read->FileHandle,
144 file_read->Buffer.segment, file_read->Buffer.offset,
145 file_read->BufferSize );
146
147 buffer = real_to_virt ( file_read->Buffer.segment,
148 file_read->Buffer.offset );
149 if ( ( len = read ( file_read->FileHandle, buffer,
150 file_read->BufferSize ) ) < 0 ) {
151 file_read->Status = PXENV_STATUS ( len );
152 return PXENV_EXIT_FAILURE;
153 }
154
155 DBG ( " read %04zx", ( ( size_t ) len ) );
156
157 file_read->BufferSize = len;
158 file_read->Status = PXENV_STATUS_SUCCESS;
159 return PXENV_EXIT_SUCCESS;
160}
161
162/**
163 * GET FILE SIZE
164 *
165 * @v get_file_size Pointer to a struct s_PXENV_GET_FILE_SIZE
166 * @v s_PXENV_GET_FILE_SIZE::FileHandle File handle
167 * @ret #PXENV_EXIT_SUCCESS File size has been determined
168 * @ret #PXENV_EXIT_FAILURE File size has not been determined
169 * @ret s_PXENV_GET_FILE_SIZE::Status PXE status code
170 * @ret s_PXENV_GET_FILE_SIZE::FileSize Size of file
171 */
172static PXENV_EXIT_t
174 ssize_t filesize;
175
176 DBG ( "PXENV_GET_FILE_SIZE %d", get_file_size->FileHandle );
177
178 filesize = fsize ( get_file_size->FileHandle );
179 if ( filesize < 0 ) {
180 get_file_size->Status = PXENV_STATUS ( filesize );
181 return PXENV_EXIT_FAILURE;
182 }
183
184 DBG ( " is %zd", ( ( size_t ) filesize ) );
185
186 get_file_size->FileSize = filesize;
187 get_file_size->Status = PXENV_STATUS_SUCCESS;
188 return PXENV_EXIT_SUCCESS;
189}
190
191/**
192 * FILE EXEC
193 *
194 * @v file_exec Pointer to a struct s_PXENV_FILE_EXEC
195 * @v s_PXENV_FILE_EXEC::Command Command to execute
196 * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
197 * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
198 * @ret s_PXENV_FILE_EXEC::Status PXE status code
199 *
200 */
201static PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) {
202 const char *command;
203 int rc;
204
205 DBG ( "PXENV_FILE_EXEC" );
206
207 /* Execute specified command */
208 command = real_to_virt ( file_exec->Command.segment,
209 file_exec->Command.offset );
210 DBG ( " %s", command );
211 if ( ( rc = system ( command ) ) != 0 ) {
212 file_exec->Status = PXENV_STATUS ( rc );
213 return PXENV_EXIT_FAILURE;
214 }
215
216 file_exec->Status = PXENV_STATUS_SUCCESS;
217 return PXENV_EXIT_SUCCESS;
218}
219
220/**
221 * FILE CMDLINE
222 *
223 * @v file_cmdline Pointer to a struct s_PXENV_FILE_CMDLINE
224 * @v s_PXENV_FILE_CMDLINE::Buffer Buffer to contain command line
225 * @v s_PXENV_FILE_CMDLINE::BufferSize Size of buffer
226 * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
227 * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
228 * @ret s_PXENV_FILE_EXEC::Status PXE status code
229 * @ret s_PXENV_FILE_EXEC::BufferSize Length of command line (including NUL)
230 *
231 */
232static PXENV_EXIT_t
233pxenv_file_cmdline ( struct s_PXENV_FILE_CMDLINE *file_cmdline ) {
234 char *buffer;
235 size_t len;
236
237 DBG ( "PXENV_FILE_CMDLINE to %04x:%04x+%04x \"%s\"\n",
238 file_cmdline->Buffer.segment, file_cmdline->Buffer.offset,
239 file_cmdline->BufferSize, pxe_cmdline );
240
241 buffer = real_to_virt ( file_cmdline->Buffer.segment,
242 file_cmdline->Buffer.offset );
243 len = file_cmdline->BufferSize;
244 if ( pxe_cmdline ) {
245 len = snprintf ( buffer, len, "%s", pxe_cmdline );
246 file_cmdline->BufferSize = ( len + 1 /* NUL */ );
247 } else {
248 file_cmdline->BufferSize = 0;
249 }
250
251 file_cmdline->Status = PXENV_STATUS_SUCCESS;
252 return PXENV_EXIT_SUCCESS;
253}
254
255/**
256 * FILE API CHECK
257 *
258 * @v file_exec Pointer to a struct s_PXENV_FILE_API_CHECK
259 * @v s_PXENV_FILE_API_CHECK::Magic Inbound magic number (0x91d447b2)
260 * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
261 * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
262 * @ret s_PXENV_FILE_API_CHECK::Status PXE status code
263 * @ret s_PXENV_FILE_API_CHECK::Magic Outbound magic number (0xe9c17b20)
264 * @ret s_PXENV_FILE_API_CHECK::Provider "iPXE" (0x45585067)
265 * @ret s_PXENV_FILE_API_CHECK::APIMask API function bitmask
266 * @ret s_PXENV_FILE_API_CHECK::Flags Reserved
267 *
268 */
269static PXENV_EXIT_t
271 struct pxe_api_call *call;
272 unsigned int mask = 0;
273 unsigned int offset;
274
275 DBG ( "PXENV_FILE_API_CHECK" );
276
277 /* Check for magic value */
278 if ( file_api_check->Magic != 0x91d447b2 ) {
279 file_api_check->Status = PXENV_STATUS_BAD_FUNC;
280 return PXENV_EXIT_FAILURE;
281 }
282
283 /* Check for required parameter size */
284 if ( file_api_check->Size < sizeof ( *file_api_check ) ) {
285 file_api_check->Status = PXENV_STATUS_OUT_OF_RESOURCES;
286 return PXENV_EXIT_FAILURE;
287 }
288
289 /* Determine supported calls */
291 offset = ( call->opcode - PXENV_FILE_MIN );
292 if ( offset <= ( PXENV_FILE_MAX - PXENV_FILE_MIN ) )
293 mask |= ( 1 << offset );
294 }
295
296 /* Fill in parameters */
297 file_api_check->Size = sizeof ( *file_api_check );
298 file_api_check->Magic = 0xe9c17b20;
299 file_api_check->Provider = 0x45585067; /* "iPXE" */
300 file_api_check->APIMask = mask;
301 file_api_check->Flags = 0; /* None defined */
302
303 file_api_check->Status = PXENV_STATUS_SUCCESS;
304 return PXENV_EXIT_SUCCESS;
305}
306
307/** PXE file API */
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
signed long ssize_t
Definition stdint.h:7
uint16_t offset
Offset to command line.
Definition bzimage.h:3
ring len
Length.
Definition dwmac.h:226
Error codes.
uint8_t system[ETH_ALEN]
System identifier.
Definition eth_slow.h:13
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define DHCP_EB_FEATURE_PXE_EXT
PXE API extensions.
Definition features.h:37
#define FEATURE_MISC
Miscellaneous.
Definition features.h:24
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 PXENV_FILE_MIN
Minimum possible opcode used within PXE FILE API.
Definition pxe_api.h:1520
#define PXENV_FILE_MAX
Minimum possible opcode used within PXE FILE API.
Definition pxe_api.h:1523
#define PXENV_EXIT_FAILURE
An error occurred.
Definition pxe_types.h:46
#define PXENV_EXIT_SUCCESS
No error occurred.
Definition pxe_types.h:45
UINT16_t PXENV_EXIT_t
A PXE exit code.
Definition pxe_types.h:44
#define PXENV_STATUS_SUCCESS
Definition pxe_error.h:19
#define PXENV_STATUS_BAD_FUNC
Definition pxe_error.h:21
#define PXENV_STATUS_OUT_OF_RESOURCES
Definition pxe_error.h:25
#define PXENV_FILE_API_CHECK
PXE API function code for pxenv_file_api_check()
Definition pxe_api.h:1662
#define PXENV_FILE_CLOSE
PXE API function code for pxenv_file_close()
Definition pxe_api.h:1555
#define PXENV_FILE_CMDLINE
PXE API function code for pxenv_file_cmdline()
Definition pxe_api.h:1706
#define PXENV_FILE_EXEC
PXE API function code for pxenv_file_exec()
Definition pxe_api.h:1642
#define PXENV_FILE_OPEN
PXE API function code for pxenv_file_open()
Definition pxe_api.h:1533
#define PXENV_FILE_READ
PXE API function code for pxenv_file_read()
Definition pxe_api.h:1599
#define PXENV_FILE_SELECT
PXE API function code for pxenv_file_select()
Definition pxe_api.h:1575
#define RDY_READ
File is ready for reading.
Definition pxe_api.h:1578
#define PXENV_GET_FILE_SIZE
PXE API function code for pxenv_get_file_size()
Definition pxe_api.h:1621
Feature list.
#define FEATURE(category, text, feature_opt, version)
Declare a feature.
Definition features.h:101
struct option_descriptor read[1]
Definition nvo_cmd.c:116
int select(fd_set *readfds, int wait)
Check file descriptors for readiness.
Definition posix_io.c:229
ssize_t fsize(int fd)
Determine file size.
Definition posix_io.c:310
int open(const char *uri_string)
Open file.
Definition posix_io.c:176
POSIX-like I/O.
uint32_t fd_set
File descriptor set as used for select()
Definition posix_io.h:21
#define PXE_API_CALL(_opcode, _entry, _params_type)
Define a PXE API call.
Definition pxe.h:106
#define __pxe_api_call
Declare a PXE API call.
Definition pxe.h:96
#define PXE_API_CALLS
PXE API call table.
Definition pxe.h:93
#define PXENV_STATUS(rc)
Derive PXENV_STATUS code from iPXE error number.
Definition pxe_error.h:121
static PXENV_EXIT_t pxenv_file_open(struct s_PXENV_FILE_OPEN *file_open)
FILE OPEN.
Definition pxe_file.c:54
static PXENV_EXIT_t pxenv_get_file_size(struct s_PXENV_GET_FILE_SIZE *get_file_size)
GET FILE SIZE.
Definition pxe_file.c:173
static PXENV_EXIT_t pxenv_file_select(struct s_PXENV_FILE_SELECT *file_select)
FILE SELECT.
Definition pxe_file.c:107
static PXENV_EXIT_t pxenv_file_read(struct s_PXENV_FILE_READ *file_read)
FILE READ.
Definition pxe_file.c:139
static PXENV_EXIT_t pxenv_file_cmdline(struct s_PXENV_FILE_CMDLINE *file_cmdline)
FILE CMDLINE.
Definition pxe_file.c:233
static PXENV_EXIT_t pxenv_file_api_check(struct s_PXENV_FILE_API_CHECK *file_api_check)
FILE API CHECK.
Definition pxe_file.c:270
static PXENV_EXIT_t pxenv_file_close(struct s_PXENV_FILE_CLOSE *file_close)
FILE CLOSE.
Definition pxe_file.c:86
static PXENV_EXIT_t pxenv_file_exec(struct s_PXENV_FILE_EXEC *file_exec)
FILE EXEC.
Definition pxe_file.c:201
const char * pxe_cmdline
PXE command line.
Definition pxe_image.c:48
static __always_inline void * real_to_virt(unsigned int segment, unsigned int offset)
Convert segment:offset address to virtual address.
Definition realmode.h:77
A command-line command.
Definition command.h:10
A PXE API call.
Definition pxe.h:81
uint16_t opcode
Opcode.
Definition pxe.h:89
Parameter block for pxenv_file_api_check()
Definition pxe_api.h:1665
UINT32_t Magic
Magic number.
Definition pxe_api.h:1668
PXENV_STATUS_t Status
PXE status code.
Definition pxe_api.h:1666
UINT16_t Size
Size of structure.
Definition pxe_api.h:1667
UINT32_t APIMask
Supported API functions.
Definition pxe_api.h:1670
UINT32_t Flags
Reserved for the future.
Definition pxe_api.h:1671
UINT32_t Provider
Implementation identifier.
Definition pxe_api.h:1669
Parameter block for pxenv_file_close()
Definition pxe_api.h:1558
UINT16_t FileHandle
File handle.
Definition pxe_api.h:1560
PXENV_STATUS_t Status
PXE status code.
Definition pxe_api.h:1559
Parameter block for pxenv_file_cmdline()
Definition pxe_api.h:1709
SEGOFF16_t Buffer
Data buffer.
Definition pxe_api.h:1712
UINT16_t BufferSize
Data buffer size.
Definition pxe_api.h:1711
PXENV_STATUS_t Status
PXE status code.
Definition pxe_api.h:1710
Parameter block for pxenv_file_exec()
Definition pxe_api.h:1645
SEGOFF16_t Command
Command to execute.
Definition pxe_api.h:1647
PXENV_STATUS_t Status
PXE status code.
Definition pxe_api.h:1646
Parameter block for pxenv_file_open()
Definition pxe_api.h:1536
SEGOFF16_t FileName
File URL.
Definition pxe_api.h:1539
UINT16_t FileHandle
File handle.
Definition pxe_api.h:1538
PXENV_STATUS_t Status
PXE status code.
Definition pxe_api.h:1537
Parameter block for pxenv_file_read()
Definition pxe_api.h:1602
UINT16_t BufferSize
Data buffer size.
Definition pxe_api.h:1605
SEGOFF16_t Buffer
Data buffer.
Definition pxe_api.h:1606
UINT16_t FileHandle
File handle.
Definition pxe_api.h:1604
PXENV_STATUS_t Status
PXE status code.
Definition pxe_api.h:1603
Parameter block for pxenv_file_select()
Definition pxe_api.h:1581
PXENV_STATUS_t Status
PXE status code.
Definition pxe_api.h:1582
UINT16_t Ready
Indication of readiness.
Definition pxe_api.h:1584
UINT16_t FileHandle
File handle.
Definition pxe_api.h:1583
Parameter block for pxenv_get_file_size()
Definition pxe_api.h:1624
PXENV_STATUS_t Status
PXE status code.
Definition pxe_api.h:1625
UINT16_t FileHandle
File handle.
Definition pxe_api.h:1626
UINT32_t FileSize
File size.
Definition pxe_api.h:1627
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383
static struct evtchn_close * close
Definition xenevent.h:24