|
@@ -30,11 +30,18 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
30
|
30
|
#include <ipxe/uri.h>
|
31
|
31
|
#include <ipxe/open.h>
|
32
|
32
|
#include <ipxe/init.h>
|
|
33
|
+#include <ipxe/keys.h>
|
|
34
|
+#include <ipxe/version.h>
|
|
35
|
+#include <ipxe/shell.h>
|
|
36
|
+#include <ipxe/features.h>
|
|
37
|
+#include <ipxe/image.h>
|
33
|
38
|
#include <usr/ifmgmt.h>
|
34
|
39
|
#include <usr/route.h>
|
35
|
40
|
#include <usr/dhcpmgmt.h>
|
36
|
41
|
#include <usr/imgmgmt.h>
|
|
42
|
+#include <usr/prompt.h>
|
37
|
43
|
#include <usr/autoboot.h>
|
|
44
|
+#include <config/general.h>
|
38
|
45
|
|
39
|
46
|
/** @file
|
40
|
47
|
*
|
|
@@ -47,6 +54,18 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
47
|
54
|
#define EINFO_ENOENT_BOOT \
|
48
|
55
|
__einfo_uniqify ( EINFO_ENOENT, 0x01, "Nothing to boot" )
|
49
|
56
|
|
|
57
|
+#define NORMAL "\033[0m"
|
|
58
|
+#define BOLD "\033[1m"
|
|
59
|
+#define CYAN "\033[36m"
|
|
60
|
+
|
|
61
|
+/** The "scriptlet" setting */
|
|
62
|
+struct setting scriptlet_setting __setting ( SETTING_MISC ) = {
|
|
63
|
+ .name = "scriptlet",
|
|
64
|
+ .description = "Boot scriptlet",
|
|
65
|
+ .tag = DHCP_EB_SCRIPTLET,
|
|
66
|
+ .type = &setting_type_string,
|
|
67
|
+};
|
|
68
|
+
|
50
|
69
|
/**
|
51
|
70
|
* Perform PXE menu boot when PXE stack is not available
|
52
|
71
|
*/
|
|
@@ -423,3 +442,79 @@ int autoboot ( void ) {
|
423
|
442
|
printf ( "No more network devices\n" );
|
424
|
443
|
return rc;
|
425
|
444
|
}
|
|
445
|
+
|
|
446
|
+/**
|
|
447
|
+ * Prompt for shell entry
|
|
448
|
+ *
|
|
449
|
+ * @ret enter_shell User wants to enter shell
|
|
450
|
+ */
|
|
451
|
+static int shell_banner ( void ) {
|
|
452
|
+
|
|
453
|
+ /* Skip prompt if timeout is zero */
|
|
454
|
+ if ( BANNER_TIMEOUT <= 0 )
|
|
455
|
+ return 0;
|
|
456
|
+
|
|
457
|
+ /* Prompt user */
|
|
458
|
+ printf ( "\n" );
|
|
459
|
+ return ( prompt ( "Press Ctrl-B for the iPXE command line...",
|
|
460
|
+ ( BANNER_TIMEOUT * 100 ), CTRL_B ) == 0 );
|
|
461
|
+}
|
|
462
|
+
|
|
463
|
+/**
|
|
464
|
+ * Main iPXE flow of execution
|
|
465
|
+ *
|
|
466
|
+ * @v netdev Network device, or NULL
|
|
467
|
+ */
|
|
468
|
+void ipxe ( struct net_device *netdev ) {
|
|
469
|
+ struct feature *feature;
|
|
470
|
+ struct image *image;
|
|
471
|
+ char *scriptlet;
|
|
472
|
+
|
|
473
|
+ /*
|
|
474
|
+ * Print welcome banner
|
|
475
|
+ *
|
|
476
|
+ *
|
|
477
|
+ * If you wish to brand this build of iPXE, please do so by
|
|
478
|
+ * defining the string PRODUCT_NAME in config/general.h.
|
|
479
|
+ *
|
|
480
|
+ * While nothing in the GPL prevents you from removing all
|
|
481
|
+ * references to iPXE or http://ipxe.org, we prefer you not to
|
|
482
|
+ * do so.
|
|
483
|
+ *
|
|
484
|
+ */
|
|
485
|
+ printf ( NORMAL "\n\n" PRODUCT_NAME "\n" BOLD "iPXE %s"
|
|
486
|
+ NORMAL " -- Open Source Network Boot Firmware -- "
|
|
487
|
+ CYAN "http://ipxe.org" NORMAL "\n"
|
|
488
|
+ "Features:", product_version );
|
|
489
|
+ for_each_table_entry ( feature, FEATURES )
|
|
490
|
+ printf ( " %s", feature->name );
|
|
491
|
+ printf ( "\n" );
|
|
492
|
+
|
|
493
|
+ /* Boot system */
|
|
494
|
+ if ( ( image = first_image() ) != NULL ) {
|
|
495
|
+ /* We have an embedded image; execute it */
|
|
496
|
+ image_exec ( image );
|
|
497
|
+ } else if ( shell_banner() ) {
|
|
498
|
+ /* User wants shell; just give them a shell */
|
|
499
|
+ shell();
|
|
500
|
+ } else {
|
|
501
|
+ fetch_string_setting_copy ( NULL, &scriptlet_setting,
|
|
502
|
+ &scriptlet );
|
|
503
|
+ if ( scriptlet ) {
|
|
504
|
+ /* User has defined a scriptlet; execute it */
|
|
505
|
+ system ( scriptlet );
|
|
506
|
+ free ( scriptlet );
|
|
507
|
+ } else {
|
|
508
|
+ /* Try booting. If booting fails, offer the
|
|
509
|
+ * user another chance to enter the shell.
|
|
510
|
+ */
|
|
511
|
+ if ( netdev ) {
|
|
512
|
+ netboot ( netdev );
|
|
513
|
+ } else {
|
|
514
|
+ autoboot();
|
|
515
|
+ }
|
|
516
|
+ if ( shell_banner() )
|
|
517
|
+ shell();
|
|
518
|
+ }
|
|
519
|
+ }
|
|
520
|
+}
|