\documentclass{beamer}
% Fix some Beamer warnings, see
% http://texblog.net/latex-archive/presentations/beamer-warnings/
\let\Tiny=\tiny
\usepackage[utf8]{inputenc}

\mode<presentation>
\usetheme{Bootlin}

\title{Using Buildroot for real projects}
\author{Thomas Petazzoni}
\institute{Bootlin}

\usepackage{eurosym}

\begin{document}

%% Title %%
\begin{frame}{Embedded Linux Conference Europe 2011}
  \begin{columns}[c]
   \column{0.5\textwidth}
     \huge
     Using {\em Buildroot} for real projects\\
     \vspace{1cm}
     \normalsize
     Thomas Petazzoni\\
     {\bf Bootlin}\\
     {\em thomas.petazzoni@bootlin.com}
     \column{0.5\textwidth}
     \includegraphics[width=\textwidth]{logo.png}
   \end{columns}
\end{frame}

\begin{frame}{Thomas Petazzoni}
  \begin{itemize}
  \item Embedded Linux engineer and trainer at Bootlin since
    2008
    \begin{itemize}
    \item Embedded Linux development: kernel and driver
      development, system integration, boot time and power
      consumption optimization, consulting, etc.
    \item Embedded Linux and driver development training, with
      materials freely available under a Creative Commons license.
    \item \url{https://www.bootlin.com}
    \end{itemize}
  \item Major contributor to Buildroot, an open-source, simple and
    fast embedded Linux build system
  \item Living in Toulouse, south west of France
  \end{itemize}
\end{frame}

\begin{frame}{Agenda}

\begin{itemize}
  \item What is Buildroot ?
  \item How does it work ?
  \item Example systems generated by Buildroot
  \item Recommendations for real projects
    \begin{itemize}
      \item Toolchain recommendations
      \item Project specific configuration and files
      \item Project specific packages
      \item Enabling application developers
      \item Misc best practices
    \end{itemize}
  \item Features in 2011.11 making things better
  \item Conclusion
\end{itemize}
\end{frame}

\begin{frame}{What is Buildroot ? (1/2)}

  \begin{itemize}
  \item Buildroot is an {\bf embedded Linux build system}
  \item Its goal is to build
    \begin{itemize}
      \item a {\bf cross-compiling toolchain}
      \item a {\bf root filesystem} with multiple cross-compiled
        libraries and applications
      \item a {\bf kernel image} and {\bf bootloader} images
    \end{itemize}
    or any combination of these
  \item It has a {\bf kconfig} configuration mechanism, identical to
    the one used in the kernel
  \item It is completely written in {\bf make}
  \item {\bf It builds only what's necessary}. A base system,
    containing just Busybox, takes less than 2 minutes to be built
    from scratch.
  \end{itemize}

\end{frame}

\begin{frame}{What is Buildroot ? (2/2)}

\begin{itemize}
  \item It is designed with {\bf simplicity} in mind
    \begin{itemize}
    \item Standard languages used, relatively lightweight
      infrastructure.
    \item Very easy to add packages or customize the build system
      behaviour.
    \end{itemize}
  \item It is best-suited for {\bf small to medium-sized embedded
    systems}
    \begin{itemize}
    \item In the generated root filesystem, Buildroot doesn't track
      which source package installed what. You need to do complete
      rebuilds for a clean root filesystem after configuration
      changes.
    \item Generates systems with no package management mechanism
      on the target (no ipkg, or apt)
    \end{itemize}
  \item 700+ packages
  \item {\bf Stable releases} published every three months
  \item {\bf Active user/developer community}
\end{itemize}

\end{frame}

\begin{frame}{Basic usage (1/2)}

{\tt \$ make menuconfig}

\begin{center}
\includegraphics[width=0.9\textwidth]{buildroot-menuconfig.png}
\end{center}

\end{frame}

\begin{frame}[fragile]{Basic usage (2/2)}

\begin{verbatim}
$ make
...
...
...
$ ls output/images/
dataflash_at91sam9m10g45ek.bin  rootfs.tar
rootfs.ubi                      rootfs.ubifs
u-boot.bin                      u-boot-env.bin
uImage
\end{verbatim}

\begin{center}
{\bf Ready to use !}
\end{center}

\end{frame}

\begin{frame}{How does it work ?}

\begin{itemize}
  \item Configuration options defined in {\tt Config.in} files, and
    stored in a {\tt .config} file
  \item Buildroot starts with the toolchain: either it generates it,
    or imports an existing toolchain, or uses {\em crosstool-NG} to
    generate one
  \item It creates a basic root filesystem from a {\em skeleton} (just
    a few configuration files)
  \item Once the toolchain is ready, Buildroot goes through the list
    of selected packages. It simply fetches, configures, builds and
    installs all packages, respecting their dependencies.
  \item It builds the kernel image and/or bootloader images, if
    requested
  \item It creates one or more root filesystem images, using {\em
    fakeroot}
\end{itemize}

\end{frame}

\begin{frame}{Top-level source code organization (1/2)}

\begin{itemize}
\item {\tt board/}\\contains hardware-specific and project-specific
  files. Covered later.
\item {\tt boot/}\\contains config options and recipes for various
  bootloaders
\item {\tt configs/}\\the default configurations. Covered later.
\item {\tt docs/}\\Yes, we have some documentation.
\item {\tt fs/}\\contains config options and makefiles to generate the
  various filesystem images (jffs2, ubifs, ext2, iso9660, initramfs,
  tar and more). Also contains the root filesystem {\em skeleton}
\end{itemize}

\end{frame}

\begin{frame}{Top-level source code organization (2/2)}

\begin{itemize}
\item {\tt linux/}\\contains the config options and makefile to
  generate the Linux kernel, and also the kernel part of real-time
  extensions (Xenomai, RTAI, etc.)
\item {\tt package/}\\contains the config options and makefiles for
  all userspace packages
\item {\tt support/}\\various misc stuff needed for the build ({\em
  kconfig} code, etc.)
\item {\tt target/}\\mostly historic directory. No longer contains
  anything useful besides the default {\em device table}.
\item {\tt toolchain/}\\config options and makefiles to build or
  import the toolchain
\end{itemize}

\end{frame}

\begin{frame}{What does it generate?}

In the output directory ({\tt output} by default, but out-of-tree
build with {\tt O=} is supported):

\begin{itemize}
  \item {\tt build/}, a directory with one sub-directory per component
    built. The directory contains the source of that component, and
    this is where it is built.
  \item {\tt host/}, a directory that contains the utilities built for
    the host machine, including the toolchain
    \begin{itemize}
      \item A subdirectory, {\tt host/usr/<tuple>/sysroot/} contains
        the toolchain {\em sysroot}, with all libraries and headers
        needed to build applications for the target.
    \end{itemize}
  \item {\tt staging/}, a historical symbolic link to {\tt
    host/usr/<tuple>/sysroot}
  \item {\tt target/}, the target root filesystem (without device
    files)
  \item {\tt images/}, where final images are stored

\end{itemize}

\end{frame}

\begin{frame}{Example 1: Multi-function device}

\begin{itemize}

  \item The device is an ARM AT91-based platform with GPS, RFID
    readers, GSM modem, Ethernet and USB.
  \item The Buildroot configuration:
    \begin{itemize}
    \item CodeSourcery ARM glibc toolchain
    \item {\em Linux kernel}
    \item {\em Busybox} for the basic system
    \item {\em Dropbear} for SSH access (debugging)
    \item {\em Qt} with only {\em QtCore}, {\em QtNetwork} and {\em QtXml}, no GUI
    \item {\em QExtSerialPort}
    \item {\em zlib}, {\em libxml2}, {\em logrotate}, {\em pppd}, {\em
      strace}, a special RFID library, {\em popt} library
    \item The {\em Qt} application
    \item JFFS2 root filesystem
    \end{itemize}
  \item Filesystem size: 11 MB. Could be reduced by using {\em uClibc}.
  \item Build time: 10 minutes on a fast build server (quad-core i7,
    12 GB of RAM)
\end{itemize}

\end{frame}

\begin{frame}{Example 2: vehicle navigation system}

  \begin{itemize}
  \item An x86-based system, with an OpenGL application for vehicle
    navigation system.
    \begin{itemize}
    \item External {\em glibc} toolchain generated with {\em
      crosstool-NG}
    \item The Grub bootloader
    \item {\em Linux kernel}, of course
    \item {\em Busybox}
    \item A part of the {\em X.org} stack (the server, a few drivers,
      and some client libraries), including {\em libdrm}, {\em Mesa}
    \item The {\em fglrx} ATI proprietary OpenGL driver
    \item {\em ALSA utils}, {\em ALSA library}, {\em V4L library},
      {\em Flashrom}, {\em LM Sensors}, {\em Lua}, {\em Dropbear},
      {\em Ethtool}
    \item The OpenGL application and its data
    \end{itemize}
  \item Filesystem size: 95 MB, with 10 MB of application (binary +
    data) and 45 MB (!) of {\em fglrx} driver.
  \item Build time: 27 minutes on a fast build server (quad-core i7,
    12 GB of RAM)
  \end{itemize}

\end{frame}

\begin{frame}{Toolchain}

Three choices:

\begin{itemize}

\item {\bf Buildroot builds a toolchain}. This is limited to {\em
  uClibc} based toolchains, and the toolchain is rebuilt completely at
  every complete Buildroot rebuild.

\item {\bf Buildroot uses {\em crosstool-NG}} as a back-end to generate
  the toolchain. More choices available ({\em glibc}, {\em eglibc},
  {\em uClibc} supported, more {\em gcc} versions, etc.). However,
  requires toolchain rebuild at every complete Buildroot rebuild.

\item {\bf Buildroot can import {\em external toolchains}}. This is
  definitely the mechanism I recommend.
  \begin{itemize}
  \item Allows to re-use {\em CodeSourcery} toolchains, or custom
    toolchains built with {\em crosstool-NG} or {\em Buildroot}
  \item Importing the toolchain into Buildroot takes just a few
    seconds, which saves the toolchain build time at every Buildroot
    rebuild
  \item The toolchain rarely needs to be changed compared to the root
    filesystem, so this mechanism makes sense
  \end{itemize}

\end{itemize}

\end{frame}

\begin{frame}{External toolchains: toolchain profile}

Buildroot contains presets for well-known binary toolchains such as
the CodeSourcery ones, for which Buildroot knows the properties (C
library used, etc.)  and the download location.

\begin{center}
  \includegraphics[width=0.8\textwidth]{toolchain-profile.png}
\end{center}

\end{frame}

\begin{frame}{External toolchains: custom toolchain}

Buildroot can also use custom, locally installed toolchains, in which
case one must tell Buildroot a few details about the toolchain (C
library being used, location, prefix, etc.)

\begin{center}
  \includegraphics[width=\textwidth]{toolchain-custom.png}
\end{center}

\end{frame}

\begin{frame}{External toolchains HOWTO}

\begin{itemize}
  \item You can either:
    \begin{itemize}
    \item Use an existing pre-built toolchain, available publicly from the
      Web
    \item Generate a custom toolchain, and store it pre-built next to the
      Buildroot directory on the local filesystem, or in some internal
      FTP/HTTP server
    \end{itemize}
  \item And then point your Buildroot configuration to this toolchain:
    \begin{itemize}
    \item As a {\em custom} toolchain
    \item Or by adding a new {\em profile} so that the toolchain gets
      downloaded automatically and all its configuration is already
      known to Buildroot
    \end{itemize}
  \item This way, users of the Buildroot environment don't have to
    worry about the toolchain and don't have to wait for it to build.
\end{itemize}

\end{frame}

\begin{frame}[fragile]{Project specific files}

For each project, the recommendation is to create a directory

\begin{verbatim}
   board/<company>/<project>/
\end{verbatim}

which will be used to store:

\begin{itemize}
\item Configuration files
\item Root filesystem additions
\item Project-specific kernel/bootloader patches
\item All other project specific files
\end{itemize}

\end{frame}

\begin{frame}{Kernel and bootloader changes}

\begin{itemize}
\item The kernel and bootloaders often require modifications for a
  particular hardware platform.
\item My typical workflow is the following :
\begin{itemize}
\item Have a branch in a kernel Git tree in which I commit
  the necessary changes
\item Generate patches with {\tt git format-patch}
\item Import them into Buildroot in the {\tt
  board/<company>/<project>/linux-patches/} directory
\item Configure Buildroot so that it applies the patches before
  building the kernel (option {\tt BR2\_LINUX\_KERNEL\_PATCH})
\end{itemize}
\item The advantage is that the Buildroot environment is easy to use
  for others (no external dependency on a kernel Git tree)
\item The drawback is that Buildroot does not directly use your kernel Git
  tree. This has been improved recently, covered later.
\end{itemize}

\end{frame}

\begin{frame}[fragile]{Kernel and bootloaders example (1/2)}

\begin{block}{}
\small
\begin{verbatim}
$ ls board/<company>/<project>/
linux-2.6.39.config         samba-script.tcl
linux-2.6.39-patches/       u-boot-1.3.4-patches/
at91bootstrap-1.16-patches/

$ ls board/<company>/<project>/linux-2.6.39-patches/
linux-0001-foobar.patch linux-0002-barfoo.patch

$ ls board/<company>/<project>/u-boot-1.3.4-patches/
u-boot-0001-barfoo.patch u-boot-0002-foobar.patch

$ ls board/<company>/<project>/at91bootstrap-1.16-patches/
at91bootstrap-0001-bleh.patch at91bootstrap-0002-blah.patch
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Kernel and bootloaders example (2/2)}

\begin{block}{}
\footnotesize
\begin{verbatim}
BR2_TARGET_UBOOT=y
BR2_TARGET_UBOOT_BOARDNAME="company_project"
BR2_TARGET_UBOOT_1_3_4=y
BR2_TARGET_UBOOT_CUSTOM_PATCH_DIR=
  "board/company/project/u-boot-1.3.4-patches/"
# BR2_TARGET_UBOOT_NETWORK is not set
BR2_TARGET_AT91BOOTSTRAP=y
BR2_TARGET_AT91BOOTSTRAP_BOARD="at91sam9m10g45ek"
BR2_TARGET_AT91BOOTSTRAP_CUSTOM_PATCH_DIR=
  "board/company/project/at91bootstrap-1.16-patches/"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="2.6.39"
BR2_LINUX_KERNEL_PATCH=
  "board/company/project/linux-2.6.39-patches/"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE=
  "board/company/project/linux-2.6.39.config"
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}{Root filesystem customization (1/3)}

