wok-6.x view gpxe/stuff/default_boot.u @ rev 1005
gpxe: fix pxenv_file_read
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Mon Jul 07 15:18:59 2008 +0000 (2008-07-07) |
parents | ff6fa8104a8c |
children | fea5060f74cd |
line source
1 --- gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
2 +++ gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
3 @@ -96,6 +96,8 @@
4 PXENV_EXIT_t ( * file_select ) ( struct s_PXENV_FILE_SELECT * );
5 PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * );
6 PXENV_EXIT_t ( * get_file_size ) ( struct s_PXENV_GET_FILE_SIZE * );
7 + PXENV_EXIT_t ( * file_exec ) ( struct s_PXENV_FILE_EXEC * );
8 + PXENV_EXIT_t ( * file_api_check ) ( struct s_PXENV_FILE_API_CHECK * );
9 };
11 /**
12 @@ -294,6 +296,14 @@
13 pxenv_call.get_file_size = pxenv_get_file_size;
14 param_len = sizeof ( pxenv_any.get_file_size );
15 break;
16 + case PXENV_FILE_EXEC:
17 + pxenv_call.file_exec = pxenv_file_exec;
18 + param_len = sizeof ( pxenv_any.file_exec );
19 + break;
20 + case PXENV_FILE_API_CHECK:
21 + pxenv_call.file_api_check = pxenv_file_api_check;
22 + param_len = sizeof ( pxenv_any.file_api_check );
23 + break;
24 default:
25 DBG ( "PXENV_UNKNOWN_%hx", opcode );
26 pxenv_call.unknown = pxenv_unknown;
28 --- gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
29 +++ gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
30 @@ -441,6 +441,8 @@
31 /* Calculated lcall to _start with %cs:0000 = image start */
32 lret
34 +boot_url:
35 + .space 256, 0
37 .org PREFIXSIZE
38 /*
39 @@ -453,6 +455,15 @@
40 movw %bx, %ss
41 movw $_estack16, %sp
43 + /* Copy our boot_url structure to the forced_url variable */
44 + push %cs
45 + pop %ds
46 + movw %bx, %es
47 + movw $forced_url, %di
48 + movw $boot_url, %si
49 + movw $256, %cx
50 + rep movsb
51 +
52 /* Jump to .text16 segment */
53 pushw %ax
54 pushw $1f
56 --- gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
57 +++ gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
58 @@ -19,6 +19,9 @@
59 .section ".prefix"
60 /* Set up our non-stack segment registers */
61 jmp $0x7c0, $1f
62 +#define PXELOADER_KEEP_UNDI
63 +boot_url:
64 + .space 256, 0
65 1: movw %cs, %ax
66 movw %ax, %ds
67 movw $0x40, %ax /* BIOS data segment access */
68 @@ -703,16 +706,22 @@
69 /* Set up real-mode stack */
70 movw %bx, %ss
71 movw $_estack16, %sp
72 -
73 + movw %bx, %es
74 +
75 #ifdef PXELOADER_KEEP_UNDI
76 /* Copy our undi_device structure to the preloaded_undi variable */
77 - movw %bx, %es
78 movw $preloaded_undi, %di
79 movw $undi_device, %si
80 movw $undi_device_size, %cx
81 rep movsb
82 #endif
84 + /* Copy our boot_url structure to the forced_url variable */
85 + movw $forced_url, %di
86 + movw $boot_url, %si
87 + movw $256, %cx
88 + rep movsb
89 +
90 /* Jump to .text16 segment with %ds pointing to .data16 */
91 movw %bx, %ds
92 pushw %ax
94 --- gpxe-0.9.3/src/include/pxe_api.h
95 +++ gpxe-0.9.3/src/include/pxe_api.h
96 @@ -1684,6 +1684,54 @@
98 /** @} */ /* pxenv_get_file_size */
100 +/** @defgroup pxenv_file_exec PXENV_FILE_EXEC
101 + *
102 + * FILE EXEC
103 + *
104 + * @{
105 + */
106 +
107 +/** PXE API function code for pxenv_file_exec() */
108 +#define PXENV_FILE_EXEC 0x00e5
109 +
110 +/** Parameter block for pxenv_file_exec() */
111 +struct s_PXENV_FILE_EXEC {
112 + PXENV_STATUS_t Status; /**< PXE status code */
113 + SEGOFF16_t Command; /**< Command to execute */
114 +} PACKED;
115 +
116 +typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t;
117 +
118 +extern PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec );
119 +
120 +/** @} */ /* pxenv_file_exec */
121 +
122 +/** @defgroup pxenv_file_api_check PXENV_FILE_API_CHECK
123 + *
124 + * FILE API CHECK
125 + *
126 + * @{
127 + */
128 +
129 +/** PXE API function code for pxenv_file_api_check() */
130 +#define PXENV_FILE_API_CHECK 0x00e6
131 +
132 +/** Parameter block for pxenv_file_api_check() */
133 +struct s_PXENV_FILE_API_CHECK {
134 + PXENV_STATUS_t Status; /**< PXE status code */
135 + UINT16_t Size; /**< Size of structure */
136 + UINT32_t Magic; /**< Magic number */
137 + UINT32_t Provider; /**< Implementation identifier */
138 + UINT32_t APIMask; /**< Supported API functions */
139 + UINT32_t Flags; /**< Reserved for the future */
140 +} PACKED;
141 +
142 +typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t;
143 +
144 +extern PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check );
145 +
146 +/** @} */ /* pxenv_file_api_check */
147 +
148 /** @} */ /* pxe_file_api */
150 /** @defgroup pxe_loader_api PXE Loader API
152 --- gpxe-0.9.3/src/include/pxe.h
153 +++ gpxe-0.9.3/src/include/pxe.h
154 @@ -63,6 +63,8 @@
155 struct s_PXENV_FILE_SELECT file_select;
156 struct s_PXENV_FILE_READ file_read;
157 struct s_PXENV_GET_FILE_SIZE get_file_size;
158 + struct s_PXENV_FILE_EXEC file_exec;
159 + struct s_PXENV_FILE_API_CHECK file_api_check;
160 };
162 typedef union u_PXENV_ANY PXENV_ANY_t;
164 --- gpxe-0.9.3/src/interface/pxe/pxe_file.c
165 +++ gpxe-0.9.3/src/interface/pxe/pxe_file.c
166 @@ -31,7 +31,7 @@
167 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
168 */
170 -FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 1 );
171 +FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 );
173 /**
174 * FILE OPEN
175 @@ -148,12 +148,14 @@
177 buffer = real_to_user ( file_read->Buffer.segment,
178 file_read->Buffer.offset );
179 - if ( ( len = read_user ( file_read->FileHandle, buffer, 0,
180 + while ( ( len = read_user ( file_read->FileHandle, buffer, 0,
181 file_read->BufferSize ) ) < 0 ) {
182 file_read->Status = PXENV_STATUS ( len );
183 + if (len == (ssize_t) -1309286401 /* -EWOULDBLOCK */ ) {
184 + continue;
185 + }
186 return PXENV_EXIT_FAILURE;
187 }
188 -
189 DBG ( " read %04zx", ( ( size_t ) len ) );
191 file_read->BufferSize = len;
192 @@ -189,3 +191,76 @@
193 get_file_size->Status = PXENV_STATUS_SUCCESS;
194 return PXENV_EXIT_SUCCESS;
195 }
196 +
197 +/**
198 + * FILE EXEC
199 + *
200 + * @v file_exec Pointer to a struct s_PXENV_FILE_EXEC
201 + * @v s_PXENV_FILE_EXEC::Command Command to execute
202 + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
203 + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
204 + * @ret s_PXENV_FILE_EXEC::Status PXE status code
205 + *
206 + */
207 +PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) {
208 + userptr_t command;
209 + size_t command_len;
210 + int rc;
211 +
212 + DBG ( "PXENV_FILE_EXEC" );
213 +
214 + /* Copy name from external program, and exec it */
215 + command = real_to_user ( file_exec->Command.segment,
216 + file_exec->Command.offset );
217 + command_len = strlen_user ( command, 0 );
218 + {
219 + char command_string[ command_len + 1 ];
220 +
221 + copy_from_user ( command_string, command, 0,
222 + sizeof ( command_string ) );
223 + DBG ( " %s", command_string );
224 +
225 + if ( ( rc = system ( command_string ) ) != 0 ) {
226 + file_exec->Status = PXENV_STATUS ( rc );
227 + return PXENV_EXIT_FAILURE;
228 + }
229 + }
230 +
231 + file_exec->Status = PXENV_STATUS_SUCCESS;
232 + return PXENV_EXIT_SUCCESS;
233 +}
234 +
235 +/**
236 + * FILE API CHECK
237 + *
238 + * @v file_exec Pointer to a struct s_PXENV_FILE_API_CHECK
239 + * @v s_PXENV_FILE_API_CHECK::Magic Inbound magic number (0x91d447b2)
240 + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
241 + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
242 + * @ret s_PXENV_FILE_API_CHECK::Status PXE status code
243 + * @ret s_PXENV_FILE_API_CHECK::Magic Outbound magic number (0xe9c17b20)
244 + * @ret s_PXENV_FILE_API_CHECK::Provider "gPXE" (0x45585067)
245 + * @ret s_PXENV_FILE_API_CHECK::APIMask API function bitmask
246 + * @ret s_PXENV_FILE_API_CHECK::Flags Reserved
247 + *
248 + */
249 +PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ) {
250 + DBG ( "PXENV_FILE_API_CHECK" );
251 +
252 + if ( file_api_check->Magic != 0x91d447b2 ) {
253 + file_api_check->Status = PXENV_STATUS_BAD_FUNC;
254 + return PXENV_EXIT_FAILURE;
255 + } else if ( file_api_check->Size <
256 + sizeof(struct s_PXENV_FILE_API_CHECK) ) {
257 + file_api_check->Status = PXENV_STATUS_OUT_OF_RESOURCES;
258 + return PXENV_EXIT_FAILURE;
259 + } else {
260 + file_api_check->Status = PXENV_STATUS_SUCCESS;
261 + file_api_check->Size = sizeof(struct s_PXENV_FILE_API_CHECK);
262 + file_api_check->Magic = 0xe9c17b20;
263 + file_api_check->Provider = 0x45585067; /* "gPXE" */
264 + file_api_check->APIMask = 0x0000007f; /* Functions e0-e6 */
265 + file_api_check->Flags = 0; /* None defined */
266 + return PXENV_EXIT_SUCCESS;
267 + }
268 +}
269 --- gpxe-0.9.3/src/usr/autoboot.c
270 +++ gpxe-0.9.3/src/usr/autoboot.c
271 @@ -120,6 +120,28 @@
272 return -ENOTSUP;
273 }
275 +static void set_url ( char buf[], const char url[] ) {
276 + int i, d = 0;
277 +
278 + for (i = 0; url[i] >= ' '; i++) {
279 + if (url[i] == '/') d = i;
280 + buf[i] = url[i];
281 + }
282 + buf[i] = 0;
283 + if (strstr(buf,"pxelinux")) {
284 + struct dhcp_option_block *options = list_entry (
285 + dhcp_option_blocks.next, typeof ( *options ), list );
286 +
287 + set_dhcp_option( options, 208, "\xF1\x00\x74\x7E", 4 );
288 + set_dhcp_option( options, 210, buf, d+1 );
289 + }
290 +}
291 +
292 +struct _forced_url {
293 + char url[256];
294 +};
295 +struct _forced_url __data16 ( forced_url );
296 +#define forced_url __use_data16 ( forced_url )
297 /**
298 * Boot from a network device
299 *
300 @@ -148,6 +170,12 @@
301 /* Try to download and boot whatever we are given as a filename */
302 dhcp_snprintf ( buf, sizeof ( buf ),
303 find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
304 +
305 + if ( forced_url.url[0] != 0 ) {
306 + /* Try to boot a forced url if we have one */
307 + set_url ( buf, forced_url.url );
308 + }
309 + while (1) {
310 if ( buf[0] ) {
311 printf ( "Booting from filename \"%s\"\n", buf );
312 return boot_filename ( buf );
313 @@ -162,7 +190,8 @@
314 }
316 printf ( "No filename or root path specified\n" );
317 - return -ENOENT;
318 + set_url ( buf, "http://boot.slitaz.org/gpxe" );
319 + }
320 }
322 /**
324 --- gpxe-0.9.3/src/interface/pxe/pxe_tftp.c
325 +++ gpxe-0.9.3/src/interface/pxe/pxe_tftp.c
326 @@ -189,7 +189,7 @@
327 if ( blksize < TFTP_DEFAULT_BLKSIZE )
328 blksize = TFTP_DEFAULT_BLKSIZE;
329 snprintf ( uri_string, sizeof ( uri_string ),
330 - "tftp://%s:%d%s%s?blksize=%d",
331 + "tftp://%s:%d%s%s?blksize=%zd",
332 inet_ntoa ( address ), ntohs ( port ),
333 ( ( filename[0] == '/' ) ? "" : "/" ), filename, blksize );
334 DBG ( " %s", uri_string );
335 --- gpxe-0.9.3/src/core/posix_io.c
336 +++ gpxe-0.9.3/src/core/posix_io.c
337 @@ -114,7 +114,7 @@
338 static int
339 posix_file_xfer_deliver_iob ( struct xfer_interface *xfer,
340 struct io_buffer *iobuf,
341 - struct xfer_metadata *meta __unused ) {
342 + struct xfer_metadata *meta ) {
343 struct posix_file *file =
344 container_of ( xfer, struct posix_file, xfer );
346 @@ -125,7 +125,12 @@
347 if ( file->filesize < file->pos )
348 file->filesize = file->pos;
350 - list_add_tail ( &iobuf->list, &file->data );
351 + if ( iob_len ( iobuf ) ) {
352 + list_add_tail ( &iobuf->list, &file->data );
353 + } else {
354 + free_iob ( iobuf );
355 + }
356 +
357 return 0;
358 }
360 @@ -293,12 +298,15 @@
361 free_iob ( iobuf );
362 }
363 file->pos += len;
364 + assert ( len != 0 );
365 return len;
366 }
368 /* If file has completed, return (after returning all data) */
369 - if ( file->rc != -EINPROGRESS )
370 + if ( file->rc != -EINPROGRESS ) {
371 + assert ( list_empty ( &file->data ) );
372 return file->rc;
373 + }
375 /* No data ready and file still in progress; return -WOULDBLOCK */
376 return -EWOULDBLOCK;