123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
-
-
-
- /** @page ifdef_harmful
- *
- * Overuse of @c
- * Etherboot provides a rich array of features, but all these features
- * take up valuable space in a ROM image. The traditional solution to
- * this problem has been for each feature to have its own @c
- * option, allowing the feature to be compiled in only if desired.
- *
- * The problem with this is that it becomes impossible to compile, let
- * alone test, all possible versions of Etherboot. Code that is not
- * typically used tends to suffer from bit-rot over time. It becomes
- * extremely difficult to predict which combinations of compile-time
- * options will result in code that can even compile and link
- * correctly.
- *
- * To solve this problem, we have adopted a new approach from
- * Etherboot 5.5 onwards. @c
- * its use should be minimised. Separate features should be
- * implemented in separate @c .c files, and should \b always be
- * compiled (i.e. they should \b not be guarded with a @c
- * MY_PET_FEATURE statement). By making (almost) all code always
- * compile, we avoid the problem of bit-rot in rarely-used code.
- *
- * The file config.h, in combination with the @c make command line,
- * specifies the objects that will be included in any particular build
- * of Etherboot. For example, suppose that config.h includes the line
- *
- * @code
- *
- *
- *
- *
- * @endcode
- *
- * When a particular Etherboot image (e.g. @c bin/rtl8139.zdsk) is
- * built, the options specified in config.h are used to drag in the
- * relevant objects at link-time. For the above example, serial.o and
- * tftp.o would be linked in.
- *
- * There remains one problem to solve: how do these objects get used?
- * Traditionally, we had code such as
- *
- * @code
- *
- *
- * serial_init();
- *
- *
- * @endcode
- *
- * in main.c, but this reintroduces @c
- * We cannot simply remove the @c
- *
- * @code
- *
- * serial_init();
- *
- * @endcode
- *
- * because then serial.o would end up always being linked in.
- *
- * The solution is to use @link tables.h linker tables @endlink.
- *
- */
-
- /** @file
- *
- * Linker tables
- *
- * Read @ref ifdef_harmful first for some background on the motivation
- * for using linker tables.
- *
- * This file provides macros for dealing with linker-generated tables
- * of fixed-size symbols. We make fairly extensive use of these in
- * order to avoid @c
- * For example, instead of having code such as
- *
- * @code
- *
- *
- * serial_init();
- *
- *
- * @endcode
- *
- * we make serial.c generate an entry in the initialisation function
- * table, and then have a function call_init_fns() that simply calls
- * all functions present in this table. If and only if serial.o gets
- * linked in, then its initialisation function will be called. We
- * avoid linker symbol pollution (i.e. always dragging in serial.o
- * just because of a call to serial_init()) and we also avoid @c
- *
- * functions in serial.c).
- *
- * The linker script takes care of assembling the tables for us. All
- * our table sections have names of the format @c .tbl.NAME.NN where
- * @c NAME designates the data structure stored in the table (e.g. @c
- * init_fn) and @c NN is a two-digit decimal number used to impose an
- * ordering upon the tables if required. @c NN=00 is reserved for the
- * symbol indicating "table start", and @c NN=99 is reserved for the
- * symbol indicating "table end".
- *
- * As an example, suppose that we want to create a "frobnicator"
- * feature framework, and allow for several independent modules to
- * provide frobnicating services. Then we would create a frob.h
- * header file containing e.g.
- *
- * @code
- *
- * struct frobnicator {
- * const char *name; // Name of the frobnicator
- * void ( *frob ) ( void ); // The frobnicating function itself
- * };
- *
- *
- *
- * @endcode
- *
- * Any module providing frobnicating services would look something
- * like
- *
- * @code
- *
- *
- *
- * static void my_frob ( void ) {
- * // Do my frobnicating
- * ...
- * }
- *
- * struct frob my_frobnicator __frobnicator = {
- * .name = "my_frob",
- * .frob = my_frob,
- * };
- *
- * @endcode
- *
- * The central frobnicator code (frob.c) would use the frobnicating
- * modules as follows
- *
- * @code
- *
- *
- *
- * static struct frob frob_start[0] __table_start ( frobnicators );
- * static struct frob frob_end[0] __table_end ( frobnicators );
- *
- * // Call all linked-in frobnicators
- * void frob_all ( void ) {
- * struct frob *frob;
- *
- * for ( frob = frob_start ; frob < frob_end ; frob++ ) {
- * printf ( "Calling frobnicator \"%s\"\n", frob->name );
- * frob->frob ();
- * }
- * }
- *
- * @endcode
- *
- * See init.h and init.c for a real-life example.
- *
- */
-
-
-
-
-
-
-
- __section__ ( ".tbl." __table_str(table) "." __table_str(idx) )
-
-
-
-
-
- /**
- * Linker table entry.
- *
- * Declares a data structure to be part of a linker table. Use as
- * e.g.
- *
- * @code
- *
- * struct my_foo __table ( foo, 01 ) = {
- * ...
- * };
- *
- * @endcode
- *
- */
-
- __attribute__ (( unused, __table_section(table,idx) ))
-
- /**
- * Linker table start marker.
- *
- * Declares a data structure (usually an empty data structure) to be
- * the start of a linker table. Use as e.g.
- *
- * @code
- *
- * static struct foo_start[0] __table_start ( foo );
- *
- * @endcode
- *
- */
-
- __attribute__ (( unused, __table_section_start(table) ))
-
- /**
- * Linker table end marker.
- *
- * Declares a data structure (usually an empty data structure) to be
- * the end of a linker table. Use as e.g.
- *
- * @code
- *
- * static struct foo_end[0] __table_end ( foo );
- *
- * @endcode
- *
- */
-
- __attribute__ (( unused, __table_section_end(table) ))
-
|