\input texinfo    @c -*-texinfo-*-
%
% wrs-build.in - main file for the documentation
%
%%%%

%------------------------------------------------------------------------------
%
%                         NOTE FOR THE UNAWARE USER
%                         =========================
%
%    This file is a texinfo source. It isn't the binary file of some strange
%    editor of mine. If you want ASCII, you should "make wrs-build.txt".
%
%------------------------------------------------------------------------------

%
% This is not a conventional info file...
% I use three extra features:
%   - The '%' as a comment marker, if at beginning of line ("\%" -> "%")
%   - leading blanks are allowed (this is something I can't live without)
%   - braces are automatically escaped when they appear in example blocks
%

@comment %**start of header
@documentlanguage en
@documentencoding ISO-8859-1
@setfilename wrs-build.info
@settitle wrs-build
@iftex
@afourpaper
@end iftex
@paragraphindent none
@comment %**end of header

@setchapternewpage off

@set update-month May 2011

@finalout

@titlepage
@title White Rabbit Switch: software build scripts
@subtitle @value{update-month}
@subtitle How to rebuild the whole software package from sources
@author Alessandro Rubini (@code{rubini@@gnudd.com})
@end titlepage
@headings single

@c ##########################################################################
@iftex
@contents
@end iftex

@c ##########################################################################
@node Top
@top Introduction

This document describes the software build procedures for the White
Rabbit Switch.  Currently the procedure described is in use for version 2 of
the hardware project.

If you don't need to make your hands dirty, just skip to @ref{Quick
Build}.

@menu
* Overview::                    
* Quick Build::                 
* The Compiler::                
* Buildroot::                   
* The IPL::                     
* The Boot Loader::             
* The Linux Kernel::            
* Kernel Modules::              
* User Space Tools::            
* The Complete Filesystem::     
@end menu

@c ##########################################################################
@node Overview
@chapter Overview

The scripts build over previous work by Tomasz Wlostowski, who first
made the whole thing work and stick together -- a serious result from
serious efforts, I'm really amazed by his achievements.

The rewriting described in this document (and embodied in the @code{build/}
subdirectory of the @code{wr-switch-sw} package) is meant to make the stuff
more maintainable over time.  I'm an old-fashioned follower of the rule
``first make it work then make it work well'', and this step is expected
to make it work well for everybody.

The purpose of the build-script rewrite is achieving the following targets:

@itemize @bullet
@item One-command build.
	The non-technical user should be able to rebuild the whole software
        package with a single command. This includes the IPL and boot-loader
        even though they are expected to be pre-installed in the switch with
        no real need for upgrading.
@item Sub-package separation.
	Users and developers should be able to rebuild each
        sub-package by itself. Sub-packages are the kernel,
	@i{buildroot}, libraries and so on. If you have a problem (or a
        customization you need on one sub-package), you should be able to work
        on the specific part ignoring the whole as much as possible.
@item Documentation.
	The steps are documented as much as possible, because mishaps
        do happen, and you should easily understand where the problem is.
@item Avoid redundant downloads.
	People with non-mainstream network connections would rather
	avoid downloading the same package over and over. Thus, a centralized
	download directory is defined where all external packages are
        retrieved. Even if you ``make distclean'' in the build scripts you
        won't need re re-get everything from the network.  In a similar
        mood, people who already have a local copy of the big packages
        (kernel, u-boot, white-rabbit svn) won't need to re-download not
        even the first time they build the WRS software.
@end itemize

The build system is set up as a mix of scripts and makefiles. Every
sub-package is built by its own script and/or Makefile, and configuration is
passed over through environment variables. The top-level build script
sets all environment variables, while keeping defaults from your
preexisting environment -- so you can override anything even when
rebuilding it all from scratch.

@menu
* Portability::                 
* Environment Variables::       
* Downloading Files::           
* The OHWR Repository::         
* Rebuilding Parts::            
@end menu

@c ==========================================================================
@node Portability
@section Portability

The scripts in their current status are not expected to be very
portable. I'm sure a number of @i{bashisms} exist, and I did no effort
to even identify them.  To relieve the user from possible pain,
internally the name @i{bash} is used instead of @i{sh}, so things
should work even if your default shell is @i{ash} or @i{dash}.

Similarly, the scripts are likely to fail if you use spaces in directory
names; that's because not all
uses of shell variables are properly quoted. I urge you to use directory names
with no spaces in them, or to submit a patch to fix the scripts.

It should go without saying that the build environment is expected to
be a native GNU/Linux system; success reports about other environments
(e.g. cygwin) are welcome, possibly with associated patches.