The Buildroot process to create the root filesystem is:

\begin{itemize}
\item Copy a {\em skeleton} to the {\tt output/target} directory. The
  default one is in {\tt fs/skeleton}, but a different one can be
  used.
\item Copy base libraries (C libraries and al.) from the toolchain
  {\em sysroot} into the target root filesystem
\item Install all packages
\item Execute a configuration-specified post build script
\item Generate the filesystem images in the selected formats (jffs2,
  ubifs, etc.)
\end{itemize}

\end{frame}

\begin{frame}{Root filesystem customization (2/3)}

Depending on which modifications are necessary, you might need to:

\begin{itemize}

\item Use a {\bf different filesystem skeleton} if the default
  skeleton is {\em really} not appropriate. If only tiny modifications
  are needed, do them in the post build script. I don't recommend this
  solution as it consists in duplicating the default skeleton, which
  would prevent from taking advantage of future improvements of the
  default skeleton.

\item {\bf Create packages} to install applications, data files,
  etc. The skeleton is really only for basic config files.

\item {\bf Create a post build script} that adjusts the root
  filesystem as needed.

\end{itemize}

\end{frame}

\begin{frame}{Root filesystem customization (3/3)}

\begin{itemize}
\item Create a post-build script in {\tt
  board/<company>/<project>/post-build.sh} and tell Buildroot to run
  it with the {\tt BR2\_ROOTFS\_POST\_BUILD\_SCRIPT}.

