rev |
line source |
pascal@1001
|
1 --- gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
|
pascal@1001
|
2 +++ gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
|
pascal@1001
|
3 @@ -96,6 +96,8 @@
|
pascal@1001
|
4 PXENV_EXIT_t ( * file_select ) ( struct s_PXENV_FILE_SELECT * );
|
pascal@1001
|
5 PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * );
|
pascal@1001
|
6 PXENV_EXIT_t ( * get_file_size ) ( struct s_PXENV_GET_FILE_SIZE * );
|
pascal@1001
|
7 + PXENV_EXIT_t ( * file_exec ) ( struct s_PXENV_FILE_EXEC * );
|
pascal@1001
|
8 + PXENV_EXIT_t ( * file_api_check ) ( struct s_PXENV_FILE_API_CHECK * );
|
pascal@1001
|
9 };
|
pascal@1001
|
10
|
pascal@1001
|
11 /**
|
pascal@1001
|
12 @@ -294,6 +296,14 @@
|
pascal@1001
|
13 pxenv_call.get_file_size = pxenv_get_file_size;
|
pascal@1001
|
14 param_len = sizeof ( pxenv_any.get_file_size );
|
pascal@1001
|
15 break;
|
pascal@1001
|
16 + case PXENV_FILE_EXEC:
|
pascal@1001
|
17 + pxenv_call.file_exec = pxenv_file_exec;
|
pascal@1001
|
18 + param_len = sizeof ( pxenv_any.file_exec );
|
pascal@1001
|
19 + break;
|
pascal@1001
|
20 + case PXENV_FILE_API_CHECK:
|
pascal@1001
|
21 + pxenv_call.file_api_check = pxenv_file_api_check;
|
pascal@1001
|
22 + param_len = sizeof ( pxenv_any.file_api_check );
|
pascal@1001
|
23 + break;
|
pascal@1001
|
24 default:
|
pascal@1001
|
25 DBG ( "PXENV_UNKNOWN_%hx", opcode );
|
pascal@1001
|
26 pxenv_call.unknown = pxenv_unknown;
|
pascal@1001
|
27
|
pascal@962
|
28 --- gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
|
pascal@962
|
29 +++ gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
|
pascal@1001
|
30 @@ -441,6 +441,8 @@
|
pascal@962
|
31 /* Calculated lcall to _start with %cs:0000 = image start */
|
pascal@962
|
32 lret
|
pascal@962
|
33
|
pascal@962
|
34 +boot_url:
|
pascal@1001
|
35 + .space 256, 0
|
pascal@962
|
36
|
pascal@962
|
37 .org PREFIXSIZE
|
pascal@962
|
38 /*
|
pascal@962
|
39 @@ -453,6 +455,13 @@
|
pascal@962
|
40 movw %bx, %ss
|
pascal@962
|
41 movw $_estack16, %sp
|
pascal@962
|
42
|
pascal@962
|
43 + /* Copy our boot_url structure to the forced_url variable */
|
pascal@962
|
44 + movw %bx, %es
|
pascal@962
|
45 + movw $forced_url, %di
|
pascal@962
|
46 + movw $boot_url, %si
|
pascal@1001
|
47 + movw $256, %cx
|
pascal@962
|
48 + rep movsb
|
pascal@962
|
49 +
|
pascal@962
|
50 /* Jump to .text16 segment */
|
pascal@962
|
51 pushw %ax
|
pascal@962
|
52 pushw $1f
|
pascal@962
|
53
|
pascal@962
|
54 --- gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
|
pascal@962
|
55 +++ gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
|
pascal@1001
|
56 @@ -19,6 +19,9 @@
|
pascal@962
|
57 .section ".prefix"
|
pascal@962
|
58 /* Set up our non-stack segment registers */
|
pascal@962
|
59 jmp $0x7c0, $1f
|
pascal@1001
|
60 +#define PXELOADER_KEEP_UNDI
|
pascal@962
|
61 +boot_url:
|
pascal@1001
|
62 + .space 256, 0
|
pascal@962
|
63 1: movw %cs, %ax
|
pascal@962
|
64 movw %ax, %ds
|
pascal@962
|
65 movw $0x40, %ax /* BIOS data segment access */
|
pascal@1001
|
66 @@ -703,16 +706,22 @@
|
pascal@962
|
67 /* Set up real-mode stack */
|
pascal@962
|
68 movw %bx, %ss
|
pascal@962
|
69 movw $_estack16, %sp
|
pascal@962
|
70 -
|
pascal@962
|
71 + movw %bx, %es
|
pascal@962
|
72 +
|
pascal@962
|
73 #ifdef PXELOADER_KEEP_UNDI
|
pascal@962
|
74 /* Copy our undi_device structure to the preloaded_undi variable */
|
pascal@962
|
75 - movw %bx, %es
|
pascal@962
|
76 movw $preloaded_undi, %di
|
pascal@962
|
77 movw $undi_device, %si
|
pascal@962
|
78 movw $undi_device_size, %cx
|
pascal@962
|
79 rep movsb
|
pascal@962
|
80 #endif
|
pascal@962
|
81
|
pascal@962
|
82 + /* Copy our boot_url structure to the forced_url variable */
|
pascal@962
|
83 + movw $forced_url, %di
|
pascal@962
|
84 + movw $boot_url, %si
|
pascal@1001
|
85 + movw $256, %cx
|
pascal@962
|
86 + rep movsb
|
pascal@962
|
87 +
|
pascal@962
|
88 /* Jump to .text16 segment with %ds pointing to .data16 */
|
pascal@962
|
89 movw %bx, %ds
|
pascal@962
|
90 pushw %ax
|
pascal@962
|
91
|
pascal@1001
|
92 --- gpxe-0.9.3/src/include/pxe_api.h
|
pascal@1001
|
93 +++ gpxe-0.9.3/src/include/pxe_api.h
|
pascal@1001
|
94 @@ -1684,6 +1684,54 @@
|
pascal@1001
|
95
|
pascal@1001
|
96 /** @} */ /* pxenv_get_file_size */
|
pascal@1001
|
97
|
pascal@1001
|
98 +/** @defgroup pxenv_file_exec PXENV_FILE_EXEC
|
pascal@1001
|
99 + *
|
pascal@1001
|
100 + * FILE EXEC
|
pascal@1001
|
101 + *
|
pascal@1001
|
102 + * @{
|
pascal@1001
|
103 + */
|
pascal@1001
|
104 +
|
pascal@1001
|
105 +/** PXE API function code for pxenv_file_exec() */
|
pascal@1001
|
106 +#define PXENV_FILE_EXEC 0x00e5
|
pascal@1001
|
107 +
|
pascal@1001
|
108 +/** Parameter block for pxenv_file_exec() */
|
pascal@1001
|
109 +struct s_PXENV_FILE_EXEC {
|
pascal@1001
|
110 + PXENV_STATUS_t Status; /**< PXE status code */
|
pascal@1001
|
111 + SEGOFF16_t Command; /**< Command to execute */
|
pascal@1001
|
112 +} PACKED;
|
pascal@1001
|
113 +
|
pascal@1001
|
114 +typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t;
|
pascal@1001
|
115 +
|
pascal@1001
|
116 +extern PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec );
|
pascal@1001
|
117 +
|
pascal@1001
|
118 +/** @} */ /* pxenv_file_exec */
|
pascal@1001
|
119 +
|
pascal@1001
|
120 +/** @defgroup pxenv_file_api_check PXENV_FILE_API_CHECK
|
pascal@1001
|
121 + *
|
pascal@1001
|
122 + * FILE API CHECK
|
pascal@1001
|
123 + *
|
pascal@1001
|
124 + * @{
|
pascal@1001
|
125 + */
|
pascal@1001
|
126 +
|
pascal@1001
|
127 +/** PXE API function code for pxenv_file_api_check() */
|
pascal@1001
|
128 +#define PXENV_FILE_API_CHECK 0x00e6
|
pascal@1001
|
129 +
|
pascal@1001
|
130 +/** Parameter block for pxenv_file_api_check() */
|
pascal@1001
|
131 +struct s_PXENV_FILE_API_CHECK {
|
pascal@1001
|
132 + PXENV_STATUS_t Status; /**< PXE status code */
|
pascal@1001
|
133 + UINT16_t Size; /**< Size of structure */
|
pascal@1001
|
134 + UINT32_t Magic; /**< Magic number */
|
pascal@1001
|
135 + UINT32_t Provider; /**< Implementation identifier */
|
pascal@1001
|
136 + UINT32_t APIMask; /**< Supported API functions */
|
pascal@1001
|
137 + UINT32_t Flags; /**< Reserved for the future */
|
pascal@1001
|
138 +} PACKED;
|
pascal@1001
|
139 +
|
pascal@1001
|
140 +typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t;
|
pascal@1001
|
141 +
|
pascal@1001
|
142 +extern PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check );
|
pascal@1001
|
143 +
|
pascal@1001
|
144 +/** @} */ /* pxenv_file_api_check */
|
pascal@1001
|
145 +
|
pascal@1001
|
146 /** @} */ /* pxe_file_api */
|
pascal@1001
|
147
|
pascal@1001
|
148 /** @defgroup pxe_loader_api PXE Loader API
|
pascal@1001
|
149
|
pascal@1001
|
150 --- gpxe-0.9.3/src/include/pxe.h
|
pascal@1001
|
151 +++ gpxe-0.9.3/src/include/pxe.h
|
pascal@1001
|
152 @@ -63,6 +63,8 @@
|
pascal@1001
|
153 struct s_PXENV_FILE_SELECT file_select;
|
pascal@1001
|
154 struct s_PXENV_FILE_READ file_read;
|
pascal@1001
|
155 struct s_PXENV_GET_FILE_SIZE get_file_size;
|
pascal@1001
|
156 + struct s_PXENV_FILE_EXEC file_exec;
|
pascal@1001
|
157 + struct s_PXENV_FILE_API_CHECK file_api_check;
|
pascal@1001
|
158 };
|
pascal@1001
|
159
|
pascal@1001
|
160 typedef union u_PXENV_ANY PXENV_ANY_t;
|
pascal@1001
|
161
|
pascal@1001
|
162 --- gpxe-0.9.3/src/interface/pxe/pxe_file.c
|
pascal@1001
|
163 +++ gpxe-0.9.3/src/interface/pxe/pxe_file.c
|
pascal@1001
|
164 @@ -31,7 +31,7 @@
|
pascal@1001
|
165 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
pascal@1001
|
166 */
|
pascal@1001
|
167
|
pascal@1001
|
168 -FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 1 );
|
pascal@1001
|
169 +FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 );
|
pascal@1001
|
170
|
pascal@1001
|
171 /**
|
pascal@1001
|
172 * FILE OPEN
|
pascal@1001
|
173 @@ -189,3 +189,76 @@
|
pascal@1001
|
174 get_file_size->Status = PXENV_STATUS_SUCCESS;
|
pascal@1001
|
175 return PXENV_EXIT_SUCCESS;
|
pascal@1001
|
176 }
|
pascal@1001
|
177 +
|
pascal@1001
|
178 +/**
|
pascal@1001
|
179 + * FILE EXEC
|
pascal@1001
|
180 + *
|
pascal@1001
|
181 + * @v file_exec Pointer to a struct s_PXENV_FILE_EXEC
|
pascal@1001
|
182 + * @v s_PXENV_FILE_EXEC::Command Command to execute
|
pascal@1001
|
183 + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
|
pascal@1001
|
184 + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
|
pascal@1001
|
185 + * @ret s_PXENV_FILE_EXEC::Status PXE status code
|
pascal@1001
|
186 + *
|
pascal@1001
|
187 + */
|
pascal@1001
|
188 +PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) {
|
pascal@1001
|
189 + userptr_t command;
|
pascal@1001
|
190 + size_t command_len;
|
pascal@1001
|
191 + int rc;
|
pascal@1001
|
192 +
|
pascal@1001
|
193 + DBG ( "PXENV_FILE_EXEC" );
|
pascal@1001
|
194 +
|
pascal@1001
|
195 + /* Copy name from external program, and exec it */
|
pascal@1001
|
196 + command = real_to_user ( file_exec->Command.segment,
|
pascal@1001
|
197 + file_exec->Command.offset );
|
pascal@1001
|
198 + command_len = strlen_user ( command, 0 );
|
pascal@1001
|
199 + {
|
pascal@1001
|
200 + char command_string[ command_len + 1 ];
|
pascal@1001
|
201 +
|
pascal@1001
|
202 + copy_from_user ( command_string, command, 0,
|
pascal@1001
|
203 + sizeof ( command_string ) );
|
pascal@1001
|
204 + DBG ( " %s", command_string );
|
pascal@1001
|
205 +
|
pascal@1001
|
206 + if ( ( rc = system ( command_string ) ) != 0 ) {
|
pascal@1001
|
207 + file_exec->Status = PXENV_STATUS ( rc );
|
pascal@1001
|
208 + return PXENV_EXIT_FAILURE;
|
pascal@1001
|
209 + }
|
pascal@1001
|
210 + }
|
pascal@1001
|
211 +
|
pascal@1001
|
212 + file_exec->Status = PXENV_STATUS_SUCCESS;
|
pascal@1001
|
213 + return PXENV_EXIT_SUCCESS;
|
pascal@1001
|
214 +}
|
pascal@1001
|
215 +
|
pascal@1001
|
216 +/**
|
pascal@1001
|
217 + * FILE API CHECK
|
pascal@1001
|
218 + *
|
pascal@1001
|
219 + * @v file_exec Pointer to a struct s_PXENV_FILE_API_CHECK
|
pascal@1001
|
220 + * @v s_PXENV_FILE_API_CHECK::Magic Inbound magic number (0x91d447b2)
|
pascal@1001
|
221 + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
|
pascal@1001
|
222 + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
|
pascal@1001
|
223 + * @ret s_PXENV_FILE_API_CHECK::Status PXE status code
|
pascal@1001
|
224 + * @ret s_PXENV_FILE_API_CHECK::Magic Outbound magic number (0xe9c17b20)
|
pascal@1001
|
225 + * @ret s_PXENV_FILE_API_CHECK::Provider "gPXE" (0x45585067)
|
pascal@1001
|
226 + * @ret s_PXENV_FILE_API_CHECK::APIMask API function bitmask
|
pascal@1001
|
227 + * @ret s_PXENV_FILE_API_CHECK::Flags Reserved
|
pascal@1001
|
228 + *
|
pascal@1001
|
229 + */
|
pascal@1001
|
230 +PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ) {
|
pascal@1001
|
231 + DBG ( "PXENV_FILE_API_CHECK" );
|
pascal@1001
|
232 +
|
pascal@1001
|
233 + if ( file_api_check->Magic != 0x91d447b2 ) {
|
pascal@1001
|
234 + file_api_check->Status = PXENV_STATUS_BAD_FUNC;
|
pascal@1001
|
235 + return PXENV_EXIT_FAILURE;
|
pascal@1001
|
236 + } else if ( file_api_check->Size <
|
pascal@1001
|
237 + sizeof(struct s_PXENV_FILE_API_CHECK) ) {
|
pascal@1001
|
238 + file_api_check->Status = PXENV_STATUS_OUT_OF_RESOURCES;
|
pascal@1001
|
239 + return PXENV_EXIT_FAILURE;
|
pascal@1001
|
240 + } else {
|
pascal@1001
|
241 + file_api_check->Status = PXENV_STATUS_SUCCESS;
|
pascal@1001
|
242 + file_api_check->Size = sizeof(struct s_PXENV_FILE_API_CHECK);
|
pascal@1001
|
243 + file_api_check->Magic = 0xe9c17b20;
|
pascal@1001
|
244 + file_api_check->Provider = 0x45585067; /* "gPXE" */
|
pascal@1001
|
245 + file_api_check->APIMask = 0x0000007f; /* Functions e0-e6 */
|
pascal@1001
|
246 + file_api_check->Flags = 0; /* None defined */
|
pascal@1001
|
247 + return PXENV_EXIT_SUCCESS;
|
pascal@1001
|
248 + }
|
pascal@1001
|
249 +}
|
pascal@1001
|
250
|
pascal@955
|
251 --- gpxe-0.9.3/src/usr/autoboot.c
|
pascal@955
|
252 +++ gpxe-0.9.3/src/usr/autoboot.c
|
pascal@1001
|
253 @@ -120,6 +120,28 @@
|
pascal@962
|
254 return -ENOTSUP;
|
pascal@962
|
255 }
|
pascal@962
|
256
|
pascal@1001
|
257 +static void set_url ( char buf[], const char url[] ) {
|
pascal@1001
|
258 + int i, d = 0;
|
pascal@1001
|
259 +
|
pascal@1001
|
260 + for (i = 0; url[i] >= ' '; i++) {
|
pascal@1001
|
261 + if (url[i] == '/') d = i;
|
pascal@1001
|
262 + buf[i] = url[i];
|
pascal@1001
|
263 + }
|
pascal@1001
|
264 + buf[i] = 0;
|
pascal@1001
|
265 + if (strstr(buf,"pxelinux")) {
|
pascal@1001
|
266 + struct dhcp_option_block *options = list_entry (
|
pascal@1001
|
267 + dhcp_option_blocks.next, typeof ( *options ), list );
|
pascal@1001
|
268 +
|
pascal@1001
|
269 + set_dhcp_option( options, 208, "\xF1\x00\x74\x7E", 4 );
|
pascal@1001
|
270 + set_dhcp_option( options, 210, buf, d+1 );
|
pascal@1001
|
271 + }
|
pascal@1001
|
272 +}
|
pascal@1001
|
273 +
|
pascal@962
|
274 +struct _forced_url {
|
pascal@1001
|
275 + char url[256];
|
pascal@962
|
276 +};
|
pascal@962
|
277 +struct _forced_url __data16 ( forced_url );
|
pascal@962
|
278 +#define forced_url __use_data16 ( forced_url )
|
pascal@962
|
279 /**
|
pascal@962
|
280 * Boot from a network device
|
pascal@962
|
281 *
|
pascal@1001
|
282 @@ -148,6 +170,12 @@
|
pascal@962
|
283 /* Try to download and boot whatever we are given as a filename */
|
pascal@962
|
284 dhcp_snprintf ( buf, sizeof ( buf ),
|
pascal@955
|
285 find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
|
pascal@1001
|
286 +
|
pascal@1001
|
287 + if ( forced_url.url[0] != 0 ) {
|
pascal@1001
|
288 + /* Try to boot a forced url if we have one */
|
pascal@1001
|
289 + set_url ( buf, forced_url.url );
|
pascal@1001
|
290 + }
|
pascal@962
|
291 + while (1) {
|
pascal@955
|
292 if ( buf[0] ) {
|
pascal@962
|
293 printf ( "Booting from filename \"%s\"\n", buf );
|
pascal@962
|
294 return boot_filename ( buf );
|
pascal@1001
|
295 @@ -162,7 +190,8 @@
|
pascal@962
|
296 }
|
pascal@962
|
297
|
pascal@955
|
298 printf ( "No filename or root path specified\n" );
|
pascal@955
|
299 - return -ENOENT;
|
pascal@1001
|
300 + set_url ( buf, "http://boot.slitaz.org/gpxe" );
|
pascal@962
|
301 + }
|
pascal@955
|
302 }
|
pascal@962
|
303
|
pascal@962
|
304 /**
|