@c ==========================================================================
@node Environment Variables
@section Environment Variables

The scripts use a number of environment variables; you can pre-set
them as you wish. If they are not pre-set, defaults apply as
described below.

When rebuilding everything, the defaults are applied for each unset
variable; but when rebuilding a sub-package you'll need to set the
variables beforehand.  Each sub-package complains if it needs variables
that are not set in your environment.

The following variables are used in one or more parts of the scripts;
let me restate, though, that sensible default values apply by default,
so this list is mainly for your curiosity unless you are a developer.

They are listed in an order that seems logical to me, but may sound
random to a different person, please forgive this.  Most of the
variables are prefixed with @code{WRS_} to make them easily identified
in the overall mess of variables and command names (all scripts used here
have a similar prefix for the same reason).

@table @code
@item WRS_BASE_DIR
	The pathname of the build directory (i.e., the @code{build/}
        subdirectory of @code{wr-switch-sw}).
        The variable is internally set to the directory
        name of the main script. Note that the script can't
        be run from the same directory (i.e.: @code{./wrs_build-all}
        is not allowed), you must call it from your output directory
        using a pathname to  invoke it.  This variable can't be
        overridden in the main script, but must be pre-set if you run
        a sub-script to rebuild only part of the software suite.

@item WRS_OUTPUT_DIR
	The pathname of the directory where output is placed. It defaults
        to the current directory whence you invoke the script (i.e., you
        can invoke @code{/path/to/wrs_build-all} to have all output
        in the current directory).  Compilation
        happens in a @i{build} subdirectory of @code{WRS_OUTPUT_DIR},
        done-markers are placed in a @i{_done} subdirectory
        and final images are placed in a @i{images} subdirectory.

@item WRS_DOWNLOAD_DIR
	The directory where downloaded files are placed. If unset
        it defaults to @code{$WRS_OUTPUT_DIR/downloads}, which is
        created if needed.  By pre-setting this variable you can
        simply recursively delete
        the output directory to force a full rebuild, without
        the overhead of re-downloading everything.