\item This script is executed from the Buildroot main directory and receives
  the target filesystem directory as argument.

\item Typically, my script does:

  \begin{itemize}
  \item Tune the {\tt /etc/inittab}, {\tt /etc/fstab} or {\tt
    /etc/securetty} files
  \item Copy the contents of {\tt
    board/<company>/<project>/rootfs-additions/} into the target root
    filesystem.\\In this directory, I put additional init scripts,
    configuration files for network services, or override existing
    files.
  \end{itemize}
\end{itemize}

\end{frame}

\begin{frame}[fragile]{Root filesystem customization: example script}

\begin{block}{}
\scriptsize
\begin{verbatim}
TARGETDIR=$1

# Set root password to 'root'. Password generated with
# mkpasswd, from the 'whois' package in Debian/Ubuntu.
sed -i 's%^root::%root:8kfIfYHmcyQEE:%' $TARGETDIR/etc/shadow

# Application/log file mount point
mkdir -p $TARGETDIR/applog
grep -q "^/dev/mtdblock7" $TARGETDIR/etc/fstab || \
    echo "/dev/mtdblock7\t\t/applog\tjffs2\tdefaults\t\t0\t0" \
    >> $TARGETDIR/etc/fstab

# Copy the rootfs additions
cp -a $BOARDDIR/rootfs-additions/* $TARGETDIR/
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}{{\tt /dev} managament}

Buildroot offers four solutions for {\tt /dev} management:

\begin{itemize}
\item {\bf static}, where device files are created at build
  time. They are listed in a configurable {\em device table}.
\item {\bf devtmpfs}, the kernel filesystem which creates dynmically
  device nodes. Buildroot makes sure that your kernel has the right
  options selected. Recommended solution.
\item {\bf devtmpfs+mdev}, which allows to trigger scripts or
  applications on device insertion/removal.
\item {\bf devtmpfs+udev}, the full-fledge solution.
\end{itemize}

Whichever solution is choosen, there is still a {\em device table}
used, which is used to set specific permissions and ownership on
certain files or directories. The list of {\em device tables} is
configured through {\tt BR2\_ROOTFS\_DEVICE\_TABLE}.

\end{frame}

\begin{frame}{Project-specific packages (1/5)}

\begin{itemize}
  \item A project typically requires one or more specific packages,
    containing project-specific applications or libraries.
  \item In order to make the build process fully integrated, those can
    be integrated in Buildroot.
  \item In order to isolate your packages from all other packages,
    create a sub-directory for all your packages:
    \begin{itemize}
    \item Create a {\tt package/<company>/} directory\\This allows to
      isolate your specific packages from all other packages.
    \item Put a {\tt package/<company>/<company>.mk} files into it, with
      just:\\ {\tt include package/<company>/*/*.mk}\\ This tells
      Buildroot to parse the makefiles of your packages.
    \end{itemize}
  \item Obviously, if you need to package an existing open-source
    component, package it under {\tt package/} and submit the patch to
    the Buildroot community.
