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