\documentclass[obeyspaces,spaces,hyphens]{beamer}
\usepackage[utf8]{inputenc}
\usepackage{minted}

\mode<presentation>
\usetheme{Bootlin}

\title{Buildroot Workshop}
\authors{Thomas Petazzoni}
\institute{Bootlin}

\usepackage{hyperref}

\begin{document}

\begin{frame}{Libre Software Meeting 2012}
  \begin{columns}[c]
   \column{0.6\textwidth}
     \huge
     Buildroot Workshop\\
     \vspace{1cm}
     \normalsize
     Thomas Petazzoni\\
     {\bf Bootlin}\\
     {\em thomas.petazzoni@bootlin.com}
     \column{0.4\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 training, Linux driver development training
      and Android system development training, with materials freely
      available under a Creative Commons license.
    \item \url{http://www.bootlin.com}
    \end{itemize}
  \item Major contributor to Buildroot, an open-source, simple and
    fast embedded Linux build system
  \item Speaker at Embedded Linux Conference, Embedded Linux
    Conference Europe, FOSDEM, Libre Software Meeting, etc.
  \item Living in Toulouse, south west of France
  \end{itemize}
\end{frame}

\begin{frame}{Agenda}
  \begin{itemize}
    \item Install necessary tools and packages
    \item Get Buildroot
    \item Build a minimal system, and boot it on the target
    \item Customize the system
    \item Create new packages, one library, one application
    \item Generate an UBIFS image, and flash the system in NAND
      flash
  \end{itemize}
\end{frame}

\begin{frame}{Workshop elements}

  You will find the slides and other files needed for this workshop
  at:

  \large
  \begin{center}
    \url{http://bootlin.com/~thomas/lsm-tutorial/}
  \end{center}

\end{frame}

\begin{frame}{Our target platform}
  \begin{columns}
    \column{0.4\textwidth}
    \begin{itemize}
    \item IGEPv2 from ISEE
    \item DM3730 (ARM OMAP3) at 1 GHz
    \item 512 MB of RAM, 512 MB of flash
    \item microSD, HDMI, audio, Ethernet, Bluetooth, Wifi
    \end{itemize}
    \column{0.6\textwidth}
    \includegraphics[width=\textwidth]{igep-v2-perspective.png}
  \end{columns}
  \vspace{1cm}
  \url{http://igep.es/products/processor-boards/igepv2-board}
\end{frame}

\begin{frame}{Tools to interact with the target}
  We'll need:
  \begin{itemize}
  \item A {\bf terminal emulator} program to interact with the target over
    the serial port
    \begin{block}{}
    \path{apt-get install picocom}
    \end{block}
  \item A {\bf TFTP server} to transfer the kernel image to the target
    \begin{block}{}
    \path{apt-get install tftpd-hpa}
    \end{block}
  \item A {\bf NFS server} to mount the root filesystem over the network
    \begin{block}{}
    \path{apt-get install nfs-kernel-server}
    \end{block}
  \end{itemize}
  Of course, adapt those instructions if you're not using a
  Debian-derived distribution.
\end{frame}

\begin{frame}[fragile]{Buildroot dependencies}
  Even though Buildroot builds most of the tools it needs, it still
  requires a few dependencies on the build system:
  \begin{block}{}
  \begin{verbatim}
apt-get install \
  build-essential gawk bison flex gettext \
  texinfo patch gzip bzip2 perl tar wget  \
  cpio python unzip rsync
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{Getting Buildroot}
  \begin{itemize}
  \item Tarballs are available for major versions, but since one
    generally needs to make changes to Buildroot, using Git is
    recommended
  \item Clone the repository
    \begin{block}{}
\begin{verbatim}
git clone git://git.busybox.net/buildroot
\end{verbatim}
\end{block}
  \item Create a branch starting from a stable release
    \begin{block}{}
\begin{verbatim}
git branch workshop 2012.05
\end{verbatim}
    \end{block}
  \item Switch to this branch
    \begin{block}{}
\begin{verbatim}
git checkout workshop
\end{verbatim}
    \end{block}
  \end{itemize}
\end{frame}

\begin{frame}{Initial configuration}
  Run \path{make menuconfig}
  \begin{itemize}
  \item {\bf Target architecture}: {\em ARM Little Endian}
  \item {\bf Target architecture variant}: {\em Cortex-A8}
  \item {\bf Toolchain}
    \begin{itemize}
    \item Toolchain type: {\em External toolchain}
    \item Toolchain: {\em CodeSourcery 2011.09}
    \end{itemize}
  \item {\bf System configuration}
    \begin{itemize}
    \item /dev management: {\em Dynamic using devtmpfs only}
    \item Port to run a getty on: {\em ttyO2}
    \end{itemize}
  \item {\bf Package selection for the target}
    \begin{itemize}
    \item Only Busybox is selected. This is fine for now.
    \end{itemize}
  \item {\bf Kernel}
    \begin{itemize}
    \item Kernel version: {\em Custom version}
    \item Kernel version: {\em 3.2}
    \item Custom kernel patches: \path{board/lsm/demo/linux-3.2-patches/}
    \item Defconfig name: \path{omap2plus}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Kernel patches}

  For this board to work with kernel 3.2, we need two patches to
  enable NAND support.

  \scriptsize
  \begin{block}{}
\begin{verbatim}
mkdir -p board/lsm/demo/linux-3.2-patches/

cd board/lsm/demo/linux-3.2-patches/

wget http://bootlin.com/~thomas/lsm-tutorial/
     linux-3.2-arm-omap3-igep0020-add-support-for-micron-nand-flash.patch

wget http://bootlin.com/~thomas/lsm-tutorial/
     linux-3.2-omap2-make-board-onenand-init-visible-to-board-code.patch
\end{verbatim}
  \end{block}

\end{frame}

\begin{frame}[fragile]{Running the build}
  Let's run the build, and keep a log from it:

  \begin{block}{}
\begin{verbatim}
make 2>&1 | tee logfile
\end{verbatim}
  \end{block}
\end{frame}

\begin{frame}{Build results}
  In the \code{output} directory, we have:
  \begin{itemize}
  \item \code{build}, with one subdirectory per package that has been
    built. The source code of the packages is extracted here, and they
    are compiled here.
  \item \code{host}, where host tools are installed. The external
    toolchain has been extracted in \code{host/opt}, in
    \code{host/usr/bin}, you have a few host tools, and in
    \code{host/usr/arm-unknown-linux-gnueabi/sysroot} you have the
    {\em sysroot}
  \item \code{staging}, symbolic link to the {\em sysroot}
  \item \code{target}, where the target libraries and applications are
    installed.
  \item \code{toolchain}, empty because we're using an external
    toolchain
  \item \code{images}, which contains the root filesystem as a
    tarball, and the kernel image. Look at the root filesystem size
    (it is uncompressed!)
  \end{itemize}
\end{frame}

\begin{frame}{A look at the dependencies}
  \begin{center}
    \includegraphics[width=\textwidth]{dependencies1.pdf}\\
    Generated with:\\
    \code{./support/scripts/graph-depends > deps.dot}\\
    \code{dot -Tpdf -o deps.pdf deps.dot}
  \end{center}
\end{frame}

\begin{frame}[fragile]{Preparing to boot}

\begin{enumerate}
\item Extract the root filesystem:

\begin{block}{}
\begin{verbatim}
mkdir /tmp/rootfs/
sudo tar -C /tmp/rootfs/ -xf output/images/rootfs.tar
\end{verbatim}
\end{block}

\item Export it over NFS, add the following line to \code{/etc/exports}:

\begin{block}{}
\scriptsize
\begin{verbatim}
/tmp/rootfs/ 192.168.42.2(rw,no_root_squash,no_subtree_check)
\end{verbatim}
\end{block}{}

\item And restart the NFS server:

\begin{block}{}
\begin{verbatim}
sudo /etc/init.d/nfs-kernel-server restart
\end{verbatim}
\end{block}{}

\item Copy the kernel image to the TFTP exported directory:

\begin{block}{}
\begin{verbatim}
sudo cp output/images/uImage /var/lib/tftpboot/
\end{verbatim}
\end{block}

\item Configure your system to assign the \code{192.168.42.1} static
  IP address to the USB-Ethernet interface (using Network Manager or
  \code{ifconfig})

\end{enumerate}

\end{frame}

\begin{frame}{Connecting the serial cable to the board}
  \begin{center}
    \includegraphics[width=\textwidth]{igep-v2-serial-cable.jpg}
  \end{center}
\end{frame}

\begin{frame}[fragile]{Preparing to boot, on the board}

\begin{enumerate}

\item Start a serial emulator program:

\begin{block}{}
\begin{verbatim}
picocom -b 115200 /dev/ttyUSB0
\end{verbatim}
\end{block}

\item When the board boots, interrupt in U-Boot during
\code{Hit any key to stop autoboot:} by pressing a key, and enter the
following commands:

\begin{block}{}
\scriptsize
\begin{verbatim}
setenv ipaddr 192.168.42.2
setenv serverip 192.168.42.1
setenv bootcmd 'tftp 80000000 uImage; bootm'
setenv bootargs 'console=ttyO2,115200 root=/dev/nfs ip=192.168.42.2 \
                 nfsroot=192.168.42.1:/tmp/rootfs'
saveenv
reset
\end{verbatim}
\end{block}

\item The system should boot automatically.

\end{enumerate}
\end{frame}

\begin{frame}{The system}

\begin{itemize}
\item Login as root, no password will be prompted.
\item Explore the system. You'll see that it is fairly minimal. We
  have:
  \begin{itemize}
  \item Busybox installed (in \code{/bin}, \code{/sbin},
    \code{/usr/bin}, \code{/usr/sbin})
  \item The C library in \code{/lib}
  \item A bunch of configuration files and init scripts in
    \code{/etc/}
  \item \code{/proc} and \code{/sys} mounted
  \end{itemize}
\item In the running processes, we only have the usual kernel
  threads, the \code{init} process, a shell, and the
  \code{syslogd}/\code{klogd} daemons for login
\item For Buildroot, it is important that the {\bf default is small}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Customize the kernel configuration}
  Let's learn now how to customize the kernel configuration from
  Buildroot.
  \begin{enumerate}
  \item Run \code{make linux-menuconfig}
  \item In \code{Device Drivers} $\rightarrow$ \code{LED Support},
    enable as static options (with a \code{*}, not a \code{M}):
    \begin{itemize}
    \item \code{LED Class support}
    \item \code{LED Support for GPIO connected LEDs}
    \item \code{LED Trigger support}
    \item \code{LED Timer trigger}
    \item \code{LED heartbeat trigger}
    \end{itemize}
  \item Rebuild by running \code{make}
  \item Copy your kernel image to the TFTP directory:
    \begin{block}{}
\begin{verbatim}
sudo cp output/images/uImage /var/lib/tftpboot/
\end{verbatim}
    \end{block}
  \end{enumerate}
\end{frame}

\begin{frame}[fragile]{Test the LEDs}

  Reboot your system, and try the following commands:
  \begin{block}{}
\begin{verbatim}
cd /sys/class/leds/gpio-led:green:d0
echo 255 > brightness
echo 0 > brightness
echo timer > trigger
echo heartbeat > trigger
echo none > trigger
\end{verbatim}
  \end{block}

\end{frame}

\begin{frame}[fragile]{Saving the kernel configuration}

  Our kernel configuration change has only been made to
  \code{output/build/linux-3.2/.config}, which will be removed if we
  do a \code{make clean}, so let's save our kernel configuration
  changes.
\begin{enumerate}
\item Generate a minimal defconfig for our kernel configuration:
  \begin{block}{}
\begin{verbatim}
make linux-savedefconfig
\end{verbatim}
  \end{block}
\item Store in our project-specific directory
  \begin{block}{}
    \scriptsize
\begin{verbatim}
mv output/build/linux-3.2/defconfig board/lsm/demo/linux-3.2.config
\end{verbatim}
  \end{block}
\item Adjust the Buildroot configuration:
  \begin{block}{}
\begin{verbatim}
make menuconfig
\end{verbatim}
    \end{block}
    \begin{itemize}
  \item \code{Linux Kernel} $\rightarrow$ \code{Kernel configuration} $\rightarrow$ \code{Using a custom configuration file}
  \item \code{Configuration file path}:
    \code{board/lsm/demo/linux-3.2.config}
  \end{itemize}
  \end{enumerate}
\end{frame}

\begin{frame}[fragile]{Enabling a new package: Dropbear}

  Let's enable a new package, the lightweight SSH client/server
  Dropbear.

  \begin{block}{}
    \begin{verbatim}
make menuconfig
\end{verbatim}
  \end{block}
  \vspace{1cm}
  \begin{block}{}
\begin{verbatim}
Package selection for the target
 -> Networking applications
    -> dropbear
\end{verbatim}
  \end{block}
\end{frame}

\begin{frame}[fragile]{Set root password}

\begin{enumerate}
\item Create \code{board/lsm/demo/post-build.sh} with:

\begin{block}{}
\scriptsize
\begin{verbatim}
#!/bin/sh
TARGETDIR=$1

# Set the root password to 'demo'
sed -i 's%^root::%root:pT41pCOBIPj3Q:%' $TARGETDIR/etc/shadow

# Disable login with the 'default' user
sed -i 's/^default::/default:*:/' $TARGETDIR/etc/shadow
\end{verbatim}
\end{block}

\item Add executable permissions to the script
\item In \code{make menuconfig}, \code{System configuration}
  $\rightarrow$
  \code{Custom script to run before creating filesystem images} set
  \code{board/lsm/demo/post-build.sh}.
\end{enumerate}

\end{frame}

\begin{frame}[fragile]{Testing SSH}
  \begin{enumerate}
  \item Run \code{make} to rebuild your system
  \item Re-extract the root filesystem tarball
    \begin{block}{}
\begin{verbatim}
sudo tar -C /tmp/rootfs/ output/images/rootfs.tar
\end{verbatim}
    \end{block}
  \item Boot your system, you should see Dropbear being started
  \item From your machine, log into your board through SSH:
    \begin{block}{}
\begin{verbatim}
ssh root@192.168.42.2
\end{verbatim}
    \end{block}
  \end{enumerate}
\end{frame}

\begin{frame}{Adding new packages}
  We'll now see how to add new packages, by taking the example of two
  dummy packages:
  \begin{itemize}
  \item {\bf libfoo}, a dummy library that implements just a
    \path{int foo_add(int a, int b);} function.\\
    Available at \url{http://bootlin.com/~thomas/lsm-tutorial/libfoo-0.1.tar.gz}
  \item {\bf foo}, a dummy application that uses {\bf libfoo}\\
    Available at \url{http://bootlin.com/~thomas/lsm-tutorial/foo-0.1.tar.gz}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{libfoo: Config.in}

  Create the \path{package/libfoo} directory, and edit
  \path{package/libfoo/Config.in}:

\begin{block}{}
\scriptsize
\begin{verbatim}
config BR2_PACKAGE_LIBFOO
        bool "libfoo"
        help
          libfoo is a wonderful package.

          http://bootlin.com/~thomas/lsm-tutorial/
\end{verbatim}
\end{block}

Then, edit \path{package/Config.in}, and under \code{Libraries} $\rightarrow$
\code{Other}, add:

\begin{block}{}
\begin{verbatim}
source "package/libfoo/Config.in"
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{libfoo: package/libfoo/libfoo.mk}

  Download the package tarball, and quickly study its build system. It
  uses the traditional \code{./configure; make; make install}
  mechanism, using the {\em autotools}. We'll use the
  \code{AUTOTARGETS} infrastructure for our package.

\begin{block}{}
\scriptsize
\begin{minted}{make}
LIBFOO_VERSION = 0.1
LIBFOO_SITE    = http://bootlin.com/~thomas/lsm-tutorial/

$(eval $(call AUTOTARGETS))
\end{minted}
\end{block}

\code{LIBFOO_SOURCE} could be defined to
\code{libfoo-$(LIBFOO_VERSION).tar.gz}, but since this is the default,
there's no need to mention it.

\end{frame}

\begin{frame}{libfoo: first test}
  \begin{enumerate}
  \item Enable your package in \code{make menuconfig}
  \item Run \code{make}
  \item Your library is correctly present in
    \code{output/target/usr/lib/libfoo.so.0.1}
  \item But the header files, and other developments files, are not
    present in \code{output/staging/usr/include/libfoo}
  \end{enumerate}
\end{frame}

\begin{frame}[fragile]{libfoo: installation to staging}

  For libraries, we need to explicitly tell Buildroot to install them
  to the {\em staging} directory.

\begin{block}{}
\scriptsize
\begin{minted}{make}
LIBFOO_VERSION = 0.1
LIBFOO_SITE    = http://bootlin.com/~thomas/lsm-tutorial/

LIBFOO_INSTALL_STAGING = YES

$(eval $(call AUTOTARGETS))
\end{minted}
\end{block}

\end{frame}

\begin{frame}{libfoo: second testing}
  \begin{enumerate}
  \item \code{make libfoo-dirclean}
  \item \code{make}
  \item Check in \code{output/staging/usr/include/libfoo} that the header file is installed.
  \item You should also have the static version of the library in
    \code{output/staging/usr/lib/} and the {\em pkgconfig} file
    \code{foo.pc} in \code{output/staging/usr/lib/pkgconfig}
  \end{enumerate}
\end{frame}

\begin{frame}[fragile]{libfoo: adding a configuration option (1/2)}

  Our wonderful {\bf libfoo} library supports one \code{./configure}
  option: \code{--enable-debug}. Let's add a new Buildroot option for
  it. In \code{package/libfoo/Config.in}, add:

\begin{block}{}
\begin{verbatim}
config BR2_PACKAGE_LIBFOO_DEBUG
        bool "Enable debugging support"
        depends on BR2_PACKAGE_LIBFOO
        help
          Enable debugging support in libfoo.
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]{libfoo: adding a configuration option (2/2)}

  In the \code{package/libfoo/libfoo.mk}:

\begin{block}{}
\begin{minted}{make}
ifeq ($(BR2_PACKAGE_LIBFOO_DEBUG),y)
LIBFOO_CONF_OPT += --enable-debug
endif
\end{minted}
\end{block}

\begin{itemize}
\item In \code{menuconfig}, enable your new option
\item Run \code{make libfoo-dirclean} to clean the package and force
  its rebuild
\item Run \code{make}
\end{itemize}

\end{frame}

\begin{frame}[fragile]{foo: \code{package/foo/Config.in}}

  Now, let's create a package for the application. First the
  \code{package/foo/Config.in} file:

\small
\begin{block}{}
\begin{verbatim}
config BR2_PACKAGE_FOO
        bool "foo"
        select BR2_PACKAGE_LIBFOO
        help
          Wonderful foo application

          http://bootlin.com/~thomas/lsm-tutorial/
\end{verbatim}
\end{block}

  And source it from the \code{Miscellaneous} section of
  \code{package/Config.in}:

\begin{block}{}
\begin{verbatim}
source "package/foo/Config.in"
\end{verbatim}
\end{block}

\end{frame}

\begin{frame}{foo: \code{package/foo/foo.mk}}

  Before writing the \code{foo.mk}, let's download
  \url{http://bootlin.com/~thomas/lsm-tutorial/foo-0.1.tar.gz}
  and look at its build system:

  \begin{itemize}
  \item It is based on a manual {\em Makefile}, so we will have to use
    the \code{GENTARGETS} infrastructure and not the
    \code{AUTOTARGETS} one
  \item It uses \code{pkg-config} to find the library \code{foo}. So
    we will have to depend on \code{libfoo} and \code{host-pkg-config}
  \item For the build, we will have to pass \code{CC}, \code{CFLAGS},
    \code{LDFLAGS}, etc. with appropriate values. To do this, we'll
    use the Buildroot variable \code{TARGET_CONFIGURE_OPTS}
  \item For the installation, we'll have to pass value for the
    \code{DESTDIR} and \code{prefix} variables
  \end{itemize}

\end{frame}

\begin{frame}[fragile]{foo: \code{package/foo/foo.mk}}

\begin{block}{}
\scriptsize
\begin{minted}{make}
FOO_VERSION = 0.1
FOO_SITE    = http://bootlin.com/~thomas/lsm-tutorial/

FOO_DEPENDENCIES += libfoo host-pkg-config

define FOO_BUILD_CMDS
        $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D)
endef

define FOO_INSTALL_TARGET_CMDS
        $(MAKE) $(TARGET_CONFIGURE_OPTS) \
                DESTDIR=$(TARGET_DIR) \
                prefix=/usr \
                install -C $(@D)
endef

$(eval $(call GENTARGETS))
\end{minted}
\end{block}

\end{frame}

\begin{frame}{Test \code{foo}}
  \begin{itemize}
  \item Enable the \code{foo} package in \code{menuconfig}
  \item Build your system with \code{make}
  \item Re-extract the root filesystem tarball to \code{/tmp/rootfs/}
  \item Reboot your system, and test the new \code{foo} application
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Save our configuration}

  In order to make our configuration usable by others, we'll create a
  {\em defconfig} from it:

  \begin{block}{}
\begin{verbatim}
make savedefconfig
mv defconfig configs/lsm_demo_defconfig
\end{verbatim}
  \end{block}

  Now, users of your Buildroot can simply do:

  \begin{block}{}
\begin{verbatim}
make lsm_demo_defconfig
make
\end{verbatim}
  \end{block}

  To rebuild an identical environment from scratch.

\end{frame}

\begin{frame}{Booting from flash}

  We know want to store the kernel and root filesystem in NAND
  flash. To do this, we will:

\begin{enumerate}
\item Add a custom \code{/etc/network/interfaces} file to the
  filesystem in order to not depend on the \code{ip=} kernel parameter
\item Configure Buildroot to generate an UBIFS/UBI image for the root
  filesystem
\item Adjust the U-Boot configuration and kernel arguments to boot
  from NAND flash.
\end{enumerate}

\end{frame}

\begin{frame}[fragile]{Custom \code{/etc/network/interfaces}}

  \begin{enumerate}
  \item Create the \code{board/lsm/demo/rootfs-additions} directory,
    which will be an overlay of our filesystem
  \item In our \code{post-build.sh} script, add:
    \begin{block}{}
\begin{verbatim}
# Copy the rootfs additions
cp -a board/lsm/demo/rootfs-additions/* $TARGETDIR/
\end{verbatim}
    \end{block}{}
  \item Create the
    \code{board/lsm/demo/rootfs-additions/etc/network/interfaces}
    file, with:
    \begin{block}{}
      \scriptsize
\begin{verbatim}
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
        address 192.168.42.2
        netmask 255.255.255.0
\end{verbatim}
    \end{block}
  \end{enumerate}
\end{frame}

\begin{frame}{Generate an UBIFS/UBI image}

  In \code{menuconfig}
  \begin{enumerate}
  \item Go in the \code{Filesystem images} menu
  \item Enable \code{ubifs root filesystem}
  \item Enable \code{Embed into an UBI image}
  \end{enumerate}

  Then, rebuild with \code{make}, and copy
  \code{output/images/rootfs.ubi} to \code{/var/lib/tftpboot}.

\end{frame}

\begin{frame}[fragile]{Adjust U-Boot configuration}

We will adjust the U-Boot environment variables.

\begin{itemize}
\item Kernel command line
\begin{block}{}
\tiny
\begin{verbatim}
setenv bootargs 'console=ttyO2,115200
   mtdparts=omap2-nand.0:512k(xloader),1536k(uboot),512k(env),4m(kernel),16m(rootfs)
   ubi.mtd=4 root=ubi0:rootfs rootfstype=ubifs'
\end{verbatim}
\end{block}
\item At boot time, load the kernel from NAND
\begin{block}{}
\scriptsize
\begin{verbatim}
setenv bootcmd 'nboot 80000000 0 280000; bootm'
\end{verbatim}
\end{block}
\item Helper script to flash the kernel in NAND
\begin{block}{}
\tiny
\begin{verbatim}
setenv flashkernel 'tftp 80000000 uImage;
  nand erase 0x280000 0x400000;
  nand write 0x80000000 0x280000 0x400000'
\end{verbatim}
\end{block}
\item Helper script to flash the rootfs in NAND
\begin{block}{}
\tiny
\begin{verbatim}
setenv flashrootfs 'tftp 80000000 rootfs.ubi;
  nand erase 0x680000 0x1000000;
  nand write 0x80000000 0x680000 ${filesize}'
\end{verbatim}
\end{block}
\end{itemize}

\end{frame}

\begin{frame}[fragile]{Adjust U-Boot configuration}

We will adjust the U-Boot environment variables.

\begin{itemize}
\item Helper script to flash the kernel and rootfs
\begin{block}{}
\begin{verbatim}
setenv flashall 'run flashkernel; run flashrootfs'
\end{verbatim}
\end{block}
\item Reflash
\begin{block}{}
\begin{verbatim}
run flashall
\end{verbatim}
\end{block}
\item And reboot to test the system
\begin{block}{}
\begin{verbatim}
reset
\end{verbatim}
\end{block}
\end{itemize}

\end{frame}

\begin{frame}{A final look at the dependencies}
  \begin{center}
    \includegraphics[width=\textwidth]{dependencies2.pdf}
  \end{center}
\end{frame}

\begin{frame}
  \begin{center}
  \Huge
  Thanks for attending, have fun with Buildroot!\\
  \vspace{1.5cm}
  \huge
  Thomas Petazzoni\\
  \large
  \vspace{0.5cm}
  \code{thomas.petazzoni@bootlin.com}
  \vspace{1.5cm}\\
  Slides under CC-BY-SA 3.0.
  \tiny
  PDF and sources will be available on
  \url{http://bootlin.com/pub/conferences/2012/lsm/}
  \end{center}
\end{frame}

\end{document}
