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"
26 #include <gpxe/init.h>
30 #include <gpxe/device.h>
31 #include <gpxe/heap.h>
32 #include <gpxe/netdevice.h>
35 extern char _bss
[], _ebss
[];
37 jmp_buf restart_etherboot
;
40 char as_main_program
= 1;
44 static inline unsigned long ask_boot(unsigned *index
)
46 unsigned long order
= DEFAULT_BOOT_ORDER
;
47 *index
= DEFAULT_BOOT_INDEX
;
49 order
= get_boot_order(order
, index
);
59 for ( time
= currticks() + ASK_BOOT
*TICKS_PER_SEC
;
61 if (currticks() > time
) c
= ANS_DEFAULT
;
64 #endif /* ASK_BOOT > 0 */
65 if ( !c
) c
= getchar();
66 if ((c
>= 'a') && (c
<= 'z')) c
&= 0x5F;
67 if ((c
>= ' ') && (c
<= '~')) putchar(c
);
72 /* Nothing useful try again */
79 /* Preserve the default boot order */
82 order
= (BOOT_NIC
<< (0*BOOT_BITS
)) |
83 (BOOT_NOTHING
<< (1*BOOT_BITS
));
87 order
= (BOOT_DISK
<< (0*BOOT_BITS
)) |
88 (BOOT_NOTHING
<< (1*BOOT_BITS
));
92 order
= (BOOT_FLOPPY
<< (0*BOOT_BITS
)) |
93 (BOOT_NOTHING
<< (1*BOOT_BITS
));
100 #endif /* ASK_BOOT >= 0 */
101 #endif /* defined(ASK_BOOT) */
105 static inline void try_floppy_first(void)
107 #if (TRY_FLOPPY_FIRST > 0)
109 printf("Trying floppy");
111 for (i
= TRY_FLOPPY_FIRST
; i
-- > 0; ) {
113 if (pcbios_disk_read(0, 0, 0, 0, ((char *)FLOPPY_BOOT_LOCATION
)) != 0x8000) {
114 printf("using floppy\n");
118 printf("no floppy\n");
119 #endif /* TRY_FLOPPY_FIRST */
122 static struct class_operations
{
124 int (*probe
)(struct dev
*dev
);
125 int (*load_configuration
)(struct dev
*dev
);
126 int (*load
)(struct dev
*dev
);
129 { &nic
.dev
, eth_probe
, eth_load_configuration
, eth_load
},
130 { &disk
.dev
, disk_probe
, disk_load_configuration
, disk_load
},
131 { &disk
.dev
, disk_probe
, disk_load_configuration
, disk_load
},
138 static int main_loop(int state
);
140 static int exit_status
;
141 static int initialized
;
144 /**************************************************************************
145 MAIN - Kick off routine
146 **************************************************************************/
148 struct net_device
*netdev
;
150 /* Call all registered initialisation functions */
155 netdev
= next_netdev ();
157 test_aoeboot ( netdev
);
159 printf ( "No network device found\n" );
162 printf ( "Press any key to exit\n" );
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
},
347 /**************************************************************************
348 CLEANUP - shut down networking and console so that the OS may be called
349 **************************************************************************/
352 /* Stop receiving packets */