Annotation of qemu/roms/ipxe/src/doc/build_sys.dox, revision 1.1

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: */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.