This chapter discusses extending the build process to include new components, new features and new system tunables.
The Embedded Component Markup Language (ECML) simplifies the building and configuration processes of the ChorusOS operating system. Building and configuring the system require the selection and configuration of BSPs, drivers and applications and as such encompass a wide variety of information. This widely divergent information is handled by multiple languages and configuration tools. ECML was developed to provide a unique interface to the configurable information of the ChorusOS operating system.
ECML is defined using XML syntax, making it benefit from existing XML tools, especially browsers and parsers. ECML is designed to be:
Edited using a standard editor that can be completed with XML-specific mode; for example, Emacs
Parsed using C++ or Java tools
Displayed using standard browsers, with possible extensions to handle XML
This section demonstrates through examples how modifications to different layers of the source code must be accounted for when building a ChorusOS system.
A fundamental strength of the ChorusOS operating system is its portability across a range of target family hardware architectures. The trade-off made to achieve broad portability manifests itself as build management complexity. ChorusOS system builds require powerful tools to generate the necessary Makefiles to render the process more straightforward. These tools, imake and mkmk:
Provide the rules for compiling
Manage dependencies
Allow you to add components
Enable you to configure source files with configurator or the ews graphical tool
ChorusOS operating system builds involve make for end-result build tasks, and involve imake and mkmk for generating and managing Makefiles inside components. The following tables indicate which standard system components are managed using which Makefile generation tool.
Table 4-1 Components Managed with imake
Component |
Description |
---|---|
BSP |
Bootstrap code |
DRV |
Drivers |
EXAMPLES |
Example applications |
Table 4-2 Components Managed with mkmk
Component |
Description |
---|---|
NUCLEUS |
Microkernel and related code |
OS |
POSIX, file system and networking layers of the operating system |
The rule of thumb for choosing between imake and mkmk is simple: use imake if you can; use mkmk if you must. User-level application components can be handled using imake. Hardware driver components can be handled using imake. Subsystem components -- such as microkernel components and components that modify the POSIX, file system and networking layers of the operating system itself -- might require you to use mkmk.
An Imakefile is a machine-independent description of the make targets you want to build. In the first step of the build process, the imake tool generates a Makefile from each Imakefile, by selecting the configuration files with dependencies appropriate to your target system. This has the advantage that the Imakefile is a machine-independent description of the targets you want to build and is thus portable.
If files are altered they must be rebuilt. For the imake tool within the ChorusOS operating system, only dependencies between source and binary files are taken into account when altered files are rebuilt.
ChorusOS--specific imake rules are provided in the imake subdirectory of the install-dir/tools directory, as shown below.
host% cd install_dir/chorus-family/tools/imake host% ls Imake.rules Imake.tmpl Imake32.rules Package.rules Project.tmpl host% |
Table 4-3 presents each imake file.
Table 4-3 The imake files provided with the ChorusOS System
File |
Description |
---|---|
imake/Imake.rules |
imake rules |
imake/Imake32.rules |
Provides compatibility with r3.2 imake rules |
imake/Imake.tmpl |
Template Makefile, for imake |
imake/Package.rules |
Packaging rules, for imake |
imake/Project.tmpl |
Empty Project.tmpl |
Components managed with imake export their public information through packaging rules based on those found in these files. Examples demonstrating the use of ChorusOS--specific imake rules can be found in the ChorusOS 5.0 Application Developer's Guide. Commercially available books offer extensive explanations of how to use imake to manage portable software.
The imake command uses Project.tmpl and Imakefiles you include in each directory of your component source to generate Makefiles. During builds managed with imake, only dependencies between source and binary files are taken into account.
Table 4-4 ChorusOS imake Targets
iMake Target |
Description |
---|---|
all (default target) |
Builds everything |
clean |
Removes generated files recursively |
depend |
Generates dependencies recursively |
Makefile |
Regenerates the Makefile in the current directory. |
Makefiles |
Regenerates Makefiles recursively |
Each file in the tgt-make directory deals with make rules for compiling target binary files. Certain files are specific to the gcc compiler, others to the ghs compiler. Only common and gcc/powerpc specific files are described here. All files listed in Table 4-5 are located in the bin_dir/tools/tgt-make directory:
Table 4-5 Target Rules for ChorusOS
File |
Description |
---|---|
gcc-devsys.mk | make rules used by the imake environment |
gcc-ld.ld | Linker script used to reduce the section number |
gcc-variables.rf | make variables, for the mkmk and imake environments |
gcc-tgtdevsys.rf | make rules, for mkmk |
variables.rf | Includes the compiler specific file about variables |
tgtdevsys.rf | Includes the compiler specific file about rules |
shared.rf | Calls mkmake |
Makefile.mkimage | Makefile used during image creation |
Makefile.conf | Makefile used during configurable actor links |
genLink | Generic linker, calls genLink.conf and genLink.noconf |
genLink.conf | Links configurable actors |
genLink.noconf | Links non-configurable actors |
mkdbginfo | Generates offsets and symbol information |
powerpc/genOff | Create offset files |
powerpc/genOff.awk | awk file used by genOff |
powerpc/act.ld | Linker script used for actors using dynamic libraries |
powerpc/lib.ld | Linker script used to create dynamic libraries |
The mkmk tool is used to generate Makefiles that let you build a particular target system image from source code that supports multiple target hardware architectures. The mkmk rules allow you to manage system configuration entities such as features, parameters and tunables.
The mkmk build process consists of the following steps:
Merging -- creating links to source files from the build directory; the links enable mkmk to locate source code during builds.
Generating Makefiles in the build subdirectory for the component using mkmk.
Building the object component.
Creating the dependency files for subsequent builds.
Building the system image.
The role of mkmerge is to link the source files and the component's build directory. For further information, see the mkmerge(1CC) man page.
The code for ChorusOS components containing family-specific code is organized in projected trees. Within the projected trees, there are sub-trees for:
common code
code that is related to specific families or CPU
Before generation begins, subtrees are merged into a merged tree. There is only one merged tree in each merged component. Initially, it contains symbolic, or hard, links that point to files in the projected trees. The build takes place in the merged tree, so the projected trees remain free of generated files, such as object files and Makefiles. You can delete a merged tree at any time. This will not affect the source code, as it remains clean in the projected trees.
Different merged trees can be built from a given set of subtrees of the projected trees. This allows you to produce several system configurations concurrently.
Building the merged tree is called the merge operation. When performing this operation, you provide a number of first-level options, called generation options. These options correspond to fundamental production choices, such as the choice of a development system or the target family and are typically found in the build profile.
On systems running the Solaris operating environment, mkmerge populates the merge directory with symbolic links. These links point to the source directories required for your build.
Source directories within the projected tree can be populated with special files, named merge.rf (for merge rule files), which provide a number of directives for mkmerge, for example:
Preventing merging source files depending upon flags specified in the profile file
Exporting source.h files to other directories
Pruning the merge of the source tree, depending on the flags.
During a merge, directories are examined recursively and merge.rf files are analyzed. If no problems are encountered, the real merge begins: directories, links and files are created as specified in the various merge.rf files found.
A merge.rf file is composed of lines that are evaluated one at a time. A status is associated with this file. This status evolves as the file is analyzed. Depending on its value at the end of the merge.rf file, the current directory will be merged or cut.
A merge.rf file can contain commands to describe how the current directory should be merged, where it will go, and when it will be merged. The MKMERGE_IGNORE environment variable can be used to specify a list of file suffixes that should be ignored during the merge process.
For more information about merge.rf, see the mkmerge(1CC) man page.
The build profile used by the configure command is an argument of the mkmerge command. There is one default profile for each board, as shown in"Families, Targets and Profiles" . For non-standard system generation, customize the build profile using the information on the file entries described here.
The build profile contains entries of the following type:
var = value
The range of value values depends on the variable. Note that:
on and yes are equivalent values (both mean included)
off and no are equivalent values (both mean not included)
Build profile files provide configuration flags used during the merge. The following listing shows an example microkernel build profile file for UltraSPARCTM family targets.
[profile] FLAG=host=solaris FLAG=target=upSparc FLAG=devsys=gcc FLAG=flm=on FLAG=locks=rt FLAG=optim=on FLAG=tree=upSparc [profile] devsys=gcc binfmt=elf # directories to merge tree=./../common tree=./../sparc tree=./../sparc_v9 tree=./../usparc # kernel locks configuration : # 2 choices : locks=rt, locks=gp locks=rt # available memory management implementations flm=on prm=on vm=off # # shared_lib support # choices : sharedlib=on, sharedlib=off sharedlib=on # stack fault support : # 2 choices : stack_fault_support=on, stack_fault_support=off stack_fault_support=on # FPU support : # 2 choices : fpu_support=on, fpu_support=off fpu_support=on # optimisation type # choices : optim=on, optim=no optim=on # debug on or off (default) debug=off # profiling on or off (default) profile=off
The predefined flags include:
Table 4-6 Configuration Flags
Name |
Possible values |
Description |
---|---|---|
debug |
(off|on) |
Indicates whether to compile with debugging information; default is off |
devsys |
(gcc) |
Indicates which host development tool chain is used for compilation; default is gcc |
flm |
(off|on) |
Indicates whether flat memory is in use. |
prm |
(off|on) |
Indicates whether protected memory is in use |
vm |
(off|on) |
Indicates whether virtual memory is in use |
locks |
(gp|rt) |
Specifies which type of locking to use in the core executive; default is gp |
merge_dir |
(dir) |
Specifies the path to the root of the merge tree |
optim |
(off|on|size|speed) |
Indicates how to optimize compilation; setting this flag to speed might make symbolic debugging impossible; default is on, a compromise between size and speed optimizations |
profile |
(off|on) |
Indicates whether to compile with performance profiling capabilities; default is off |
shared_lib |
(off|on) |
Shared library support. Default is on. |
softload |
(off|on) |
Library fp emulation. Default is on. |
tree |
(dir1,dir2,...) |
Specifies projected tree directories to merge |
The mkmk tool uses portable description files, independently of both the host and target systems. High-level mkmk rules are included in .bf, .df and .mf portable description files for a component, and are then processed to create Makefiles and .dp dependency files for the builds.
The mkmk command uses three types of build description files, suffixed by .df, .bf, and .mf, to produce Makefiles and generate all .dp dependencies. With mkmk, you create a .mf file for each host. In this way the mkmk tool ensures portability during cross compilation and so ensures the portability of hosts and targets.
The .bf suffix denotes build file.
The .bf files are a subset of Imakefiles. They contain link directives , and you can have several .bf files per directory. The mkmk tool concatenates the .bf files inside the Makefile product. The .bf file is preprocessed by the macro processor m4(1).
Table 4-7 lists the macros used in a .bf file. The Actor
, ConfigurableActor
, Library
and BigObject
macros use getExport, either directly or
indirectly, to get the list of object files. The getExport
command computes the list of object files to use when creating a link.
Macro |
Description |
---|---|
|
Build actor using libs |
|
Build actor using libs |
|
Build lib |
|
Build a relocatable object file |
|
Copy file into dir |
|
Copy file into dir |
|
Build actor using libs |
|
Build actor using libs |
|
Build lib |
|
Build a relocatable object file |
|
Copy file into dir |
|
Copy file into dir |
|
Build a pre-built actor and its finalized makefile using libs and local_libs. |
The .df suffix denotes definitions file.
The .df files are used as shell scripts that are launched when the Makefile is created to adjust variables before they are written into the Makefile. The .df files define the following variables:
The cpp symbols
The header file directories
The list of subdirectories
The .df files have similar properties to the Project.tmpl files of the imake tool. They affect the building of the Makefiles for all the subdirectories. With mkmk, you can have several .df files in each directory of the source tree. This contrasts with the imake tool, which has only one Project.tmpl file per component.
The inheritance mechanism of the mkmk tool is different from that of the imake tool. With mkmk, every Makefile is dependent on the Makefile present in the parent directory. However, with imake, every Makefile is dependent on the Project.tmpl file present in the top-level directory of the component and on the few variables inherited from the parent directory. The variables and macros are defined in the production tools. Table 4-8 lists those you must not modify and Table 4-9 lists those you can modify.
Table 4-8 Variables for the .df Files that must not Change
Variable |
Description |
---|---|
DTL | (DEVTOOLS_DIR)/host/bin/ |
GROOT | ../../ (the relative path to the root component) |
BDIR | build_dir |
BNAME | Name of current directory |
HOST | Type of host |
FAMILY | Type of target |
COMPILER | Type of compiler |
MPATH |
Pathname of current directory relative to the component root |
BFILES | List of .bf files found in your work directory |
MFILES | List of .lf and .mf files found in your work directory |
DFILES | List of .df files in your work directory |
Table 4-9 Variables in the .df Files hat can Change
Variable |
Description |
---|---|
DEFINES | List of macro definitions to use in every compilation rule |
INCLUDES | List of directories to search for header files |
VARIABLES | The list of user defined variables to export in Makefiles produced in subdirectories |
SUB_DIRS | The list of directories to use when compiling; these are usually the subdirectories of your build directory |
EXTRA_DIRS | A list of directories to use, in addition to SUB_DIRS, when creating libraries or linking actors (usually empty) |
MODULES | The name of the module to which the object in your build directory (and subdirectories) belong; this is only useful in configurable actors |
FARROP |
Application profiling |
FEXCEPTION | (ON/OFF): Compile with exception support |
FPU | (ON/OFF): Compile with FPU support |
FOPTIM | (ON/OFF): Compile with optimization |
FPROF | (ON/OFF): Support for profiling |
FREMOTEDEB | (ON/OFF): Compile with debug options, to enable source level debugging |
FVERBOSE | (ON/OFF): Verbose compilations |
FWARN | (STRICT/ON/OFF): Enable production of warnings during compilation; with STRICT, warnings are treated as errors. The NUCLEUS component uses STRICT |
FASSERT |
(ON/OFF): Enable or disable assertions |
FGCOV |
(ON/OFF): Enable or disable code coverage testing with gcov |
FPIC |
(ON/OFF): Enable or disable compilation for inclusion in shared libraries |
FVEC |
(ON/OFF): Enable or disable generation/build options to use or not use a unit vector |
The .mf suffix denotes make file.
The .mf files contain lists of source files. The .mf files are used during make sources when the binary file to be built uses many subdirectories, each subdirectory containing a variable number of files to be compiled.
Another form of .mf files are .lf files. The variables and macros used in the .mf and .lf files are listed in Table 4-10.
Table 4-10 Variables and Macros used in .mf and .lf Files
Variable |
Description |
---|---|
C++SRCS | C++ source files |
C_SRCS | C source files |
AS_SRCS | Assembly code source files |
M4_SRCS | M4 source files (assembly code source files preprocessed with m4). |
OF_SRCS | C++ source files used to produce offset files |
During generation, mkmk goes down the build tree and creates a Makefile for each build directory. The Makefiles are used to build the binary files and each of these Makefiles is autonomous. This means that you can set make running from any directory and all files located in the subdirectories attached to that directory are built automatically. The Makefile content depends on the mkmk production files.
In each directory, where mkmk produces a Makefile, mkmk:
Calculates the initial value of the variables, in relation to the Makefile of the parent directory.
Activates the .df script files, located in the current directory, in a parallel shell.
Asks the shell to recover the values of the variables defined by the .df files.
The list of files to be compiled varies depending on the merge operation. Writing a Makefile that will work on several configurations can be complicated. The solution offered by mkmk is to:
Place the .mf files found in projected trees at the same directory level as the sources files to be compiled.
Concatenate the .mf files inside the Makefile that it produces.
The .mf files do not have an equivalent within the imake tool.
The mkmk tool will regenerate the Makefile produced if the .df, .bf or .mf files used to build it change.
Once a file has been modified, for example with an editor, or by a previous compilation, the files that depend on the altered file must be rebuilt. Most development tools only deal with the dependencies between source and binary files. The mkmk system goes further, taking into account any changes which occur in the source files during the build process.
The relationship between the different components is managed through the components' Makefile.bin and Makefile.src files and through the build paths found in the Paths file in your ChorusOS build directory. For example, applications can access both the microkernel API and the OS API through the variables set in the Paths file:
NUCLEUS_DIR provides the applications with access to the microkernel
BSP_DIR and DRV_DIR give access to the board support package information
OS_DIR enables access to the operating system API
This section presents the complete list of make targets you can use with the mkmk tool.
Table 4-11 Description of Make Targets used with mkmk
Make Target |
Description |
---|---|
all | Default make target, builds everything |
Makefile | Rebuild the Makefile in current directory |
makemk | Rebuild the Makefiles (recursively) |
merge | Remerge the current component |
makesrc | Build offset files (recursively) |
sources | Build offset files in the current directory |
makeprod | Build object files and libraries (recursively) |
prod | Build object files and libraries in the current directory |
makelink | Link libraries and actors (recursively) |
link | Link libraries and actors in the current directory |
depend | Generate dependencies (recursively) |
clean | Remove files produced (recursively), with the exception of Makefiles and dependency files |
clobber | Remove files produced (recursively) |
There also exists an alternative to imake, cdstool, which you can use to compile simple binaries. The cdstool utility is a wrapper for the C compiler delivered with the ChorusOS operating system.
#include <stdio.h> main() { printf("Hello world\n"); }
host% build_dir/bin/cdstool cc example.c -o example
$ |
This section uses the example of the built OS
component to present the component build directories and files.
Table 4-12 and Table 4-13 show the content of build_dir/build-OS after running make:
Table 4-12 Directories in theOS
Component Build Directory
Directory |
Description |
---|---|
include | Header files exported by the OS component |
lib | Libraries used by the OS component |
obj | Object files needed to link the OS component |
src | Source files of the OS component |
conf | Configuration files of the OS component (used by mkmerge) |
Table 4-13 Files Generated in the
OS
Component Build
Directory
File |
Description |
---|---|
DONE | Created by Makefile.src when compilation is complete |
profile | Created by the merge process, it contains merge options |
merge.log | Created by the merge process, it contains all mkmerge output |
export.lst | The list of files to export; mkmake uses this file to determine which files it should copy and where to copy them |
Makefile | The top level Makefile, produced by mkmk |
For the OS
component, the OS
source files are merged into the component's build directory, build_dir/build-OS. In this directory, exports.1st is produced by the mkmerge command.
This directory relies on the profile file to ensure that
the NUCLEUS
component is merged before the OS
component.
To look in greater detail at the OS
build directory,
list the contents of build_dir/build-OS/src/sys. This directory contains the following:
File |
Description |
---|---|
Makefile | The Makefile of the directory, produced by mkmk |
C_OS | The C_OS actor |
all.dp | Dependency file, produced by make depend and getExport |
sys_agglo.mk | Internal Makefile, used when linking the configurable actor, to copy files from the src directory to the obj directory |
sys.bf |
The build file |
sys.df |
The definition file |
sys_rule.xml |
XML rules for the |
sys_action.xml |
XML action rules for the |
The contents the sys.bf and sys.df files, the Makefile and the common.mf and all.dp files are given below:
The sys.df file, defines the INCLUDES and DEFINES variables.
INCLUDES=" \ -I${OS_DIR}/src/sys \ -I${OS_DIR}/src/sys/chorus/sys \ -I${OS_DIR}/src/sys/sys \ -I${OS_DIR}/src/sys/machine \ -I${NUCLEUS_DIR}/include \ -I${NUCLEUS_DIR}/include/chorus \ -I${OS_DIR}/include/chorus \ -I${OS_DIR}/include" DEFINES="$DEFINES -DKERNEL -D_KERNEL -D__FreeBSD__ -DINET -DNO_CACHE" DEFINES="$DEFINES -DMSDOSFS -DNFS" FWARN=STRICT
In this example, S_LIBS
contains the list of
libraries used to link the OS
component. The ConfigurableActor rule is also used to link the OS
component to build the C_OS
actor.
S_LIBS = $(OS_DIR)/lib/sys/libufs.a \ $(OS_DIR)/lib/sys/libdisk.a \ $(OS_DIR)/lib/sys/libgen.a \ $(OS_DIR)/lib/sys/libmem.a \ $(OS_DIR)/lib/sys/libunresolved.a \ $(OS_DIR)/lib/sys/libloader.s.a \ $(NUCLEUS_DIR)/lib/zlib/zlib.a \ $(OS_DIR)/lib/sys/libio.s.a \ $(NUCLEUS_DIR)/lib/stdc/libstdc++.a \ $(NUCLEUS_DIR)/lib/embedded/libebd.s.a \ $(NUCLEUS_DIR)/lib/cpu/cpu.s.a \ $(NUCLEUS_DIR)/lib/ddi/net.s.a \ $(NUCLEUS_DIR)/lib/ddm/ddm.s.a \ $(NUCLEUS_DIR)/lib/sysevent/sysevent.a \ $(NUCLEUS_DIR)/lib/visu/visu.s.a \ $(NUCLEUS_DIR)/lib/gauges/gauges.s.a \ $(NUCLEUS_DIR)/lib/classix/libsys.s.a \ $(DRV_DIR)/lib/drv_tools/drv_tools.s.a ConfigurableActor(C_OS, $(S_LIBS))
The Makefile generated by mkmk contains two parts. The first part has a list of the definitions of variables as defined in Table 4-8, Table 4-9, Table 4-7 and Table 4-10. The second part contains preprocessed copies of the .bf, .lf, and .mf files found in the work directory. In this example there is only a .bf file present in the work directory.
BDIR = build_dir FAMILY = usparc COMPILER = gcc include $(BDIR)/Paths include $(DEVTOOLS_DIR)/tgt-make/host.conf include $(DEVTOOLS_DIR)/tgt-make/variables.rf BNAME = sys MPATH = src/sys DEFINES = -DKERNEL -D_KERNEL -D__FreeBSD__ -DINET -DNO_CACHE -DMSDOSFS -DNFS INCLUDES = -I/build_dir/build-OS/src/sys -Ibuild_dir /build-OS/src/sys/chorus/sys -I/build_dir/build-OS/src/sys/sys -I/build_dir/build-OS/src/sys/machine -I/build_dir/build-NUCLEUS/include -I/build_dir/build-NUCLEUS/include/chorus -I/build_dir/build-OS/include/chorus -I/build_dir/build-OS/include FEXCEPTION = OFF FFPU = ON FOPTIM = OFF FPROF = OFF FREMOTEDEB = ON FVERBOSE = OFF FASSERT = ON FWARN = STRICT FGCOV = OFF FPIC = OFF FLARGEGOT = OFF FVEC = OFF VARIABLES = OS_DIR NUCLEUS_DIR DRV_DIR OS_USER_LIBS OS_SUP_LIBS SUB_DIRS = cam chorus crypto dev isofs kern libkern machine miscfs msdosfs net netinet netinet6 netkey netns nfs nfs_noserver solaris sys ufs vm EXTRA_DIRS = BFILES = sys.bf MFILES = DFILES = debug.df sys.df MODULES = OS_DIR = build_dir/build-OS NUCLEUS_DIR = build_dir/build-NUCLEUS DRV_DIR = build_dir/build-DRV OS_USER_LIBS = build_dir/build-OS/lib/libc.a build_dir/build-OS/lib/sys/ libsystrap.u.a /net/abdias/export/build/orivat/chorus/dev-r50/sparc/dev-int2709/ build-OS/lib/libc.a OS_SUP_LIBS = build_dir/build-OS/lib/libc.a build_dir/build-OS/lib/sys/ libsyscall.a /build_dir/build-OS/lib/libc.a include $(BDIR)/Paths include $(DEVTOOLS_DIR)/tgt-make/shared.rf # produced from sys.bf -- begin S_LIBS = $(OS_DIR)/lib/sys/libufs.a \ $(OS_DIR)/lib/sys/libdisk.a \ $(OS_DIR)/lib/sys/libgen.a \ $(OS_DIR)/lib/sys/libmem.a \ $(OS_DIR)/lib/sys/libunresolved.a \ $(OS_DIR)/lib/sys/libloader.s.a \ $(NUCLEUS_DIR)/lib/zlib/zlib.a \ $(OS_DIR)/lib/sys/libio.s.a \ $(NUCLEUS_DIR)/lib/stdc/libstdc++.a \ $(NUCLEUS_DIR)/lib/embedded/libebd.s.a \ $(NUCLEUS_DIR)/lib/cpu/cpu.s.a \ $(NUCLEUS_DIR)/lib/ddi/net.s.a \ $(NUCLEUS_DIR)/lib/ddm/ddm.s.a \ $(NUCLEUS_DIR)/lib/sysevent/sysevent.a \ $(NUCLEUS_DIR)/lib/visu/visu.s.a \ $(NUCLEUS_DIR)/lib/gauges/gauges.s.a \ $(NUCLEUS_DIR)/lib/classix/libsys.s.a \ $(DRV_DIR)/lib/drv_tools/drv_tools.s.a BINARY += C_OS C_OS: $(S_LIBS) $(MKLINK) -r -c -e _start -o C_OS -B $(S_LIBS) # produced from sys.bf -- end include all.dp include $(DEVTOOLS_DIR)/tgt-make/tgtdevsys.rf DTL=${DEVTOOLS_DIR}/host/bin/
The common.mf file is found in the build_dir/build-OS/src/sys/chorus/lib/gen directory.
.... C__SRCS = \ insremque.c ovbcopy.c memstat.c util.c sysInitFuncs.c
The .mf files contain the definition of variables and nothing else. These variables are listed in Table 4-10.
The Makefile listed above for the OS
component, located at build_dir/build-OS/src/sys, includes a dependency file, all.dp. This dependency
file is located in the same directory as the Makefile.
In the OS
component, the all.dp
file contains the list of files upon which the linked binary files, such as
actors or libraries, are dependent. The -export lines at
the top of the file are used by getExport during the link
phase. In this example, as the directory contains no object file, these lines
are empty.
host% head all.dp # automatically generated file # -export ALL : # -export SUP : # -export USR : # built from a complex makefile C_OS: cam/scsi/all.dp C_OS: cam/scsi/scsi_da.o C_OS: cam/scsi/scsi_all.o .... C_OS: all.dp
This section shows you how to create your own component for your ChorusOS system. You can create this type of component with mkmk, imake or a tool of your choice.
A component must provide a set of Makefiles so that you can configure it using the configure tool. These Makefiles are as follows:
Makefile.bin for binary components
Makefile.src and Makefile.bin for source components.
When you receive the source delivery of the ChorusOS operating system, the Makefile.src and Makefile.bin files are provided for each component. This has the advantage that, prior to configuration, all the components have characteristics in common. Consequently, the components are compatible, even when they have been built using different tools.
You can choose a selection of components generated with the mkmk and imake tools to create your system image.
You can also create your own components by creating the Makefile.bin, Makefile.src, and src.df files yourself as shown in this chapter.
This section describes how to build a ChorusOS component with imake and the basic operations needed to manage your component. The information is provided in the form of a tutorial, leading you through an example which shows you how to perform each step.
The procedures below show you how to build a very simple ChorusOS component
called TEST
, containing an application that displays
a short message.
TEST
ComponentCreate a TEST directory in your /tmp directory to contain your new component.
host% cd /tmp/TEST host% mkdir TEST
Add the files listed below to the TEST directory
Makefile.bin
Makefile.src
Project.tmpl
Imakefile
src.df
Examples of these files are given below.
TEST
Component: Makefile.bin
The Makefile.bin file can contain the following information:
COMPONENT += TEST ROOT += $(TEST_DIR)/root TEST.all::
The first line in the output, which declares the component's name, is mandatory.
As the COMPONENT variable is the list of all components to be configured, use '+=', and not '='.
The ROOT variable contains a list of directories to be copied to the target root file system.
TEST
Component: Makefile.src
The Makefile.src file, can contain the following information:
all:: TEST.all TEST.all:: NUCLEUS.all OS.all DRV.all TEST.all:: $(TEST_DIR)/DONE $(TEST_DIR)/DONE: $(TEST_DIR)/Makefile sh $(DEVTOOLS_DIR)/resync TEST -f $(TEST) -s $(TEST_DIR) cd $(TEST_DIR); $(make) touch $(TEST_DIR)/DONE $(TEST_DIR)/Makefile: $(TEST)/Imakefile sh $(DEVTOOLS_DIR)/ChorusOSMkMf $(BUILD_DIR) -s $(TEST) -b $(TEST_DIR) -d $(TEST_DIR) cd $(TEST_DIR); $(make) Makefiles TEST_DIST = $(BUILD_DIR)/dist-TEST TEST.dist: TEST.all rm -rf $(TEST_DIST) cd $(TEST_DIR); $(make) DIST_DIR=$(TEST_DIST)
This file is more complex than the Makefile.bin
file as it describes how to build the component. The first lines of output
give the list of components that must be built before the TEST
component.
As your application requires operating system services, you must build
the NUCLEUS
and OS
components
before building the TEST
component.
TEST
Component: Project.tmpl
The Project.tmpl file can contain the following information:
#include "Package.rules" SRC_DIR = SourceDir BUILD_DIR = BuildDir DIST_DIR = DistDir VPATH = $(SRC_DIR)$(REL_DIR) WARN = $(WARN_ON) TEST_DIST_BIN = $(DIST_DIR)/bin/test
TEST
Component: Imakefile
The Imakefile indicates that you will have subdirectories (in this case /src).
#define IHaveSubdirs SUBDIRS = \ src DistFile(Makefile.bin,$(DIST_DIR))
TEST
Component: src.df
The src.df contains the following information:
. ../Paths VARIABLES="OS_DIR NUCLEUS_DIR" BDIR=${BUILD_DIR} SUB_DIRS=src
This file sets the parameters required for the make command to work.
You now need to create an application for the TEST
component to perform.
Create a subdirectory, src, within your /tmp/TEST directory.
host% cd /tmp/TEST host% mkdir src
Create the following two files:
This source file will say "Hello World":
#include <stdio.h> int main() { /* Print the message */ printf("Hello World\n"); return 0; }
This file provides rules to build the application:
CSRCS= bonjour.c OBJS= $(CSRCS:.c=.o) DEBUG=$(DEBUG_ON) UserActorTarget(bonjour_u,bonjour.o,) SupActorTarget(bonjour_s, bonjour.o,) DistActor(bonjour_u, $(DIST_DIR)/root/test/src) DistActor(bonjour_s, $(DIST_DIR)/root/test/src)The Imakefile file declares:
The source files to be compiled.
The libraries to be used.
The fact that you want to build the bonjour actor.
The fact that you want to copy the bonjour actor into the root/bin directory, once it is built.
Build your component in your work directory using the make command
host% make
Add the bonjour binary file to the target file system
host% make root
Once you have created the component, with its application, you must include it in the system configuration.
Run make reconfigure
Use the make reconfigure command in the directory in build_dir in which you have previously run configure to build your system image. Run make to compile your component:
host% make reconfigure='-s /tmp/TEST'
Compile the component
Type make to compile your TEST
component.
host% rm -rf build_dir/build-TEST host% make
This section demonstrates through examples how to add new features and tunables to the ChorusOS operating system.
Define the Tunable
To add a tunable (my_tunable) to the OS component, write an integer named my_tunable in an OS source file, as follows:
extern int my_tunable;This integer is configured using the external name iom.my.tunable. The default value for my_tunable is 0.
Add the Tunable to the XML Source Configuration File
To add the tunable to the XML source configuration file for the OS
component, go to the directory containing the OS
configuration files:
host% cd source_dir/os
Modify sys_rule.xml and sys_action.xml
To add the iom.my.tunable, you must modify two files, sys_rule.xml and sys_action.xml.
The sys_rule.xml file contains the description of the configurable entities as features and tunables, and their associated dependency.
The sys_action.xml file contains the internal implementation rules for management of features and tunables and provides the interface with the mkmk environment.
<tunable name=iom.my.tunable> <description> My Tunable </description> <int> <const>0</const> </tunable>
This definition includes the external name, a description field that will be accessible through the ews configuration tool, and a default value. All tunable values are integers; the default value is 0 in this example.
Include the standard rule used for the management of the OS tunables in sys_action.xml:
<setting name="sys.tunables"> <condition><ifdef name="iom.my.tunable"></condition> <value index="size"> <vstring>my_tunable iom.my.tunable ${iom.my.tunable}</vstring> </value> </setting>
iom.my.tunable is the external name of the tunable and my_tunable is the corresponding integer declaration in the source code.
Update the configuration in the build directory and build the new system image.
As you modified XML configuration files in the source directory, you must propagate these changes back to the work directory. Remove the corresponding XML files and run make xml.
host% cd build_dir host% rm conf/mkconfig/sys_rule.xml conf/mkconfig/sys_action.xml host% make xml
Set your tunable and check that it is now visible in the configuration
host% configurator -set iom.my.tunable=0x12345 host% configurator -list tunables | grep my host% iom.my.tunable:'0x12345'
Build the new system image and check that the tunable is in the C_OS actor:
host% make build host% powerpc-elf-nm image/RAM/chorus/bin/C_OS | grep my_ host% a00b44f0 D my_tunable a00b44f0: 00 01 23 45 .long 0x12345
Features are implemented by source code modules.
The example below demonstrates how to use modules to add a feature, called TEST
, to your ChorusOS operating system. In this feature, we
shall include a test file, mytest.c.
Create a test directory
host% cd source_dir/os/sys host% mkdir test
Create the a modules.df file in this directory
MODULES=bsd__test
Create mytest.c and common.mf files
mytest.c: #include <stdio.h> int hello() { printf("hello world\n"); return 0; }
common.mf: C__SRCS = \ mytest.c
Add the TEST
feature to the sys_action.xml and sys_rule.xml files
Add the following to sys_action.xml:
sys_action.xml: <!-- bsd__test=on/off --> <setting name="iom.modules"/> <description/>bsd__test/<description> <condition> <var name="TEST"> /<condition> <value index="size"> <const>bsd__test/<const> /<value> /<setting>
Add the following to the sys_rule.xml file:
sys_rule.xml: <feature name="TEST"> <description> TEST /<description> <false> /<feature>
Build the TEST
feature
Since the XML configuration files have been modified, you must propagate the changes. The existing sys_action.xml, and sys_rule.xml files must be updated.
host% cd build_dir host% rm conf/mkconfig/sys_rule.xml conf/mkconfig/sys_action.xml host% make xml
Check that the TEST
feature is present
host% build-DEVTOOLS/host/bin/configurator -list features | grep TEST TEST:bool='false'
Assert the TEST
feature
host% build-DEVTOOLS/host/bin/configurator -set TEST=true
Building the test directory
Before building a new archive with the TEST
feature asserted, merge the source code corresponding to TEST
within the working environment:
host% cd build_dir/build-OS/src host% ../../build-DEVTOOLS/host/bin/mkmerge -U host% cd build_dir host% make mkmk
To perform the merge, you must first run mkmerge in build-OS/ to perform a merge update, then run make mkmk in build_dir.
Compile the system to produce an new archive with the TEST
feature
host% make host% make chorus
XML files used during ChorusOS system generation
are copied to the conf directory, so that they can be
modified using the configurator command or the ews graphical tool. A component that adds new XML
files must have rules to execute these files in its Makefile.bin file. For instance, the Makefile.bin of the OS
component contains:
OS_XML = os.xml sys_rule.xml sys_action.xml cinit.xml cinit_action.xml hrCtrl.xm l hrCtrl_action.xml OS_SYSADM = sysadm.ini xml:: DEVTOOLS.all $(OS_DIR)/exports.lst @sh $(DEVTOOLS_DIR)/cpxml $(BUILD_DIR)/conf/mkconfig $(OS_DIR)/conf/ mkconfig $(OS_XML) @sh $(DEVTOOLS_DIR)/cpxml $(BUILD_DIR)/conf $(OS_DIR)/conf $(OS_SYSADM) @sh $(DEVTOOLS_DIR)/cpxml $(OS_DIR) $(OS) Makefile.bin
In this example, the XML files have to be copied from the OS
merged tree, so the XML target depends on $(OS_DIR)/exports.lst (which is produced by mkmerge
during the OS
merge). The cpxml
command acts as a wrapper around cp.