|
|
1.1 ! root 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: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.