summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorMichael Brown2007-07-04 00:09:56 +0200
committerMichael Brown2007-07-04 00:09:56 +0200
commit89349d7fad252f0b36be4a764369e6dd40a2e692 (patch)
tree72b112d6152fadee77673994f1e92b82a9c506e8 /src/core
parentAdded missing line to set return status code. (diff)
downloadipxe-89349d7fad252f0b36be4a764369e6dd40a2e692.tar.gz
ipxe-89349d7fad252f0b36be4a764369e6dd40a2e692.tar.xz
ipxe-89349d7fad252f0b36be4a764369e6dd40a2e692.zip
Separated out initialisation functions from startup/shutdown functions.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/heap.c27
-rw-r--r--src/core/init.c122
-rw-r--r--src/core/main.c34
-rw-r--r--src/core/malloc.c24
-rw-r--r--src/core/process.c8
-rw-r--r--src/core/serial.c18
6 files changed, 150 insertions, 83 deletions
diff --git a/src/core/heap.c b/src/core/heap.c
deleted file mode 100644
index 4a84fc262..000000000
--- a/src/core/heap.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <gpxe/malloc.h>
-#include <gpxe/heap.h>
-
-/**
- * @file
- *
- * Heap
- *
- */
-
-/**
- * Heap size
- *
- * Currently fixed at 128kB.
- */
-#define HEAP_SIZE ( 128 * 1024 )
-
-/** The heap itself */
-char heap[HEAP_SIZE] __attribute__ (( aligned ( __alignof__(void *) )));
-
-/**
- * Initialise the heap
- *
- */
-void init_heap ( void ) {
- mpopulate ( heap, sizeof ( heap ) );
-}
diff --git a/src/core/init.c b/src/core/init.c
index 61570fd17..ed91bf367 100644
--- a/src/core/init.c
+++ b/src/core/init.c
@@ -1,37 +1,117 @@
-/**************************************************************************
- * call_{init,reset,exit}_fns ()
- *
- * Call the various initialisation and exit functions. We use a
- * function table so that we don't end up dragging in an object just
- * because we call its initialisation function.
- **************************************************************************
+/*
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <gpxe/device.h>
#include <gpxe/init.h>
+/** @file
+ *
+ * Initialisation, startup and shutdown routines
+ *
+ */
+
+/** Registered initialisation functions */
static struct init_fn init_fns[0]
- __table_start ( struct init_fn, init_fn );
+ __table_start ( struct init_fn, init_fns );
static struct init_fn init_fns_end[0]
- __table_end ( struct init_fn, init_fn );
+ __table_end ( struct init_fn, init_fns );
+
+/** Registered startup/shutdown functions */
+static struct startup_fn startup_fns[0]
+ __table_start ( struct startup_fn, startup_fns );
+static struct startup_fn startup_fns_end[0]
+ __table_end ( struct startup_fn, startup_fns );
-void call_init_fns ( void ) {
+/** "startup() has been called" flag */
+static int started = 0;
+
+/**
+ * Initialise gPXE
+ *
+ * This function performs the one-time-only and irreversible
+ * initialisation steps, such as initialising the heap. It must be
+ * called before (almost) any other function.
+ *
+ * There is, by definition, no counterpart to this function on the
+ * shutdown path.
+ */
+void initialise ( void ) {
struct init_fn *init_fn;
- for ( init_fn = init_fns; init_fn < init_fns_end ; init_fn++ ) {
- if ( init_fn->init )
- init_fn->init ();
+ /* Call registered initialisation functions */
+ for ( init_fn = init_fns ; init_fn < init_fns_end ; init_fn++ ) {
+ init_fn->initialise ();
}
}
-void call_exit_fns ( void ) {
- struct init_fn *init_fn;
+/**
+ * Start up gPXE
+ *
+ * This function performs the repeatable initialisation steps, such as
+ * probing devices. You may call startup() and shutdown() multiple
+ * times (as is done via the PXE API when PXENV_START_UNDI is used).
+ */
+void startup ( void ) {
+ struct startup_fn *startup_fn;
+
+ if ( started )
+ return;
+
+ /* Call registered startup functions */
+ for ( startup_fn = startup_fns ; startup_fn < startup_fns_end ;
+ startup_fn++ ) {
+ if ( startup_fn->startup )
+ startup_fn->startup();
+ }
- /*
- * Exit functions are called in reverse order to
- * initialisation functions.
+ /* Probe for all devices. Treated separately because nothing
+ * else will drag in device.o
*/
- for ( init_fn = init_fns_end - 1; init_fn >= init_fns ; init_fn-- ) {
- if ( init_fn->exit )
- init_fn->exit ();
+ probe_devices();
+
+ started = 1;
+}
+
+/**
+ * Shut down gPXE
+ *
+ * This function reverses the actions of startup(), and leaves gPXE in
+ * a state ready to be removed from memory. You may call startup()
+ * again after calling shutdown().
+
+ * Call this function only once, before either exiting main() or
+ * starting up a non-returnable image.
+ */
+void shutdown ( void ) {
+ struct startup_fn *startup_fn;
+
+ if ( ! started )
+ return;
+
+ /* Remove all devices */
+ remove_devices();
+
+ /* Call registered shutdown functions (in reverse order) */
+ for ( startup_fn = startup_fns_end - 1 ; startup_fn >= startup_fns ;
+ startup_fn-- ) {
+ if ( startup_fn->shutdown )
+ startup_fn->shutdown();
}
+
+ started = 0;
}
diff --git a/src/core/main.c b/src/core/main.c
index 5b01df9cc..09dccc761 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1,5 +1,5 @@
/**************************************************************************
-Etherboot - Network Bootstrap Program
+gPXE - Network Bootstrap Program
Literature dealing with the network protocols:
ARP - RFC826
@@ -14,49 +14,19 @@ Literature dealing with the network protocols:
**************************************************************************/
-#include <gpxe/heap.h>
#include <gpxe/init.h>
-#include <gpxe/process.h>
-#include <gpxe/device.h>
#include <gpxe/shell.h>
#include <gpxe/shell_banner.h>
-#include <gpxe/shutdown.h>
-#include <gpxe/hidemem.h>
#include <usr/autoboot.h>
/**
- * Start up Etherboot
- *
- * Call this function only once, before doing (almost) anything else.
- */
-static void startup ( void ) {
- init_heap();
- init_processes();
-
- hide_etherboot();
- call_init_fns();
- probe_devices();
-}
-
-/**
- * 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();
- unhide_etherboot();
-}
-
-/**
* Main entry point
*
* @ret rc Return status code
*/
int main ( void ) {
+ initialise();
startup();
/* Try autobooting if we're not going straight to the shell */
diff --git a/src/core/malloc.c b/src/core/malloc.c
index bf94592cc..2d892f42d 100644
--- a/src/core/malloc.c
+++ b/src/core/malloc.c
@@ -22,6 +22,7 @@
#include <strings.h>
#include <io.h>
#include <gpxe/list.h>
+#include <gpxe/init.h>
#include <gpxe/malloc.h>
/** @file
@@ -73,6 +74,16 @@ static LIST_HEAD ( free_blocks );
size_t freemem;
/**
+ * Heap size
+ *
+ * Currently fixed at 128kB.
+ */
+#define HEAP_SIZE ( 128 * 1024 )
+
+/** The heap itself */
+static char heap[HEAP_SIZE] __attribute__ (( aligned ( __alignof__(void *) )));
+
+/**
* Allocate a memory block
*
* @v size Requested size
@@ -342,6 +353,19 @@ void mpopulate ( void *start, size_t len ) {
free_memblock ( start, ( len & ~( MIN_MEMBLOCK_SIZE - 1 ) ) );
}
+/**
+ * Initialise the heap
+ *
+ */
+static void init_heap ( void ) {
+ mpopulate ( heap, sizeof ( heap ) );
+}
+
+/** Memory allocator initialisation function */
+struct init_fn heap_init_fn __init_fn ( INIT_EARLY ) = {
+ .initialise = init_heap,
+};
+
#if 0
#include <stdio.h>
/**
diff --git a/src/core/process.c b/src/core/process.c
index bd35e614f..9d9ca6a68 100644
--- a/src/core/process.c
+++ b/src/core/process.c
@@ -17,6 +17,7 @@
*/
#include <gpxe/list.h>
+#include <gpxe/init.h>
#include <gpxe/process.h>
/** @file
@@ -83,10 +84,15 @@ void step ( void ) {
* Initialise processes
*
*/
-void init_processes ( void ) {
+static void init_processes ( void ) {
struct process *process;
for ( process = processes ; process < processes_end ; process++ ) {
process_add ( process );
}
}
+
+/** Process initialiser */
+struct init_fn process_init_fn __init_fn ( INIT_NORMAL ) = {
+ .initialise = init_processes,
+};
diff --git a/src/core/serial.c b/src/core/serial.c
index 3e4543bbc..f325bc45b 100644
--- a/src/core/serial.c
+++ b/src/core/serial.c
@@ -225,7 +225,7 @@ static void serial_init ( void ) {
/*
* void serial_fini(void);
* Cleanup our use of the serial port, in particular flush the
- * output buffer so we don't accidentially loose characters.
+ * output buffer so we don't accidentially lose characters.
*/
static void serial_fini ( void ) {
int i, status;
@@ -250,5 +250,19 @@ struct console_driver serial_console __console_driver = {
.disabled = 1,
};
-INIT_FN ( INIT_CONSOLE, serial_init, serial_fini );
+/** Serial console startup function */
+struct startup_fn serial_startup_fn __startup_fn ( STARTUP_NORMAL ) = {
+ .startup = serial_init,
+ .shutdown = serial_fini,
+};
+/**
+ * Serial console initialisation function
+ *
+ * Initialise console early on so that it is available to capture
+ * early debug messages. It is safe to call serial_init() multiple
+ * times.
+ */
+struct init_fn serial_init_fn __init_fn ( INIT_EARLY ) = {
+ .initialise = serial_init,
+};