Home | History | Annotate | Download | only in doc
      1 /** @page build_sys Build system
      2 
      3 @section overview Overview
      4 
      5 Building an Etherboot image consists of three stages:
      6 
      7   -# @ref compilation : Compiling all the source files into object files
      8   -# @ref linking : Linking a particular image from selected object files
      9   -# @ref finalisation : Producing the final output binary
     10 
     11 Though this is a remarkably complex process, it is important to note
     12 that it all happens automatically.  Whatever state your build tree is
     13 in, you can always type, for example
     14 
     15 @code
     16 
     17 	make bin/rtl8139.dsk
     18 
     19 @endcode
     20 
     21 and know that you will get a floppy disk image with an RTL8139 driver
     22 built from the current sources.
     23 
     24 @section compilation Compilation
     25 
     26 @subsection comp_overview Overview
     27 
     28 Each source file (a @c .c or a @c .S file) is compiled into a @c .o
     29 file in the @c bin/ directory.  Etherboot makes minimal use of
     30 conditional compilation (see @ref ifdef_harmful), and so you will find
     31 that all objects get built, even the objects that correspond to
     32 features that you are not intending to include in your image.  For
     33 example, all network card drivers will be compiled even if you are
     34 just building a ROM for a 3c509 card.  This is a deliberate design
     35 decision; please do @b not attempt to "fix" the build system to avoid
     36 doing this.
     37 
     38 Source files are defined to be any @c .c or @c .S files found in a
     39 directory listed in the Makefile variable #SRCDIRS.  You therefore do
     40 @b not need to edit the Makefile just because you have added a new
     41 source file (although you will need to edit the Makefile if you have
     42 added a new source directory).  To see a list of all source
     43 directories and source files that the build system currently knows
     44 about, you can use the commands
     45 
     46 @code
     47 
     48 	make srcdirs
     49 	make srcs
     50 
     51 @endcode
     52 
     53 Rules for compiling @c .c and @c .S files are defined in the Makefile
     54 variables #RULE_c and #RULE_S.  Makefile rules are automatically
     55 generated for each source file using these rules.  The generated rules
     56 can be found in the @c .d file corresponding to each source file;
     57 these are located in <tt>bin/deps/</tt>.  For example, the rules
     58 generated for <tt>drivers/net/rtl8139.c</tt> can be found in
     59 <tt>bin/deps/drivers/net/rtl8139.c.d</tt>.  These rules allow you to
     60 type, for example
     61 
     62 @code
     63 
     64 	make bin/rtl8139.o
     65 
     66 @endcode
     67 
     68 and have <tt>rtl8139.o</tt> be built from
     69 <tt>drivers/net/rtl8139.c</tt> using the generic rule #RULE_c for
     70 compiling @c .c files.
     71 
     72 You can see the full list of object files that will be built using
     73 
     74 @code
     75 
     76 	make bobjs
     77 
     78 @endcode
     79 
     80 @subsection comp_ar After compilation
     81 
     82 Once all objects have been compiled, they will be collected into a
     83 build library ("blib") in <tt>bin/blib.a</tt>.
     84 
     85 @subsection comp_custom Customising compilation
     86 
     87 The Makefile rules for a particular object can be customised to a
     88 certain extent by defining the Makefile variable CFLAGS_@<object@>.
     89 For example, if you were to set
     90 
     91 @code
     92 
     93 	CFLAGS_rtl8139 = -DFOO
     94 
     95 @endcode
     96 
     97 then <tt>bin/rtl8139.o</tt> would be compiled with the additional
     98 flags <tt>-DFOO</tt>.  To see the flags that will be used when
     99 compiling a particular object, you can use e.g.
    100 
    101 @code
    102 
    103 	make bin/rtl8139.flags
    104 
    105 @endcode
    106 
    107 If you need more flexibility than the CFLAGS_@<object@> mechanism
    108 provides, then you can exclude source files from the automatic rule
    109 generation process by listing them in the Makefile variable
    110 #NON_AUTO_SRCS.  The command
    111 
    112 @code
    113 
    114 	make autosrcs
    115 
    116 @endcode
    117 
    118 will show you which files are currently part of the automatic rule
    119 generation process.
    120 
    121 @subsection comp_multiobj Multiple objects
    122 
    123 A single source file can be used to generate multiple object files.
    124 This is used, for example, to generate the decompressing and the
    125 non-decompressing prefixes from the same source files.
    126 
    127 By default, a single object will be built from each source file.  To
    128 override the list of objects for a source file, you can define the
    129 Makefile variable OBJS_@<object@>.  For example, the
    130 <tt>arch/i386/prefix/dskprefix.S</tt> source file is built into two
    131 objects, <tt>bin/dskprefix.o</tt> and <tt>zdskprefix.o</tt> by
    132 defining the Makefile variable
    133 
    134 @code
    135 
    136 	OBJS_dskprefix = dskprefix zdskprefix
    137 
    138 @endcode
    139 
    140 Since there would be little point in building two identical objects,
    141 customised compilation flags (see @ref comp_custom) are defined as
    142 
    143 @code
    144 
    145 	CFLAGS_zdskprefix = -DCOMPRESS
    146 
    147 @endcode
    148 
    149 Thus, <tt>arch/i386/prefix/dskprefix.S</tt> is built into @c
    150 dskprefix.o using the normal set of flags, and into @c zdskprefix.o
    151 using the normal set of flags plus <tt>-DCOMPRESS</tt>.
    152 
    153 @subsection comp_debug Special debugging targets
    154 
    155 In addition to the basic rules #RULE_c and #RULE_S for compiling
    156 source files into object files, there are various other rules that can
    157 be useful for debugging.
    158 
    159 @subsubsection comp_debug_c_to_c Preprocessed C
    160 
    161 You can see the results of preprocessing a @c .c file (including the
    162 per-object flags defined via CFLAGS_@<object@> if applicable) using
    163 e.g.
    164 
    165 @code
    166 
    167 	make bin/rtl8139.c
    168 
    169 @endcode
    170 
    171 and examining the resulting file (<tt>bin/rtl8139.c</tt> in this
    172 case).
    173 
    174 @subsubsection comp_debug_x_to_s Assembler
    175 
    176 You can see the results of assembling a @c .c file, or of
    177 preprocessing a @c .S file, using e.g.
    178 
    179 @code
    180 
    181 	make bin/rtl8139.s
    182 	make bin/zdskprefix.s
    183 
    184 @endcode
    185 
    186 @subsubsection comp_debug_dbg Debugging-enabled targets
    187 
    188 You can build targets with debug messages (DBG()) enabled using e.g.
    189 
    190 @code
    191 
    192 	make bin/rtl8139.dbg.o
    193 	make bin/rtl8139.dbg2.o
    194 
    195 @endcode
    196 
    197 You will probably not need to use these targets directly, since a
    198 mechanism exists to select debugging levels at build time; see @ref
    199 debug.
    200 
    201 @section linking Linking
    202 
    203 @subsection link_overview Overview
    204 
    205 Etherboot is designed to be small and extremely customisable.  This is
    206 achieved by linking in only the features that are really wanted in any
    207 particular build.
    208 
    209 There are two places from which the list of desired features is
    210 obtained:
    211 
    212   -# @ref link_config_h
    213   -# @ref link_cmdline
    214 
    215 @subsection link_config_h config.h
    216 
    217 The config.h file is used to define global build options that are
    218 likely to apply to all images that you build, such as the console
    219 types, supported download protocols etc.  See the documentation for
    220 config.h for more details.
    221 
    222 @subsection link_cmdline The make command line
    223 
    224 When you type a command such as
    225 
    226 @code
    227 
    228 	make bin/dfe538.zrom
    229 
    230 @endcode
    231 
    232 it is used to derive the following information:
    233 
    234    - We are building a compressed ROM image
    235    - The DFE538 is a PCI NIC, so we need the decompressing PCI ROM prefix
    236    - The PCI IDs for the DFE538 are 1186:1300
    237    - The DFE538 is an rtl8139-based card, therefore we need the rtl8139 driver
    238 
    239 You can see this process in action using the command
    240 
    241 @code
    242 
    243 	make bin/dfe538.zrom.info
    244 
    245 @endcode
    246 
    247 which will print
    248 
    249 @code
    250 
    251 	Elements             : dfe538
    252 	Prefix               : zrom
    253 	Drivers              : rtl8139
    254 	ROM name             : dfe538
    255 	Media                : rom
    256 
    257 	ROM type             : pci
    258 	PCI vendor           : 0x1186
    259 	PCI device           : 0x1300
    260 
    261 	LD driver symbols    : obj_rtl8139
    262 	LD prefix symbols    : obj_zpciprefix
    263 	LD ID symbols        : pci_vendor_id=0x1186 pci_device_id=0x1300
    264 
    265 	LD target flags      :  -u obj_zpciprefix --defsym check_obj_zpciprefix=obj_zpciprefix   -u obj_rtl8139 --defsym check_obj_rtl8139=obj_rtl8139   -u obj_config --defsym check_obj_config=obj_config  --defsym pci_vendor_id=0x1186 --defsym pci_device_id=0x1300
    266 
    267 @endcode
    268 
    269 This should be interpreted as follows:
    270 
    271 @code
    272 
    273 	Elements             : dfe538
    274 	Prefix               : zrom
    275 
    276 @endcode
    277 
    278 "Elements" is the list of components preceding the first dot in the
    279 target name.  "Prefix" is the component following the first dot in the
    280 target name.  (It's called a "prefix" because the code that makes it a
    281 @c .zrom (rather than a @c .dsk, @c .zpxe or any other type of target)
    282 usually ends up at the start of the resulting binary image.)
    283 
    284 @code
    285 
    286 	Drivers              : rtl8139
    287 
    288 @endcode
    289 
    290 "Drivers" is the list of drivers corresponding to the "Elements".
    291 Most drivers support several network cards.  The PCI_ROM() and
    292 ISA_ROM() macros are used in the driver source files to list the cards
    293 that a particular driver can support.
    294 
    295 @code
    296 
    297 	ROM name             : dfe538
    298 
    299 @endcode
    300 
    301 "ROM name" is the first element in the "Elements" list.  It is used to
    302 select the PCI IDs for a PCI ROM.
    303 
    304 @code
    305 
    306 	Media                : rom
    307 
    308 @endcode
    309 
    310 "Media" is the "Prefix" minus the leading @c z, if any.
    311 
    312 @code
    313 
    314 	ROM type             : pci
    315 	PCI vendor           : 0x1186
    316 	PCI device           : 0x1300
    317 
    318 @endcode
    319 
    320 These are derived from the "ROM name" and the PCI_ROM() or ISA_ROM()
    321 macros in the driver source files.
    322 
    323 @code
    324 
    325 	LD driver symbols    : obj_rtl8139
    326 	LD prefix symbols    : obj_zpciprefix
    327 
    328 @endcode
    329 
    330 This is the interesting part.  At this point, we have established that
    331 we need the rtl8139 driver (i.e. @c rtl8139.o) and the decompressing
    332 PCI prefix (i.e. @c zpciprefix.o).  Our build system (via the
    333 compiler.h header file) arranges that every object exports a symbol
    334 obj_@<object@>; this can be seen by e.g.
    335 
    336 @code
    337 
    338 	objdump -t bin/rtl8139.o
    339 
    340 @endcode
    341 
    342 which will show the line
    343 
    344 @code
    345 
    346 	00000000 g       *ABS*  00000000 obj_rtl8139
    347 
    348 @endcode
    349 
    350 By instructing the linker that we need the symbols @c obj_rtl8139 and
    351 @c obj_zpciprefix, we can therefore ensure that these two objects are
    352 included in our build.  (The linker will also include any objects that
    353 these two objects require, since that's the whole purpose of the
    354 linker.)
    355 
    356 In a similar way, we always instruct the linker that we need the
    357 symbol @c obj_config, in order to include the object @c config.o.  @c
    358 config.o is used to drag in the objects that were specified via
    359 config.h; see @ref link_config_h.
    360 
    361 @code
    362 
    363 	LD target flags      :  -u obj_zpciprefix --defsym check_obj_zpciprefix=obj_zpciprefix   -u obj_rtl8139 --defsym check_obj_rtl8139=obj_rtl8139   -u obj_config --defsym check_obj_config=obj_config  --defsym pci_vendor_id=0x1186 --defsym pci_device_id=0x1300
    364 
    365 @endcode
    366 
    367 These are the flags that we pass to the linker in order to include the
    368 objects that we want in our build, and to check that they really get
    369 included.  (This latter check is needed to work around what seems to
    370 be a bug in @c ld).
    371 
    372 The linker does its job of linking all the required objects together
    373 into a coherent build.  The best way to see what is happening is to
    374 look at one of the resulting linker maps; try, for example
    375 
    376 @code
    377 
    378 	make bin/dfe538.dsk.map
    379 
    380 @endcode
    381 
    382 The linker map includes, amongst others:
    383 
    384   - A list of which objects are included in the build, and why.
    385   - The results of processing the linker script, line-by-line.
    386   - A complete symbol table of the resulting build.
    387 
    388 It is worth spending time examining the linker map to see how an
    389 Etherboot image is assembled.
    390 
    391 Whatever format is selected, the Etherboot image is built into an ELF
    392 file, simply because this is the default format used by @c ld.
    393 
    394 @section finalisation Finalisation
    395 
    396 @subsection final_overview Overview
    397 
    398 The ELF file resulting from @ref linking "linking" needs to be
    399 converted into the final binary image.  Usually, this is just a case
    400 of running
    401 
    402 @code
    403 
    404 	objcopy -O binary <elf file> <output file>
    405 
    406 @endcode
    407 
    408 to convert the ELF file into a raw binary image.  Certain image
    409 formats require special additional treatment.
    410 
    411 @subsection final_rom ROM images
    412 
    413 ROM images must be rounded up to a suitable ROM size (e.g. 16kB or
    414 32kB), and certain header information such as checksums needs to be
    415 filled in.  This is done by the @c makerom.pl program.
    416 
    417 @section debug Debugging-enabled builds
    418 
    419 */
    420