\end{itemize}

\end{frame}

\begin{frame}{Project-specific packages (2/5)}

For each package:

\begin{itemize}
  \item Create a {\tt package/<company>/<yourpkg>/} directory
  \item Create a {\tt package/<company>/<yourpkg>/<yourpkg>.mk}
    makefile that contains the recipe to build your package
  \item Create a {\tt package/<company>/<yourpkg>/Config.in} file
    that details the configuration options of your package. At least
    one is mandatory, in order to enable/disable your package.
  \item From {\tt package/Config.in}, source your {\tt
    package/<company>/<yourpkg>/Config.in}, preferably in a
    company-specific menu to make merges with future Buildroot
    versions easier.
\end{itemize}

\end{frame}

\begin{frame}{Project-specific packages (3/5)}

To create the {\tt .mk} file, three infrastructures are available:

\begin{itemize}

\item The {\bf AUTOTARGETS} infrastructure, for autotools-based
  packages.\\You describe the tarball URL and version, the dependencies
  and configuration options, and Buildroot does all the rest.
\item The {\bf CMAKETARGETS} infrastructure, for CMake-based
  packages.\\Here as well, Buildroot does most of the work.
\item The {\bf GENTARGETS} infrastructure, for other packages not
  using a well-known build system.\\Here, Buildroot has no knowledge
  of the build system, so you have to specify what needs to be done to
  configure, build and install the component.