@item WRS_WR_REPOSITORY
	The @i{url} of the @i{svn} repository for @i{White Rabbit}.
        It defaults to the official place in @i{ohwr.org} but may be
        pre-set to a local copy (e.g.:
	@code{file:///opt/ohwr-svn/white-rabbit}.  See @ref{The OHWR
        Repository} below about how to build a local copy of the repository.

@item CROSS_COMPILE
	The variable is the usual cross-compilation prefix. For example,
        @code{arm-linux-} if you have @i{arm-linux-gcc} in your path,
        or a full pathname without the trailing @code{gcc}. If unset,
        it defaults to the compiler that @i{buildroot} self-builds.
        See @ref{The Compiler} for some more details.

@end table

Other variables are used internally in the script; since they are only
useful to people working on the script itself, they are documented in
place.

@c ==========================================================================
@node Downloading Files
@section Downloading Files

Every downloaded file is saved to the download directory, you might
arrange not to remove that directory when you recompile over and over
during development.

If the file is missing in the download directory, it is retrieved from
one of the following places:

@itemize @bullet
@item If the file exists in the download directory, the @i{md5sum} is
      checked; on success, nothing else is done.
@item If the repository (@code{$WRS_WR_REPOSITORY}) is a @code{file://}
      identifier, then the copy from the local checkout is retrieved.
@item If the previous step fails, the file is retrieved from upstream.
@item If the previous step fails, the file is downloaded from the
      @i{ohwr} web site.
@end itemize

The policy just described is implemented in @i{wrs_download}, in the file
@code{scripts/wrs_functions}, based on @code{download-info} in the
main build directory.

@c ==========================================================================
@node The OHWR Repository
@section The OHWR Repository

Most of the code here (with the huge exception of @i{buildroot}
archives) comes from the @i{svn} repository at @code{ohwr.org}.

To avoid massive network downloads you can use a local copy of the
repository.  The environment variable @code{WRS_WR_REPOSITORY} can
point to a local checkout (use a @code{file://} notation), but you
can also have the complete history of the repository in your local
computer.  If you are not interested, you can skip this section.

@strong{Attention:} instead of this procedure, you may prefer @i{git-svn},
which is not described here at this point
@c FIXME: git-svn

Having a local repository is useful if you need to checkout older
versions, or just diff among versions or run @code{svn log}, which
will fail for White Rabbit over @u{http} due to the size of the
repository itself.

To make a local copy with @i{svnsync} you can do as follows
(thanks to Francisco Juan for teaching me about this):

@example
   export BASE="/opt/ohwr-svn"
   export REPO="white-rabbit"

   mkdir -p $BASE && cd $BASE
   svnadmin create $REPO
   echo '#!/bin/sh' > $REPO/hooks/pre-revprop-change
   chmod +x $REPO/hooks/pre-revprop-change
   svnsync init file://$BASE/$REPO http://svn.ohwr.org/$REPO
   svnsync sync file://$BASE/$REPO
@end example

To further track commits in the remote repository, you only need to
repeat the last command, ``@code{svnsync sync}''.

Then, to make a local checkout that refers to your local archive, you
can do like this:

@example
   mkdir -p $BASE/checkout && cd $BASE/checkout
   svn checkout file://$BASE/$REPO
@end example

After this, your @code{/opt/ohwr-svn/checkout/white-rabbit} will
refer to @code{/opt/ohwr-svn/white-rabbit} for every operation,
like @i{diff}, @i{log}, @i{update}.

To use the checkout in this project, and avoid extra downloads please
run:

@example
   export WRS_WR_REPOSITORY=file:///opt/ohwr/checkout/white-rabbit
@end example

@c ==========================================================================
@node Rebuilding Parts
@section Rebuilding Parts

When the script builds each part (sub-package), it creates a file in
the @code{build/_done} directory.

When you rebuild everything, steps for which the marker file exists
are not rebuilt. To force rebuilding of one specific part, just remove
the marker.  Markers are numbered, reflecting the order of compilation
steps, but they also have a name: names like @code{02-u-boot} should be
self-explicative.

As an alternative, you can run the individual script within
@i{scripts/}, after setting the proper environment variables.

@c ##########################################################################
@node Quick Build
@chapter Quick Build

If you just want to build stuff, with no concern about network
downloads and without even knowing what is happening, just create a
directory where you want the output to be generated and start
compilation. Note that it takes around 3GB of storage.

If possible, I strongly suggest to at least set the environment variable
@code{WRS_WR_REPOSITORY} to @code{file:///opt/ohwr-svn/white-rabbit}
or equivalent.

Then run:

@example
   /path/to/wr-switch-sw/build/wrs_build-all
@end example

The script refuses to run from within the package itself, because
@i{u-boot} would spit a puzzling @code{"fatal"} message and would
generate a strange version number for itself.

Note that progress messages are sent to @i{stderr}, so you may want to
save @i{stdout} to a file, like this:

@example
   /path/to/wr-switch-sw/build/wrs_build-all > logfile
@end example

Please note that there are also a number of warning messages being
printed to @i{stderr}. It's a few hundred lines over the few dozen
minutes it takes to build @i{buildroot}, but you can safely ignore them,
trusting the build process will complete successfully.

@b{Warning:} there is especially one hairy message being returned
by @i{wget} if you are using the @i{ohwr} repository: @code{ERROR 500:
Internal Server Error}. Please ignore this message, as it is about
a file that is not being used (nor explicitly looked for, actually).
Arranging for the message to be removed would have unpleasant side
effects, and you are not expected to lack a local copy in any case.

The progress messages look like what is shown here below.  The log
file will be rather big, as all the compilation steps are quite
verbose.

@smallexample
2011-05-18 00:26:45: --- Buildroot compiler and filesystem
2011-05-18 00:26:45: Looking for file buildroot-2009.11.tar.bz2
2011-05-18 00:26:45: Skip download of buildroot-2009.11.tar.bz2
2011-05-18 00:26:58: Copied packages from /opt/ohwr-svn/white-rabbit/trunk/pkg/buildroot-pkg
2011-05-18 00:26:58: Hardlinked packages from downloads to build place
2011-05-18 00:43:41: --- AT91Boot
2011-05-18 00:43:41: Looking for file AT91Bootstrap1.11.zip
2011-05-18 00:43:42: Skip download of AT91Bootstrap1.11.zip
2011-05-18 00:43:42: Patching AT91Boot
2011-05-18 00:43:42: Building AT91Boot
2011-05-18 00:43:42: --- U-Boot
2011-05-18 00:43:42: Looking for file u-boot-1.3.4.tar.bz2
2011-05-18 00:43:43: Skip download of u-boot-1.3.4.tar.bz2
2011-05-18 00:43:45: Patching U-Boot
2011-05-18 00:43:49: Building U-Boot
2011-05-18 00:44:05: --- Linux kernel for switch
2011-05-18 00:44:05: Looking for file buildroot-pkg/linux-2.6.35.tar.bz2
2011-05-18 00:44:07: Skip download of buildroot-pkg/linux-2.6.35.tar.bz2
2011-05-18 00:46:38: --- Kernel modules from this package
2011-05-18 00:46:43: --- PTP daemon (noposix repository)
2011-05-18 00:46:43: Using local git repository
2011-05-18 00:46:45: --- User space tools
2011-05-18 00:46:46: --- Wrapping filesystem
2011-05-18 00:46:47: Complete build succeeded, apparently
@end smallexample

You may prefer to save @i{stderr} with @i{stdout} to the log file
but still see the time-stamped messages from the scripts. In this
case you can issue the following command -- which is what I used
to generate the terse output shown above:

@example
   /path/to/wr-switch-sw/build/wrs_build-all 2>&1 | tee logfile \
        | grep '^20..-..-.. ..:'
@end example

If you are lucky, everything completes by itself in quite some minutes,
depending on you CPU, disk and network speed.
At the end you'll find your final files in the @code{images}
subdirectory.  If you are not too lucky, the build stops because
you've found a bug in the build scripts; most likely because your
setup differs from the ones we have been testing on.

In order to re-run the build from the beginning, please remove (or
rename) the output directory and reissue the command.  To only
redo one step, you can remove the marker in @code{build/_done}
(the markers are empty files with name like @code{00-buildroot}
and @code{03-kernel}).

@c ##########################################################################
@node The Compiler
@chapter The Compiler

The predefined compiler used here is the one built by @i{buildroot}.
The default configuration selects this choice.  If you pre-set a
different @code{CROSS_COMPILE} prefix in your environment, your own
choice will be used by modifying the @i{buildroot} configuration file.
Note, however, that not all cross-compilers will work (@i{buildroot}
wants one that has been configured with @code{--sysroot} and it is
quite unlikely yours has).

In practice, you may want to set @code{CROSS_COMPILE} when you compile
the boot loader and kernel by themselves, and avoid it when compiling
the complete package.

@c ##########################################################################
@node Buildroot
@chapter Buildroot

The distribution being used here is @i{buildroot}. It is the first
step being built, because it first creates a cross-compiler. Such a
compiler is later used to compile all other software for the White
Rabbit Switch.

The configuration for @i{buildroot} comes from
@code{patches/buildroot/buildroot-config-wrswitch}. The configuration
is then changed only if you pre-set your own @code{CROSS_COMPILE}
variable.

Since @i{buildroot} itself is a moving target, all packages needed to
build the chosen version with the default configuration of this
package are part of the White Rabbit @i{svn} repository (that you need
anyways to the WR-specific software packages.  Therefore, please set
the environment variable @code{WRS_WR_REPOSITORY} to the place where
you checked out the repository, without the @code{trunk} path
component. For example:

@example
   export WRS_WR_REPOSITORY=file:///opt/ohwr-svn/white-rabbit
@end example

If you want to change the configuration, you can do so after the first
build iteration: change directory to @code{build/buildroot-2009.11}
and run @code{make menuconfig}. After making your choices, copy back
the file @code{.config} to
@code{patches/buildroot/buildroot-config-wrswitch} in this package.

You can also set @code{WRS_BUILDROOT_CONFIG} to the full pathname of
your configuration file of choice. The file must be a copy of the
@code{.config} after the @code{make menuconfig} step described above.
Note that if the variable is not pointing to a regular file it is
ignored with a simple warning -- rather than stopping the build procedure.

@c ##########################################################################
@node The IPL
@chapter The IPL

The IPL being used is @i{AT91Bootstrap-1.11}, with a specific patch
for the White Rabbit Switch. The patch is written by Tomasz and is
part of this package (but is also in the @i{svn} repository at
@code{ohwr.org}).

After compilation, @code{images/dataflash_whiterabbit-mch.bin} is the
binary to be loaded in the actual hardware.

@c ##########################################################################
@node The Boot Loader
@chapter The Boot Loader

The boot loader in use is @i{u-boot-1.3.4}, with a specific patch for
the White Rabbit Switch, the patch is work of Tomasz. The patch is
part of this packages (but is also in the @i{svn} repository at
@code{ohwr.org}).

After compilation, the binary is found in @code{images/u-boot.bin}.
The ELF version is copied to @i{images} as well, as
@code{images/u-boot}; this file includes the symbol table and may be
useful -- or may not.

@c ##########################################################################
@node The Linux Kernel
@chapter The Linux Kernel

The kernel is currently version 2.6.35, compiled from an uncompressed
tar file (so not within a @i{git} repository).  The upstream
vanilla kernel is downloaded, then
local patches are applied (they come from a @i{git}
repository, but they are currently applied with a simple @i{patch}
command).

The configuration being used is copied from this package: it is
different from the default set forth by the patches
(i.e. @code{wrswitchv2_defconfig}) because it adds support for the MMC
card and NFS-Root. A later release of this package may integrate
the configuration within the kernel patches.

If you want to change the configuration, you can do so after the first
build iteration: change directory to @code{build/kernel}
and run @code{make menuconfig}. After making your choices, copy back
the file @code{.config} to
@code{patches/kernel/v2.6.35/linux-config-wrswitch} in this package.

You can also set @code{WRS_KERNEL_CONFIG} to the full pathname of
your configuration file of choice. The file must be a copy of the
@code{.config} after the @code{make menuconfig} step described above.
Note that if the variable is not pointing to a regular file it is
ignored with a simple warning -- rather than stopping the build procedure.

@c ##########################################################################
@node Kernel Modules
@chapter Kernel Modules

In the next step the scripts compile modules that are part of this
package.  The step depends on the kernel being available in the
build directory. The modules are then copied into the @code{images}
subdirectory of the main build directory.

Please note that modules (and later user-space) are compiled in-place,
not in the output directory.  The disadvantage is that your repository
becomes dirty with output and intermediate files; the advantage is that
any modification you make to the code is already in the repository
for your to commit.

@c ##########################################################################
@node PTPd
@chapter PTPd

The Precision Time Protocol Daemon being used is host in a different
repository. It's the code base that has been ported to compile in a
freestanding environment, downloaded from
@code{git://gnudd.com/ptp-noposix.git} .

A plain @i{make} in the directory will fail, because after building
@i{ptpd} other steps are tried, but they are only needed for
the freestanding environment (i.e., LM32 with supporting code) and will
fail for this @i{arm-linux} hosted build.

Additionally, the script installs the header and library for
@i{wr_ipc}, which are needed for later steps and are now part of the
@i{ptp} repository. Similarly, the script installs headers for the hal
and @i{libptpnetif}.

The script is known to work with version @code{fea09f7} of the @i{git}
repository, but the script checks out the @i{master} branch, being
confident newer versions will be at least as good as the current one
(for example, the current version as I write this has some concerning
warning messages).

@c ##########################################################################
@node User Space Applications
@chapter User Space Applications

The build of user space is concerned about the following steps:

@table @i
@item 3rdparty
	The directory includes the @i{lua} tool, used in the switch
        to parse the configuration file.

@item libswitchhw 
	This is a library of functions needed by the next
        step. @code{libswitchhw.a} is thus installed in @code{images/wr/lib}.

@item wrsw_hal
	This is the main application program for the White Rabbit Switch
        operation. The script installs the executable in @code{images/wr/bin}.

@item wrsw_rtud
	This is the daemon for the routing table unit, installed in
        @code{images/wr/bin}.

@end table

@c ##########################################################################
@node VHDL Binaries
@chapter VHDL Binaries

The binaries are currently missing from the filesystem-making procedures.

@c ##########################################################################
@node The Complete Filesystem
@chapter The Complete Filesystem

The final step in compiling the filesystem is making the CPIO archive
to be used as @i{ramdisk} in the switch.  The name of the file
@code{images/ramdisk.ext2} within the @code{WRS_BUILD_DIR}, even if
it has nothing to do with an @i{ext2} filesystem.  The name, however,
is the predefined one in @i{u-boot} configuration; so until we
change @i{u-boot}, it's easier for the image to keep this older name.

The filesystem is built by copying the @i{buildroot} file tree and
overlaying it with @code{userspace/rootfs_override/}; device files
are extracted from @code{userspace/devices.tar.gz}.

The @i{root} user has an empty password (set forth in
@code{userspace/rootfs_override/}) and authorizes a few @i{ssh} keys,
to allow @i{ssh} login (and @i{scp}) without the need to provide a
password -- though empty.  The script authorizes the key of the user
running the script and all keys listed in the file @code{authorized_keys}
in the main directory of this package, if present.

@c ##########################################################################
@bye


@c  LocalWords:  gnudd titlepage iftex texinfo CERN timestamping smallexample
@c  LocalWords:  LocalWords ietf timestamp misc timestamps ttstamp onestamp
@c  LocalWords:  Tomasz Wlostowski buildroot distclean defconfig wrswitch REPO
@c  LocalWords:  menuconfig config dataflash whiterabbit stdout stderr svnsync
@c  LocalWords:  filesystem diff ohwr http mkdir linux rubini itemize PTPd VHDL
@c  LocalWords:  noposix ptpd userspace libswitchhw
