From 033f4c92ca86834e44cb3c2a75cdc87cdef80cf9 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 11 Mar 2013 18:38:42 +0000 Subject: [PATCH] [autoboot] Split main control flow out of main() into a new function ipxe() Signed-off-by: Michael Brown --- src/core/main.c | 84 +-------------------------------- src/include/usr/autoboot.h | 1 + src/usr/autoboot.c | 95 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 82 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 7b7755c9..8ad912d4 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -14,56 +14,18 @@ Literature dealing with the network protocols: FILE_LICENCE ( GPL2_OR_LATER ); +#include #include -#include #include -#include -#include -#include -#include -#include -#include #include #include -#define NORMAL "\033[0m" -#define BOLD "\033[1m" -#define CYAN "\033[36m" - -/** The "scriptlet" setting */ -struct setting scriptlet_setting __setting ( SETTING_MISC ) = { - .name = "scriptlet", - .description = "Boot scriptlet", - .tag = DHCP_EB_SCRIPTLET, - .type = &setting_type_string, -}; - -/** - * Prompt for shell entry - * - * @ret enter_shell User wants to enter shell - */ -static int shell_banner ( void ) { - - /* Skip prompt if timeout is zero */ - if ( BANNER_TIMEOUT <= 0 ) - return 0; - - /* Prompt user */ - printf ( "\n" ); - return ( prompt ( "Press Ctrl-B for the iPXE command line...", - ( BANNER_TIMEOUT * 100 ), CTRL_B ) == 0 ); -} - /** * Main entry point * * @ret rc Return status code */ __asmcall int main ( void ) { - struct feature *feature; - struct image *image; - char *scriptlet; /* Some devices take an unreasonably long time to initialise */ printf ( PRODUCT_SHORT_NAME " initialising devices..." ); @@ -71,49 +33,7 @@ __asmcall int main ( void ) { startup(); printf ( "ok\n" ); - /* - * Print welcome banner - * - * - * If you wish to brand this build of iPXE, please do so by - * defining the string PRODUCT_NAME in config/general.h. - * - * While nothing in the GPL prevents you from removing all - * references to iPXE or http://ipxe.org, we prefer you not to - * do so. - * - */ - printf ( NORMAL "\n\n" PRODUCT_NAME "\n" BOLD "iPXE %s" - NORMAL " -- Open Source Network Boot Firmware -- " - CYAN "http://ipxe.org" NORMAL "\n" - "Features:", product_version ); - for_each_table_entry ( feature, FEATURES ) - printf ( " %s", feature->name ); - printf ( "\n" ); - - /* Boot system */ - if ( ( image = first_image() ) != NULL ) { - /* We have an embedded image; execute it */ - image_exec ( image ); - } else if ( shell_banner() ) { - /* User wants shell; just give them a shell */ - shell(); - } else { - fetch_string_setting_copy ( NULL, &scriptlet_setting, - &scriptlet ); - if ( scriptlet ) { - /* User has defined a scriptlet; execute it */ - system ( scriptlet ); - free ( scriptlet ); - } else { - /* Try booting. If booting fails, offer the - * user another chance to enter the shell. - */ - autoboot(); - if ( shell_banner() ) - shell(); - } - } + ipxe ( NULL ); shutdown_exit(); diff --git a/src/include/usr/autoboot.h b/src/include/usr/autoboot.h index 25b9f073..cfa4c41e 100644 --- a/src/include/usr/autoboot.h +++ b/src/include/usr/autoboot.h @@ -31,6 +31,7 @@ extern struct uri * fetch_next_server_and_filename ( struct settings *settings ); extern int netboot ( struct net_device *netdev ); extern int autoboot ( void ); +extern void ipxe ( struct net_device *netdev ); extern int pxe_menu_boot ( struct net_device *netdev ); diff --git a/src/usr/autoboot.c b/src/usr/autoboot.c index 0587f204..b2d288ea 100644 --- a/src/usr/autoboot.c +++ b/src/usr/autoboot.c @@ -30,11 +30,18 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include +#include +#include +#include +#include #include #include #include #include +#include #include +#include /** @file * @@ -47,6 +54,18 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define EINFO_ENOENT_BOOT \ __einfo_uniqify ( EINFO_ENOENT, 0x01, "Nothing to boot" ) +#define NORMAL "\033[0m" +#define BOLD "\033[1m" +#define CYAN "\033[36m" + +/** The "scriptlet" setting */ +struct setting scriptlet_setting __setting ( SETTING_MISC ) = { + .name = "scriptlet", + .description = "Boot scriptlet", + .tag = DHCP_EB_SCRIPTLET, + .type = &setting_type_string, +}; + /** * Perform PXE menu boot when PXE stack is not available */ @@ -423,3 +442,79 @@ int autoboot ( void ) { printf ( "No more network devices\n" ); return rc; } + +/** + * Prompt for shell entry + * + * @ret enter_shell User wants to enter shell + */ +static int shell_banner ( void ) { + + /* Skip prompt if timeout is zero */ + if ( BANNER_TIMEOUT <= 0 ) + return 0; + + /* Prompt user */ + printf ( "\n" ); + return ( prompt ( "Press Ctrl-B for the iPXE command line...", + ( BANNER_TIMEOUT * 100 ), CTRL_B ) == 0 ); +} + +/** + * Main iPXE flow of execution + * + * @v netdev Network device, or NULL + */ +void ipxe ( struct net_device *netdev ) { + struct feature *feature; + struct image *image; + char *scriptlet; + + /* + * Print welcome banner + * + * + * If you wish to brand this build of iPXE, please do so by + * defining the string PRODUCT_NAME in config/general.h. + * + * While nothing in the GPL prevents you from removing all + * references to iPXE or http://ipxe.org, we prefer you not to + * do so. + * + */ + printf ( NORMAL "\n\n" PRODUCT_NAME "\n" BOLD "iPXE %s" + NORMAL " -- Open Source Network Boot Firmware -- " + CYAN "http://ipxe.org" NORMAL "\n" + "Features:", product_version ); + for_each_table_entry ( feature, FEATURES ) + printf ( " %s", feature->name ); + printf ( "\n" ); + + /* Boot system */ + if ( ( image = first_image() ) != NULL ) { + /* We have an embedded image; execute it */ + image_exec ( image ); + } else if ( shell_banner() ) { + /* User wants shell; just give them a shell */ + shell(); + } else { + fetch_string_setting_copy ( NULL, &scriptlet_setting, + &scriptlet ); + if ( scriptlet ) { + /* User has defined a scriptlet; execute it */ + system ( scriptlet ); + free ( scriptlet ); + } else { + /* Try booting. If booting fails, offer the + * user another chance to enter the shell. + */ + if ( netdev ) { + netboot ( netdev ); + } else { + autoboot(); + } + if ( shell_banner() ) + shell(); + } + } +}