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