Make shutdown functions callable by OS image's exec methods.
authorMichael Brown <mcb30@etherboot.org>
Sun, 14 Jan 2007 00:16:41 +0000 (00:16 +0000)
committerMichael Brown <mcb30@etherboot.org>
Sun, 14 Jan 2007 00:16:41 +0000 (00:16 +0000)
src/core/main.c
src/core/misc.c
src/include/gpxe/shutdown.h [new file with mode: 0644]

index 3c0048d..185e44b 100644 (file)
@@ -14,145 +14,44 @@ Literature dealing with the network protocols:
 
 **************************************************************************/
 
-/* #define MDEBUG */
-
-#include "etherboot.h"
-#include "dev.h"
-#include "nic.h"
-#include "disk.h"
-#include "timer.h"
-#include "cpu.h"
-#include "cmdline.h"
-#include "console.h"
+#include <gpxe/heap.h>
 #include <gpxe/init.h>
-#include <stdarg.h>
-
 #include <gpxe/device.h>
-#include <gpxe/heap.h>
-#include <gpxe/netdevice.h>
 #include <gpxe/shell.h>
 #include <gpxe/shell_banner.h>
+#include <gpxe/shutdown.h>
 #include <usr/autoboot.h>
 
-/* Linker symbols */
-extern char _bss[], _ebss[];
-
-jmp_buf        restart_etherboot;
-int    url_port;               
-
-char as_main_program = 1;
-
-#if 0
-
-static inline unsigned long ask_boot(unsigned *index)
-{
-       unsigned long order = DEFAULT_BOOT_ORDER;
-       *index = DEFAULT_BOOT_INDEX;
-#ifdef LINUXBIOS
-       order = get_boot_order(order, index);
-#endif
-#if defined(ASK_BOOT)
-#if ASK_BOOT >= 0
-       while(1) {
-               int c = 0;
-               printf(ASK_PROMPT);
-#if ASK_BOOT > 0
-               {
-                       unsigned long time;
-                       for ( time = currticks() + ASK_BOOT*TICKS_PER_SEC;
-                             !c && !iskey(); ) {
-                               if (currticks() > time) c = ANS_DEFAULT;
-                       }
-               }
-#endif /* ASK_BOOT > 0 */
-               if ( !c ) c = getchar();
-               if ((c >= 'a') && (c <= 'z')) c &= 0x5F;
-               if ((c >= ' ') && (c <= '~')) putchar(c);
-               putchar('\n');
-
-               switch(c) {
-               default:
-                       /* Nothing useful try again */
-                       continue;
-               case ANS_QUIT:
-                       order = BOOT_NOTHING;
-                       *index = 0;
-                       break;
-               case ANS_DEFAULT:
-                       /* Preserve the default boot order */
-                       break;
-               case ANS_NETWORK:
-                       order = (BOOT_NIC     << (0*BOOT_BITS)) | 
-                               (BOOT_NOTHING << (1*BOOT_BITS));
-                       *index = 0;
-                       break;
-               case ANS_DISK:
-                       order = (BOOT_DISK    << (0*BOOT_BITS)) | 
-                               (BOOT_NOTHING << (1*BOOT_BITS));
-                       *index = 0;
-                       break;
-               case ANS_FLOPPY:
-                       order = (BOOT_FLOPPY  << (0*BOOT_BITS)) | 
-                               (BOOT_NOTHING << (1*BOOT_BITS));
-                       *index = 0;
-                       break;
-               }
-               break;
-       }
-       putchar('\n');
-#endif /* ASK_BOOT >= 0 */
-#endif /* defined(ASK_BOOT) */
-       return order;
-}
-
-static inline void try_floppy_first(void)
-{
-#if (TRY_FLOPPY_FIRST > 0)
-       int i;
-       printf("Trying floppy");
-       disk_init();
-       for (i = TRY_FLOPPY_FIRST; i-- > 0; ) {
-               putchar('.');
-               if (pcbios_disk_read(0, 0, 0, 0, ((char *)FLOPPY_BOOT_LOCATION)) != 0x8000) {
-                       printf("using floppy\n");
-                       exit(0);
-               }
-       }
-       printf("no floppy\n");
-#endif /* TRY_FLOPPY_FIRST */  
+/**
+ * Start up Etherboot
+ *
+ * Call this function only once, before doing (almost) anything else.
+ */
+static void startup ( void ) {
+       init_heap();
+       call_init_fns ();
+       probe_devices();
 }
 
-static struct class_operations {
-       struct dev *dev;
-       int (*probe)(struct dev *dev);
-       int (*load_configuration)(struct dev *dev);
-       int (*load)(struct dev *dev);
+/**
+ * Shut down Etherboot
+ *
+ * Call this function only once, before either exiting main() or
+ * starting up a non-returnable image.
+ */
+void shutdown ( void ) {
+       remove_devices();
+       call_exit_fns ();
 }
-operations[] = {
-       { &nic.dev,  eth_probe,  eth_load_configuration,  eth_load  },
-       { &disk.dev, disk_probe, disk_load_configuration, disk_load },
-       { &disk.dev, disk_probe, disk_load_configuration, disk_load },
-};
-
-#endif
 
-#if 0
-static int main_loop(int state);
-static int exit_ok;
-static int initialized;
-#endif
-
-static int exit_status;
-
-/**************************************************************************
-MAIN - Kick off routine
-**************************************************************************/
+/**
+ * Main entry point
+ *
+ * @ret rc             Return status code
+ */
 int main ( void ) {
 
-       /* Call all registered initialisation functions */
-       init_heap();
-       call_init_fns ();
-       probe_devices();
+       startup();
 
        /* Try autobooting if we're not going straight to the shell */
        if ( ! shell_banner() ) {
@@ -162,201 +61,7 @@ int main ( void ) {
        /* Autobooting failed or the user wanted the shell */
        shell();
 
-       remove_devices();
-       call_exit_fns ();
-
-       return exit_status;
-}
-
-#if 0
-
-void exit(int status)
-{
-       while(!exit_ok)
-               ;
-       exit_status = status;
-       longjmp(restart_etherboot, 255);
-}
-
-
-
-static int main_loop(int state)
-{
-       /* Splitting main into 2 pieces makes the semantics of 
-        * which variables are preserved across a longjmp clean
-        * and predictable.
-        */
-       static unsigned long order;
-       static unsigned boot_index;
-       static struct dev * dev = 0;
-       static struct class_operations *ops;
-       static int type;
-       static int i;
-
-       if (!initialized) {
-               initialized = 1;
-               if (dev && (state >= 1) && (state <= 2)) {
-                       dev->how_probe = PROBE_AWAKE;
-                       dev->how_probe = ops->probe(dev);
-                       if (dev->how_probe == PROBE_FAILED) {
-                               state = -1;
-                       }
-                       if (state == 1) {
-                               /* The bootp reply might have been changed, re-parse.  */
-                               decode_rfc1533(bootp_data.bootp_reply.bp_vend, 0,
-#ifdef NO_DHCP_SUPPORT
-                                              BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 
-#else
-                                              DHCP_OPT_LEN + MAX_BOOTP_EXTLEN, 
-#endif /* NO_DHCP_SUPPORT */
-                                              1);
-                       }
-               }
-       }
-       switch(state) {
-       case 0:
-       {
-               static int firsttime = 1;
-               /* First time through */
-               if (firsttime) {
-                       cleanup();
-                       firsttime = 0;
-               } 
-#ifdef EXIT_IF_NO_OFFER
-               else {
-                       cleanup();
-                       exit(0);
-               }
-#endif
-               i = -1;
-               state = 4;
-               dev = 0;
-
-               /* We just called setjmp ... */
-               order = ask_boot(&boot_index);
-               try_floppy_first();
-               break;
-       }
-       case 4:
-               cleanup();
-               call_reset_fns();
-               /* Find a dev entry to probe with */
-               if (!dev) {
-                       int boot;
-                       int failsafe;
-
-                       /* Advance to the next device type */
-                       i++;
-                       boot = (order >> (i * BOOT_BITS)) & BOOT_MASK;
-                       type = boot & BOOT_TYPE_MASK;
-                       failsafe = (boot & BOOT_FAILSAFE) != 0;
-                       if (i >= MAX_BOOT_ENTRIES) {
-                               type = BOOT_NOTHING;
-                       }
-                       if ((i == 0) && (type == BOOT_NOTHING)) {
-                               /* Return to caller */
-                               exit(0);
-                       }
-                       if (type >= BOOT_NOTHING) {
-                               interruptible_sleep(2);
-                               state = 0;
-                               break;
-                       }
-                       ops = &operations[type];
-                       dev = ops->dev;
-                       dev->how_probe = PROBE_FIRST;
-                       dev->type = type;
-                       dev->failsafe = failsafe;
-                       dev->type_index = 0;
-               } else {
-                       /* Advance to the next device of the same type */
-                       dev->how_probe = PROBE_NEXT;
-               }
-               state = 3;
-               break;
-       case 3:
-               state = -1;
-               /* Removed the following line because it was causing
-                * heap.o to be dragged in unnecessarily.  It's also
-                * slightly puzzling: by resetting heap_base, doesn't
-                * this mean that we permanently leak memory?
-                */
-               /* heap_base = allot(0); */
-               dev->how_probe = ops->probe(dev);
-               if (dev->how_probe == PROBE_FAILED) {
-                       dev = 0;
-                       state = 4;
-               } else if (boot_index && (i == 0) && (boot_index != (unsigned)dev->type_index)) {
-                       printf("Wrong index\n");
-                       state = 4;
-               }
-               else {
-                       state = 2;
-               }
-               break;
-       case 2:
-               state = -1;
-               if (ops->load_configuration(dev) >= 0) {
-                       state = 1;
-               }
-               break;
-       case 1:
-               /* Any return from load is a failure */
-               ops->load(dev);
-               state = -1;
-               break;
-       case 256:
-               state = 0;
-               break;
-       case -3:
-               i = MAX_BOOT_ENTRIES;
-               type = BOOT_NOTHING;
-               /* fall through */
-       default:
-               printf("<abort>\n");
-               state = 4;
-               /* At the end goto state 0 */
-               if ((type >= BOOT_NOTHING) || (i >= MAX_BOOT_ENTRIES)) {
-                       state = 0;
-               }
-               break;
-       }
-       return state;
-}
-
-
-#endif
-
+       shutdown();
 
-/**************************************************************************
-LOADKERNEL - Try to load kernel image
-**************************************************************************/
-#if 0
-/* To be split out into individual files */
-static const struct proto protos[] = {
-       { "x-tftm", url_tftm },
-       { "x-slam", url_slam },
-       { "nfs", nfs },
-       { "file", url_file },
-       { "tftp", tftp },
-        { "http", http },
-};
-#endif
-
-/**************************************************************************
-CLEANUP - shut down networking and console so that the OS may be called 
-**************************************************************************/
-#if 0
-void cleanup(void)
-{
-       /* Stop receiving packets */
-       disable ( &dev );
-       initialized = 0;
+       return 0;
 }
-#endif
-
-/*
- * Local variables:
- *  c-basic-offset: 8
- * End:
- */
index fcbcdd6..e150709 100644 (file)
@@ -94,32 +94,6 @@ void interruptible_sleep(int secs)
        sleep(secs);
 }
 
-/**************************************************************************
-TWIDDLE
-**************************************************************************/
-void twiddle(void)
-{
-#ifdef BAR_PROGRESS
-       static int count=0;
-       static const char tiddles[]="-\\|/";
-       static unsigned long lastticks = 0;
-       unsigned long ticks;
-#endif
-       if ( ! as_main_program ) return;
-#ifdef BAR_PROGRESS
-       /* Limit the maximum rate at which characters are printed */
-       ticks = currticks();
-       if ((lastticks + (TICKS_PER_SEC/18)) > ticks)
-               return;
-       lastticks = ticks;
-
-       putchar(tiddles[(count++)&3]);
-       putchar('\b');
-#else
-       putchar('.');
-#endif /* BAR_PROGRESS */
-}
-
 /**************************************************************************
 STRCASECMP (not entirely correct, but this will do for our purposes)
 **************************************************************************/
diff --git a/src/include/gpxe/shutdown.h b/src/include/gpxe/shutdown.h
new file mode 100644 (file)
index 0000000..4510293
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _GPXE_SHUTDOWN_H
+#define _GPXE_SHUTDOWN_H
+
+/**
+ * Shut down before exit
+ */
+
+extern void shutdown ( void );
+
+#endif /* _GPXE_SHUTDOWN_H */