1 /**************************************************************************
2 Etherboot - Network Bootstrap Program
4 Literature dealing with the network protocols:
8 BOOTP - RFC951, RFC2132 (vendor extensions)
9 DHCP - RFC2131, RFC2132 (options)
10 TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize)
11 RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper)
12 NFS - RFC1094, RFC1813 (v3, useful for clarifications, not implemented)
15 **************************************************************************/
19 #include "etherboot.h"
27 #include <gpxe/init.h>
30 #include <gpxe/device.h>
31 #include <gpxe/heap.h>
32 #include <gpxe/netdevice.h>
33 #include <gpxe/shell.h>
34 #include <gpxe/shell_banner.h>
35 #include <usr/autoboot.h>
38 extern char _bss[], _ebss[];
40 jmp_buf restart_etherboot;
43 char as_main_program = 1;
47 static inline unsigned long ask_boot(unsigned *index)
49 unsigned long order = DEFAULT_BOOT_ORDER;
50 *index = DEFAULT_BOOT_INDEX;
52 order = get_boot_order(order, index);
62 for ( time = currticks() + ASK_BOOT*TICKS_PER_SEC;
64 if (currticks() > time) c = ANS_DEFAULT;
67 #endif /* ASK_BOOT > 0 */
68 if ( !c ) c = getchar();
69 if ((c >= 'a') && (c <= 'z')) c &= 0x5F;
70 if ((c >= ' ') && (c <= '~')) putchar(c);
75 /* Nothing useful try again */
82 /* Preserve the default boot order */
85 order = (BOOT_NIC << (0*BOOT_BITS)) |
86 (BOOT_NOTHING << (1*BOOT_BITS));
90 order = (BOOT_DISK << (0*BOOT_BITS)) |
91 (BOOT_NOTHING << (1*BOOT_BITS));
95 order = (BOOT_FLOPPY << (0*BOOT_BITS)) |
96 (BOOT_NOTHING << (1*BOOT_BITS));
103 #endif /* ASK_BOOT >= 0 */
104 #endif /* defined(ASK_BOOT) */
108 static inline void try_floppy_first(void)
110 #if (TRY_FLOPPY_FIRST > 0)
112 printf("Trying floppy");
114 for (i = TRY_FLOPPY_FIRST; i-- > 0; ) {
116 if (pcbios_disk_read(0, 0, 0, 0, ((char *)FLOPPY_BOOT_LOCATION)) != 0x8000) {
117 printf("using floppy\n");
121 printf("no floppy\n");
122 #endif /* TRY_FLOPPY_FIRST */
125 static struct class_operations {
127 int (*probe)(struct dev *dev);
128 int (*load_configuration)(struct dev *dev);
129 int (*load)(struct dev *dev);
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 },
140 static int main_loop(int state);
142 static int initialized;
145 static int exit_status;
147 /**************************************************************************
148 MAIN - Kick off routine
149 **************************************************************************/
152 /* Call all registered initialisation functions */
157 /* Try autobooting if we're not going straight to the shell */
158 if ( ! shell_banner() ) {
162 /* Autobooting failed or the user wanted the shell */
173 void exit(int status)
177 exit_status = status;
178 longjmp(restart_etherboot, 255);
183 static int main_loop(int state)
185 /* Splitting main into 2 pieces makes the semantics of
186 * which variables are preserved across a longjmp clean
189 static unsigned long order;
190 static unsigned boot_index;
191 static struct dev * dev = 0;
192 static struct class_operations *ops;
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) {
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,
210 DHCP_OPT_LEN + MAX_BOOTP_EXTLEN,
211 #endif /* NO_DHCP_SUPPORT */
219 static int firsttime = 1;
220 /* First time through */
225 #ifdef EXIT_IF_NO_OFFER
235 /* We just called setjmp ... */
236 order = ask_boot(&boot_index);
243 /* Find a dev entry to probe with */
248 /* Advance to the next device type */
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) {
256 if ((i == 0) && (type == BOOT_NOTHING)) {
257 /* Return to caller */
260 if (type >= BOOT_NOTHING) {
261 interruptible_sleep(2);
265 ops = &operations[type];
267 dev->how_probe = PROBE_FIRST;
269 dev->failsafe = failsafe;
272 /* Advance to the next device of the same type */
273 dev->how_probe = PROBE_NEXT;
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?
284 /* heap_base = allot(0); */
285 dev->how_probe = ops->probe(dev);
286 if (dev->how_probe == PROBE_FAILED) {
289 } else if (boot_index && (i == 0) && (boot_index != (unsigned)dev->type_index)) {
290 printf("Wrong index\n");
299 if (ops->load_configuration(dev) >= 0) {
304 /* Any return from load is a failure */
312 i = MAX_BOOT_ENTRIES;
318 /* At the end goto state 0 */
319 if ((type >= BOOT_NOTHING) || (i >= MAX_BOOT_ENTRIES)) {
331 /**************************************************************************
332 LOADKERNEL - Try to load kernel image
333 **************************************************************************/
335 /* To be split out into individual files */
336 static const struct proto protos[] = {
337 { "x-tftm", url_tftm },
338 { "x-slam", url_slam },
340 { "file", url_file },
346 /**************************************************************************
347 CLEANUP - shut down networking and console so that the OS may be called
348 **************************************************************************/
352 /* Stop receiving packets */