|
@@ -14,145 +14,44 @@ Literature dealing with the network protocols:
|
14
|
14
|
|
15
|
15
|
**************************************************************************/
|
16
|
16
|
|
17
|
|
-/* #define MDEBUG */
|
18
|
|
-
|
19
|
|
-#include "etherboot.h"
|
20
|
|
-#include "dev.h"
|
21
|
|
-#include "nic.h"
|
22
|
|
-#include "disk.h"
|
23
|
|
-#include "timer.h"
|
24
|
|
-#include "cpu.h"
|
25
|
|
-#include "cmdline.h"
|
26
|
|
-#include "console.h"
|
|
17
|
+#include <gpxe/heap.h>
|
27
|
18
|
#include <gpxe/init.h>
|
28
|
|
-#include <stdarg.h>
|
29
|
|
-
|
30
|
19
|
#include <gpxe/device.h>
|
31
|
|
-#include <gpxe/heap.h>
|
32
|
|
-#include <gpxe/netdevice.h>
|
33
|
20
|
#include <gpxe/shell.h>
|
34
|
21
|
#include <gpxe/shell_banner.h>
|
|
22
|
+#include <gpxe/shutdown.h>
|
35
|
23
|
#include <usr/autoboot.h>
|
36
|
24
|
|
37
|
|
-/* Linker symbols */
|
38
|
|
-extern char _bss[], _ebss[];
|
39
|
|
-
|
40
|
|
-jmp_buf restart_etherboot;
|
41
|
|
-int url_port;
|
42
|
|
-
|
43
|
|
-char as_main_program = 1;
|
44
|
|
-
|
45
|
|
-#if 0
|
46
|
|
-
|
47
|
|
-static inline unsigned long ask_boot(unsigned *index)
|
48
|
|
-{
|
49
|
|
- unsigned long order = DEFAULT_BOOT_ORDER;
|
50
|
|
- *index = DEFAULT_BOOT_INDEX;
|
51
|
|
-#ifdef LINUXBIOS
|
52
|
|
- order = get_boot_order(order, index);
|
53
|
|
-#endif
|
54
|
|
-#if defined(ASK_BOOT)
|
55
|
|
-#if ASK_BOOT >= 0
|
56
|
|
- while(1) {
|
57
|
|
- int c = 0;
|
58
|
|
- printf(ASK_PROMPT);
|
59
|
|
-#if ASK_BOOT > 0
|
60
|
|
- {
|
61
|
|
- unsigned long time;
|
62
|
|
- for ( time = currticks() + ASK_BOOT*TICKS_PER_SEC;
|
63
|
|
- !c && !iskey(); ) {
|
64
|
|
- if (currticks() > time) c = ANS_DEFAULT;
|
65
|
|
- }
|
66
|
|
- }
|
67
|
|
-#endif /* ASK_BOOT > 0 */
|
68
|
|
- if ( !c ) c = getchar();
|
69
|
|
- if ((c >= 'a') && (c <= 'z')) c &= 0x5F;
|
70
|
|
- if ((c >= ' ') && (c <= '~')) putchar(c);
|
71
|
|
- putchar('\n');
|
72
|
|
-
|
73
|
|
- switch(c) {
|
74
|
|
- default:
|
75
|
|
- /* Nothing useful try again */
|
76
|
|
- continue;
|
77
|
|
- case ANS_QUIT:
|
78
|
|
- order = BOOT_NOTHING;
|
79
|
|
- *index = 0;
|
80
|
|
- break;
|
81
|
|
- case ANS_DEFAULT:
|
82
|
|
- /* Preserve the default boot order */
|
83
|
|
- break;
|
84
|
|
- case ANS_NETWORK:
|
85
|
|
- order = (BOOT_NIC << (0*BOOT_BITS)) |
|
86
|
|
- (BOOT_NOTHING << (1*BOOT_BITS));
|
87
|
|
- *index = 0;
|
88
|
|
- break;
|
89
|
|
- case ANS_DISK:
|
90
|
|
- order = (BOOT_DISK << (0*BOOT_BITS)) |
|
91
|
|
- (BOOT_NOTHING << (1*BOOT_BITS));
|
92
|
|
- *index = 0;
|
93
|
|
- break;
|
94
|
|
- case ANS_FLOPPY:
|
95
|
|
- order = (BOOT_FLOPPY << (0*BOOT_BITS)) |
|
96
|
|
- (BOOT_NOTHING << (1*BOOT_BITS));
|
97
|
|
- *index = 0;
|
98
|
|
- break;
|
99
|
|
- }
|
100
|
|
- break;
|
101
|
|
- }
|
102
|
|
- putchar('\n');
|
103
|
|
-#endif /* ASK_BOOT >= 0 */
|
104
|
|
-#endif /* defined(ASK_BOOT) */
|
105
|
|
- return order;
|
106
|
|
-}
|
107
|
|
-
|
108
|
|
-static inline void try_floppy_first(void)
|
109
|
|
-{
|
110
|
|
-#if (TRY_FLOPPY_FIRST > 0)
|
111
|
|
- int i;
|
112
|
|
- printf("Trying floppy");
|
113
|
|
- disk_init();
|
114
|
|
- for (i = TRY_FLOPPY_FIRST; i-- > 0; ) {
|
115
|
|
- putchar('.');
|
116
|
|
- if (pcbios_disk_read(0, 0, 0, 0, ((char *)FLOPPY_BOOT_LOCATION)) != 0x8000) {
|
117
|
|
- printf("using floppy\n");
|
118
|
|
- exit(0);
|
119
|
|
- }
|
120
|
|
- }
|
121
|
|
- printf("no floppy\n");
|
122
|
|
-#endif /* TRY_FLOPPY_FIRST */
|
|
25
|
+/**
|
|
26
|
+ * Start up Etherboot
|
|
27
|
+ *
|
|
28
|
+ * Call this function only once, before doing (almost) anything else.
|
|
29
|
+ */
|
|
30
|
+static void startup ( void ) {
|
|
31
|
+ init_heap();
|
|
32
|
+ call_init_fns ();
|
|
33
|
+ probe_devices();
|
123
|
34
|
}
|
124
|
35
|
|
125
|
|
-static struct class_operations {
|
126
|
|
- struct dev *dev;
|
127
|
|
- int (*probe)(struct dev *dev);
|
128
|
|
- int (*load_configuration)(struct dev *dev);
|
129
|
|
- int (*load)(struct dev *dev);
|
|
36
|
+/**
|
|
37
|
+ * Shut down Etherboot
|
|
38
|
+ *
|
|
39
|
+ * Call this function only once, before either exiting main() or
|
|
40
|
+ * starting up a non-returnable image.
|
|
41
|
+ */
|
|
42
|
+void shutdown ( void ) {
|
|
43
|
+ remove_devices();
|
|
44
|
+ call_exit_fns ();
|
130
|
45
|
}
|
131
|
|
-operations[] = {
|
132
|
|
- { &nic.dev, eth_probe, eth_load_configuration, eth_load },
|
133
|
|
- { &disk.dev, disk_probe, disk_load_configuration, disk_load },
|
134
|
|
- { &disk.dev, disk_probe, disk_load_configuration, disk_load },
|
135
|
|
-};
|
136
|
|
-
|
137
|
|
-#endif
|
138
|
46
|
|
139
|
|
-#if 0
|
140
|
|
-static int main_loop(int state);
|
141
|
|
-static int exit_ok;
|
142
|
|
-static int initialized;
|
143
|
|
-#endif
|
144
|
|
-
|
145
|
|
-static int exit_status;
|
146
|
|
-
|
147
|
|
-/**************************************************************************
|
148
|
|
-MAIN - Kick off routine
|
149
|
|
-**************************************************************************/
|
|
47
|
+/**
|
|
48
|
+ * Main entry point
|
|
49
|
+ *
|
|
50
|
+ * @ret rc Return status code
|
|
51
|
+ */
|
150
|
52
|
int main ( void ) {
|
151
|
53
|
|
152
|
|
- /* Call all registered initialisation functions */
|
153
|
|
- init_heap();
|
154
|
|
- call_init_fns ();
|
155
|
|
- probe_devices();
|
|
54
|
+ startup();
|
156
|
55
|
|
157
|
56
|
/* Try autobooting if we're not going straight to the shell */
|
158
|
57
|
if ( ! shell_banner() ) {
|
|
@@ -162,201 +61,7 @@ int main ( void ) {
|
162
|
61
|
/* Autobooting failed or the user wanted the shell */
|
163
|
62
|
shell();
|
164
|
63
|
|
165
|
|
- remove_devices();
|
166
|
|
- call_exit_fns ();
|
167
|
|
-
|
168
|
|
- return exit_status;
|
169
|
|
-}
|
170
|
|
-
|
171
|
|
-#if 0
|
172
|
|
-
|
173
|
|
-void exit(int status)
|
174
|
|
-{
|
175
|
|
- while(!exit_ok)
|
176
|
|
- ;
|
177
|
|
- exit_status = status;
|
178
|
|
- longjmp(restart_etherboot, 255);
|
179
|
|
-}
|
180
|
|
-
|
181
|
|
-
|
182
|
|
-
|
183
|
|
-static int main_loop(int state)
|
184
|
|
-{
|
185
|
|
- /* Splitting main into 2 pieces makes the semantics of
|
186
|
|
- * which variables are preserved across a longjmp clean
|
187
|
|
- * and predictable.
|
188
|
|
- */
|
189
|
|
- static unsigned long order;
|
190
|
|
- static unsigned boot_index;
|
191
|
|
- static struct dev * dev = 0;
|
192
|
|
- static struct class_operations *ops;
|
193
|
|
- static int type;
|
194
|
|
- static int i;
|
195
|
|
-
|
196
|
|
- if (!initialized) {
|
197
|
|
- initialized = 1;
|
198
|
|
- if (dev && (state >= 1) && (state <= 2)) {
|
199
|
|
- dev->how_probe = PROBE_AWAKE;
|
200
|
|
- dev->how_probe = ops->probe(dev);
|
201
|
|
- if (dev->how_probe == PROBE_FAILED) {
|
202
|
|
- state = -1;
|
203
|
|
- }
|
204
|
|
- if (state == 1) {
|
205
|
|
- /* The bootp reply might have been changed, re-parse. */
|
206
|
|
- decode_rfc1533(bootp_data.bootp_reply.bp_vend, 0,
|
207
|
|
-#ifdef NO_DHCP_SUPPORT
|
208
|
|
- BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN,
|
209
|
|
-#else
|
210
|
|
- DHCP_OPT_LEN + MAX_BOOTP_EXTLEN,
|
211
|
|
-#endif /* NO_DHCP_SUPPORT */
|
212
|
|
- 1);
|
213
|
|
- }
|
214
|
|
- }
|
215
|
|
- }
|
216
|
|
- switch(state) {
|
217
|
|
- case 0:
|
218
|
|
- {
|
219
|
|
- static int firsttime = 1;
|
220
|
|
- /* First time through */
|
221
|
|
- if (firsttime) {
|
222
|
|
- cleanup();
|
223
|
|
- firsttime = 0;
|
224
|
|
- }
|
225
|
|
-#ifdef EXIT_IF_NO_OFFER
|
226
|
|
- else {
|
227
|
|
- cleanup();
|
228
|
|
- exit(0);
|
229
|
|
- }
|
230
|
|
-#endif
|
231
|
|
- i = -1;
|
232
|
|
- state = 4;
|
233
|
|
- dev = 0;
|
234
|
|
-
|
235
|
|
- /* We just called setjmp ... */
|
236
|
|
- order = ask_boot(&boot_index);
|
237
|
|
- try_floppy_first();
|
238
|
|
- break;
|
239
|
|
- }
|
240
|
|
- case 4:
|
241
|
|
- cleanup();
|
242
|
|
- call_reset_fns();
|
243
|
|
- /* Find a dev entry to probe with */
|
244
|
|
- if (!dev) {
|
245
|
|
- int boot;
|
246
|
|
- int failsafe;
|
247
|
|
-
|
248
|
|
- /* Advance to the next device type */
|
249
|
|
- i++;
|
250
|
|
- boot = (order >> (i * BOOT_BITS)) & BOOT_MASK;
|
251
|
|
- type = boot & BOOT_TYPE_MASK;
|
252
|
|
- failsafe = (boot & BOOT_FAILSAFE) != 0;
|
253
|
|
- if (i >= MAX_BOOT_ENTRIES) {
|
254
|
|
- type = BOOT_NOTHING;
|
255
|
|
- }
|
256
|
|
- if ((i == 0) && (type == BOOT_NOTHING)) {
|
257
|
|
- /* Return to caller */
|
258
|
|
- exit(0);
|
259
|
|
- }
|
260
|
|
- if (type >= BOOT_NOTHING) {
|
261
|
|
- interruptible_sleep(2);
|
262
|
|
- state = 0;
|
263
|
|
- break;
|
264
|
|
- }
|
265
|
|
- ops = &operations[type];
|
266
|
|
- dev = ops->dev;
|
267
|
|
- dev->how_probe = PROBE_FIRST;
|
268
|
|
- dev->type = type;
|
269
|
|
- dev->failsafe = failsafe;
|
270
|
|
- dev->type_index = 0;
|
271
|
|
- } else {
|
272
|
|
- /* Advance to the next device of the same type */
|
273
|
|
- dev->how_probe = PROBE_NEXT;
|
274
|
|
- }
|
275
|
|
- state = 3;
|
276
|
|
- break;
|
277
|
|
- case 3:
|
278
|
|
- state = -1;
|
279
|
|
- /* Removed the following line because it was causing
|
280
|
|
- * heap.o to be dragged in unnecessarily. It's also
|
281
|
|
- * slightly puzzling: by resetting heap_base, doesn't
|
282
|
|
- * this mean that we permanently leak memory?
|
283
|
|
- */
|
284
|
|
- /* heap_base = allot(0); */
|
285
|
|
- dev->how_probe = ops->probe(dev);
|
286
|
|
- if (dev->how_probe == PROBE_FAILED) {
|
287
|
|
- dev = 0;
|
288
|
|
- state = 4;
|
289
|
|
- } else if (boot_index && (i == 0) && (boot_index != (unsigned)dev->type_index)) {
|
290
|
|
- printf("Wrong index\n");
|
291
|
|
- state = 4;
|
292
|
|
- }
|
293
|
|
- else {
|
294
|
|
- state = 2;
|
295
|
|
- }
|
296
|
|
- break;
|
297
|
|
- case 2:
|
298
|
|
- state = -1;
|
299
|
|
- if (ops->load_configuration(dev) >= 0) {
|
300
|
|
- state = 1;
|
301
|
|
- }
|
302
|
|
- break;
|
303
|
|
- case 1:
|
304
|
|
- /* Any return from load is a failure */
|
305
|
|
- ops->load(dev);
|
306
|
|
- state = -1;
|
307
|
|
- break;
|
308
|
|
- case 256:
|
309
|
|
- state = 0;
|
310
|
|
- break;
|
311
|
|
- case -3:
|
312
|
|
- i = MAX_BOOT_ENTRIES;
|
313
|
|
- type = BOOT_NOTHING;
|
314
|
|
- /* fall through */
|
315
|
|
- default:
|
316
|
|
- printf("<abort>\n");
|
317
|
|
- state = 4;
|
318
|
|
- /* At the end goto state 0 */
|
319
|
|
- if ((type >= BOOT_NOTHING) || (i >= MAX_BOOT_ENTRIES)) {
|
320
|
|
- state = 0;
|
321
|
|
- }
|
322
|
|
- break;
|
323
|
|
- }
|
324
|
|
- return state;
|
325
|
|
-}
|
326
|
|
-
|
327
|
|
-
|
328
|
|
-#endif
|
329
|
|
-
|
|
64
|
+ shutdown();
|
330
|
65
|
|
331
|
|
-/**************************************************************************
|
332
|
|
-LOADKERNEL - Try to load kernel image
|
333
|
|
-**************************************************************************/
|
334
|
|
-#if 0
|
335
|
|
-/* To be split out into individual files */
|
336
|
|
-static const struct proto protos[] = {
|
337
|
|
- { "x-tftm", url_tftm },
|
338
|
|
- { "x-slam", url_slam },
|
339
|
|
- { "nfs", nfs },
|
340
|
|
- { "file", url_file },
|
341
|
|
- { "tftp", tftp },
|
342
|
|
- { "http", http },
|
343
|
|
-};
|
344
|
|
-#endif
|
345
|
|
-
|
346
|
|
-/**************************************************************************
|
347
|
|
-CLEANUP - shut down networking and console so that the OS may be called
|
348
|
|
-**************************************************************************/
|
349
|
|
-#if 0
|
350
|
|
-void cleanup(void)
|
351
|
|
-{
|
352
|
|
- /* Stop receiving packets */
|
353
|
|
- disable ( &dev );
|
354
|
|
- initialized = 0;
|
|
66
|
+ return 0;
|
355
|
67
|
}
|
356
|
|
-#endif
|
357
|
|
-
|
358
|
|
-/*
|
359
|
|
- * Local variables:
|
360
|
|
- * c-basic-offset: 8
|
361
|
|
- * End:
|
362
|
|
- */
|