From 89349d7fad252f0b36be4a764369e6dd40a2e692 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 3 Jul 2007 23:09:56 +0100 Subject: Separated out initialisation functions from startup/shutdown functions. --- src/core/heap.c | 27 ------------ src/core/init.c | 122 ++++++++++++++++++++++++++++++++++++++++++++--------- src/core/main.c | 34 +-------------- src/core/malloc.c | 24 +++++++++++ src/core/process.c | 8 +++- src/core/serial.c | 18 +++++++- 6 files changed, 150 insertions(+), 83 deletions(-) delete mode 100644 src/core/heap.c (limited to 'src/core') 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 -#include - -/** - * @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 . + * + * 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 #include +/** @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,42 +14,11 @@ Literature dealing with the network protocols: **************************************************************************/ -#include #include -#include -#include #include #include -#include -#include #include -/** - * 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 * @@ -57,6 +26,7 @@ void shutdown ( void ) { */ 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 #include #include +#include #include /** @file @@ -72,6 +73,16 @@ static LIST_HEAD ( free_blocks ); /** Total amount of free memory */ 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 * @@ -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 /** 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 +#include #include /** @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, +}; -- cgit v1.2.3-55-g7522