\end{itemize}

See the Buildroot documentation for more details on using these
package infrastructures.

\end{frame}

\begin{frame}{Project-specific packages (4/5)}

\begin{itemize}

\item Typically, the package source code is downloaded as a tarball
  from HTTP/FTP or from a Git/Mercurial/Subversion repository.

\item For project-specific applications or libraries, it might be
  useful to store them locally.

  \begin{itemize}
  \item For small utilities, it can be directly in the package
    directory, in an {\tt src/} subdirectory.
  \item For larger programs or libraries having their own version
    control, it is possible to override the package extraction
    commands to copy their source code in the build directory
  \end{itemize}

\end{itemize}

\end{frame}

\begin{frame}[fragile]{Project-specific packages (5/5)}

The application source code is stored in {\tt ../company-application/}
relative to the Buildroot source code.

\begin{block}{}
\small
\begin{verbatim}
MY_APPLICATION_VERSION = 1.0
MY_APPLICATION_DEPENDENCIES = \
  qextserialport host-pkg-config

define MY_APPLICATION_EXTRACT_CMDS
        cp -a $(TOPDIR)/../company-application/* $(@D)/
endef

define MY_APPLICATION_INSTALL_TARGET_CMDS
        cp $(@D)/myapp $(BINARIES_DIR)
endef

$(eval $(call CMAKETARGETS))
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}{During application development}

\begin{itemize}

\item Buildroot is really an {\em integration} utility. Once a package
  has been built, it is not rebuilt, even if its source code changes.
\item When working on the development of a component, it is usually
  more convenient to build it outside of Buildroot, for a quicker
  compile/test/debug cycle.
\item The upcoming {\em source directory override} feature, covered
  later, makes it easier to use Buildroot during development.

\end{itemize}

\end{frame}

\begin{frame}{Using Buildroot to build external components}

\begin{itemize}
\item The {\tt output/host} directory is the Buildroot SDK.
\item {\tt output/host/usr/bin/ARCH-linux-*} are the cross-compilation
  utilities. A wrapper is used so that the compiler is passed the
  appropriate {\tt --sysroot} option. From the user perspective, the
  compiler therefore automagically finds the libraries and headers.
\item {\tt output/host/usr/bin} also contains other useful utilities
  for the build process
  \begin{itemize}
  \item {\tt pkg-config}, which is configured to look for libraries
    in the right location by default.
  \item {\tt qmake}, if Qt is used, also configured with the correct paths
  \end{itemize}
\item {\tt output/toolchainfile.cmake} is a {\em CMake} description of
  the toolchain. Can be passed to {\tt cmake} using {\tt
    -DCMAKE\_TOOLCHAIN\_FILE=...}.
\end{itemize}

\end{frame}

\begin{frame}[fragile]{Using Buildroot to build external components}

\begin{block}{A simple application}
\scriptsize
\begin{verbatim}
BRPATH/output/host/usr/bin/arm-unknown-linux-gcc -o prog prog.c
  $(BRPATH/output/host/usr/bin/pkg-config --libs --cflags glib-2.0)
\end{verbatim}
\end{block}

\begin{block}{Autotools component}
\scriptsize
\begin{verbatim}
export PATH=$PATH:BRPATH/output/host/usr/bin/
./configure --host=arm-unknown-linux
\end{verbatim}
\end{block}

\begin{block}{CMake component}
\scriptsize
\begin{verbatim}
cmake -DCMAKE_TOOLCHAIN_FILE=BRPATH/output/toolchainfile.cmake
make
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}{Forcing Buildroot to rebuild a package}

\begin{itemize}
\item Buildroot keeps {\bf stamp files} in the package build directory
  {\tt output/build/pkg-version/}. They are named {\tt
    .stamp\_extracted}, {\tt .stamp\_configured}, {\tt .stamp\_built},
  {\tt .stamp\_target\_installed}, etc.
\item Removing a stamp file and re-executing {\tt make} will {\bf
  force Buildroot to do the corresponding step} again.
\item Removing the complete package build directory will {\bf force
  Buildroot to rebuild the package from scratch}.
\item This will be improved in the upcoming Buildroot version.
\end{itemize}

\end{frame}

\begin{frame}{Using NFS during application development}

\begin{itemize}
  \item Mounting the root filesystem over NFS is very practical during
    development
  \item The {\tt output/target} directory created by Buildroot cannot
    directly be used for NFS mount, because it does not contain any
    device file and the permissions may not be correct. This is
    because Buildroot runs as non-root.
  \item The recommended way is:
    \begin{itemize}
    \item Ask Buildroot to generate a tarball image of the root
      filesystem
    \item Uncompress this tarball image, as root, in some directory
      exported by NFS.
    \item {\tt make \&\& tar -xf -C /nfsroot/ output/images/rootfs.tar}
    \end{itemize}
  \item {\tt /nfsroot} should be exported with the NFS options {\tt
    rw} and {\tt no\_root\_squash} in {\tt /etc/exports}
\end{itemize}

\end{frame}

\begin{frame}{Storing the project configuration}

\begin{itemize}

\item Once you have defined a Buildroot configuration for your
  project, you want to save it somewhere and allow others to use it.
\item Just do:
  \begin{itemize}
  \item {\tt make savedefconfig}\\Creates a {\tt defconfig} file in the
    top Buildroot source directory.
  \item {\tt mv defconfig configs/company\_project\_defconfig}
  \end{itemize}
\item Others can then load this configuration very easily:
  \begin{itemize}
  \item {\tt make company\_project\_defconfig}
  \end{itemize}
\end{itemize}

\end{frame}

\begin{frame}{Summarizing the project-specific bits}

\begin{itemize}
  \item In the end, your project-specific bits are in:
  \begin{itemize}
  \item {\tt board/<company>/<project>/} for the kernel and bootloader
    patches and configuration, post-build script and root filesystem
    overlay
  \item {\tt configs/company\_project\_defconfig} for the Buildroot
    configuration.
  \item {\tt package/company/} for your specific packages
  \end{itemize}
\item Your modifications are cleanly isolated from the Buildroot
  core, making it easy to upgrade Buildroot when needed.
\end{itemize}
\end{frame}

\begin{frame}{Be prepared for offline builds}

\begin{itemize}
\item When working on a project, you'll want to make sure that your
  build can be done offline in order to not depend on resources that
  may disappear from the Net.
\item Here are some useful Buildroot features to do so:
  \begin{itemize}
  \item {\tt make source} will download into the Buildroot download
    cache {\em all} the files required to do the build
  \item {\tt make external-deps} will list the name of all the files
    (essentially tarballs) that are required to do the
    build. Identifies the useful tarballs in the Buildroot download
    cache.
  \item With the {\tt BR2\_PRIMARY\_SITE} configuration option,
    Buildroot will download files from a specified HTTP/FTP server
    {\em before} trying to reach the official site for each
    package. Useful to create an internal server.
  \item The location of the local download cache can be configured
    with {\tt BR2\_DL\_DIR} or with the {\tt BUILDROOT\_DL\_DIR}
    environment variable.
  \end{itemize}
\end{itemize}

\end{frame}

\begin{frame}{In 2011.11: local method}

\begin{itemize}
  \item The upcoming 2011.11 release will natively support packages
    whose source code is in a local directory.
  \item Simply need to use:\\
    {\tt MYPKG\_SITE = /some/local/directory}\\
    {\tt MYPKG\_SITE\_METHOD = local}
  \item Buildroot will {\em rsync} the source code from the specified
    location into its build directory in {\tt
      output/build/pkg-version}.
\end{itemize}

\end{frame}

\begin{frame}{In 2011.11: source directory override}

\begin{itemize}
  \item A package typically specifies a HTTP or FTP location for its tarball
  \item You might want to use a local source code for this package,
    instead of the official tarball
  \item The upcoming 2011.11 allows to specify an {\em override file}
    \begin{itemize}
    \item This file is simply a {\em makefile} with variable
      assignments
    \item Those variable assignments allows you to tell Buildroot:
      ``for package foo, use the source code in this directory rather
      than the normal tarball location''
    \item {\tt ZLIB\_OVERRIDE\_SRCDIR = /home/foo/my-zlib/}
    \item {\tt LINUX\_OVERRIDE\_SRCDIR = /home/foo/linux-2.6/}
    \end{itemize}
  \item The source code is {\em rsync'ed} from the given source
    directory into the Buildroot build directory.
\end{itemize}

\end{frame}

\begin{frame}{In 2011.11: other features}

\begin{itemize}
\item Addition of {\tt make <pkg>-reconfigure} and {\tt make
  <pkg>-rebuild}
  \begin{itemize}
  \item Instead of manually manipulating the stamp files, those
    commands restart the package build process at the configuration
    stage or at the compilation stage.
  \item Makes using {\em Buildroot} during kernel or application
    development a lot easier.
  \end{itemize}
\item Support for fetching from Mercurial repository
\item Support for fetching using {\tt scp}, both for packages and for
  the {\em primary download site}
\end{itemize}

\end{frame}

\begin{frame}{Conclusion}

\begin{itemize}
\item Buildroot has multiple features making it easy to customize the
  generated system
  \begin{itemize}
  \item Addition of kernel and bootloader patches and configuration
  \item Addition of project specific configuration files and scripts
  \item Addition of project specific packages
  \end{itemize}
\item These features makes Buildroot suitable to generate embedded
  Linux systems for a wide range of projects, with a preference on
  moderately large systems.
\item From our experience, Buildroot also remains simple enough to be
  used and understood by non-Linux experts.
\end{itemize}

\end{frame}

\begin{frame}
  \begin{center}
  \Huge
  Questions?\\
  \vspace{1.5cm}
  \huge
  Thomas Petazzoni\\
  \large
  \vspace{0.5cm}
  \code{thomas.petazzoni@bootlin.com}
  \vspace{1.5cm}\\
  \scriptsize
  Special thanks to the Buildroot community, including
  Peter Korsgaard, Baruch Siach, Thomas de Schampheleire, Arnout
  Vandecappelle and Will Moore for their comments and suggestions on
  this presentation.\\
  Slides under CC-BY-SA 3.0.
  \end{center}

\end{frame}

\end{document}
