\subsection{The U-boot bootloader}

\begin{frame}
  \frametitle{U-Boot}
  U-Boot is a typical free software project
  \begin{itemize}
  \item Freely available at \url{http://www.denx.de/wiki/U-Boot}
  \item Documentation available at
    \url{http://www.denx.de/wiki/U-Boot/Documentation}
  \item The latest development source code is available in a Git
    repository:
    \url{http://git.denx.de/cgi-bin/gitweb.cgi?p=u-boot.git;a=summary}
  \item Development and discussions happen around an open mailing-list
    \url{http://lists.denx.de/pipermail/u-boot/}
  \item Since the end of 2008, it follows a fixed-interval release
    schedule. Every two months, a new version is released. Versions
    are named \code{YYYY.MM}.
\end{itemize}
\end{frame}

\begin{frame}
  \frametitle{U-Boot configuration}
  \begin{itemize}
  \item Get the source code from the website, and uncompress it
  \item The \code{include/configs/} directory contains one
    configuration file for each supported board
    \begin{itemize}
    \item It defines the CPU type, the peripherals and their configuration, the
      memory mapping, the U-Boot features that should be compiled in, etc.
    \item It is a simple \code{.h} file that sets pre-processor
      constants. See the \code{README} file for the documentation of
      these constants.
    \end{itemize}
  \item Assuming that your board is already supported by U-Boot, there
    should be one file corresponding to your board, for example
    \code{include/configs/igep0020.h}
  \item This file can also be adjusted to add or remove features from
    U-Boot
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{U-Boot configuration file excerpt}
  \begin{columns}
    \column{0.5\textwidth}
    \scriptsize
\begin{verbatim}
/* CPU configuration */
#define CONFIG_ARMV7 1
#define CONFIG_OMAP 1
#define CONFIG_OMAP34XX 1
#define CONFIG_OMAP3430 1
#define CONFIG_OMAP3_IGEP0020 1
[...]
/* Memory configuration */
#define CONFIG_NR_DRAM_BANKS 2
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
#define PHYS_SDRAM_1_SIZE (32 <<  20)
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
[...]
/* USB configuration */
#define CONFIG_MUSB_UDC 1
#define CONFIG_USB_OMAP3 1
#define CONFIG_TWL4030_USB 1
[...]
\end{verbatim}
    \column{0.5\textwidth}
    \scriptsize
\begin{verbatim}
/* Available commands and features */
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_FAT
#define CONFIG_CMD_I2C
#define CONFIG_CMD_MMC
#define CONFIG_CMD_NAND
#define CONFIG_CMD_NET
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_PING
#define CONFIG_CMD_NFS
#define CONFIG_CMD_MTDPARTS
[...]
\end{verbatim}
  \end{columns}
\end{frame}

\begin{frame}
  \frametitle{Configuring and compiling U-Boot}
  \begin{itemize}
  \item U-Boot must be configured before being compiled
    \begin{itemize}
    \item \code{make BOARDNAME_config}
    \item Where \code{BOARDNAME} is usually the name of the
      configuration file in \code{include/configs/}, without the
      \code{.h}
    \end{itemize}
  \item Make sure that the cross-compiler is available in \code{PATH}
  \item Compile U-Boot, by specifying the cross-compiler prefix.\\
    Example, if your cross-compiler executable is \code{arm-linux-gcc}:\\
    \code{make CROSS_COMPILE=arm-linux-}
  \item The result is a \code{u-boot.bin} file, which is the U-Boot
    image
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Installing U-Boot}
  \begin{itemize}
  \item U-Boot must usually be installed in flash memory to be
    executed by the hardware. Depending on the hardware, the
    installation of U-Boot is done in a different way:
    \begin{itemize}
    \item The CPU provides some kind of specific boot monitor with
      which you can communicate through serial port or USB using a
      specific protocol
    \item The CPU boots first on removable media (MMC) before booting
      from fixed media (NAND). In this case, boot from MMC to reflash
      a new version
    \item U-Boot is already installed, and can be used to flash a new
      version of U-Boot. However, be careful: if the new version of
      U-Boot doesn't work, the board is unusable
    \item The board provides a JTAG interface, which allows to write
      to the flash memory remotely, without any system running on the
      board. It also allows to rescue a board if the bootloader
      doesn't work.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{U-boot prompt}
  \begin{itemize}
  \item Connect the target to the host through a serial console
  \item Power-up the board. On the serial console, you will see
    something like:
  \end{itemize}
\scriptsize
\begin{verbatim}
U-Boot 2011.12 (May 04 2012 - 10:31:05)
OMAP36XX/37XX-GP ES1.2, CPU-OPP2, L3-165MHz, Max CPU Clock 1 Ghz
IGEP v2 board + LPDDR/ONENAND
I2C:   ready
DRAM:  512 MiB
NAND:  512 MiB
MMC:   OMAP SD/MMC: 0
[...]
Net:   smc911x-0
Hit any key to stop autoboot:  0
U-Boot #
\end{verbatim}
\normalsize
  \begin{itemize}
  \item The U-Boot shell offers a set of commands. We will study the
    most important ones, see the documentation for a complete
    reference or the \code{help} command.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Information commands}
\scriptsize
  {\bf Flash information (NOR and SPI flash)}
\begin{verbatim}
U-Boot> flinfo
DataFlash:AT45DB021
Nb pages: 1024
Page Size: 264
Size= 270336 bytes
Logical address: 0xC0000000
Area 0: C0000000 to C0001FFF (RO) Bootstrap
Area 1: C0002000 to C0003FFF Environment
Area 2: C0004000 to C0041FFF (RO) U-Boot
\end{verbatim}
  {\bf NAND flash information}
\begin{verbatim}
U-Boot> nand info
Device 0: NAND 256MiB 3,3V 8-bit, sector size 128 KiB
\end{verbatim}
  {\bf Version details}
\begin{verbatim}
U-Boot> version
U-Boot 2009.08 (Nov 15 2009 - 14:48:35)
\end{verbatim}
\normalsize
Those details will vary from one board to the other (according to the
U-Boot configuration and hardware devices)
\end{frame}

\begin{frame}
  \frametitle{Important commands (1)}
  \begin{itemize}
  \item The exact set of commands depends on the U-Boot configuration
  \item \code{help} and \code{help command}
  \item \code{boot}, runs the default boot command, stored in
    \code{bootcmd}
  \item \code{bootm <address>} , starts a kernel image loaded at the
    given address in RAM
  \item \code{ext2load}, loads a file from an ext2 filesystem to RAM
    \begin{itemize}
    \item And also \code{ext2ls} to list files, \code{ext2info} for
      information
    \end{itemize}
  \item \code{fatload}, loads a file from a FAT filesystem to RAM
    \begin{itemize}
    \item And also \code{fatls} and \code{fatinfo}
    \end{itemize}
  \item \code{tftp}, loads a file from the network to RAM
  \item \code{ping}, to test the network
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Important commands (2)}
  \begin{itemize}
  \item \code{loadb}, \code{loads}, \code{loady}, load a file from the
    serial line to RAM
  \item \code{usb}, to initialize and control the USB subsystem,
    mainly used for USB storage devices such as USB keys
  \item \code{mmc}, to initialize and control the MMC subsystem, used
    for SD and microSD cards
  \item \code{nand}, to erase, read and write contents to the NAND
  \item \code{erase}, \code{protect}, \code{cp}, to erase, modify
    protection and write to a NOR flash
  \item \code{md}, displays memory contents. Can be useful to check the
    contents loaded in memory, or to look at hardware registers.
  \item \code{mm}, modifies memory contents. Can be useful to modify
    directly hardware registers, for testing purposes.
\end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Environment variables commands}
  \begin{itemize}
  \item U-Boot can be configured through environment variables, which
    affect the behavior of the different commands.
  \item Environment variables are loaded from Flash to RAM at U-Boot
    startup, can be modified and saved back to Flash for persistence
  \item There is a dedicated location in Flash to store U-Boot
    environment, defined in the board configuration file
  \item Commands to manipulate environment variables:
    \begin{itemize}
    \item \code{printenv}, shows all variables
    \item \code{printenv <variable-name>}, shows the value of one variable
    \item \code{setenv <variable-name> <variable- value>}, changes the
      value of a variable, only in RAM
    \item \code{saveenv}, saves to Flash the current state of the environment
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Environment variables commands (2)}
\begin{verbatim}
u-boot # printenv
baudrate=19200
ethaddr=00:40:95:36:35:33
netmask=255.255.255.0
ipaddr=10.0.0.11
serverip=10.0.0.1
stdin=serial
stdout=serial
stderr=serial
u-boot # printenv serverip
serverip=10.0.0.2
u-boot # setenv serverip 10.0.0.100
u-boot # saveenv
\end{verbatim}
\end{frame}

\begin{frame}
  \frametitle{Important U-Boot env variables}
  \begin{itemize}
  \item \code{bootcmd}, contains the command that U-Boot will
    automatically execute at boot time after a configurable delay, if
    the process is not interrupted
  \item \code{bootargs}, contains the arguments passed to the Linux
    kernel, covered later
  \item \code{serverip}, the IP address of the server that U-Boot will
    contact for network related commands
  \item \code{ipaddr}, the IP address that U-Boot will use
  \item \code{netmask}, the network mask to contact the server
  \item \code{ethaddr}, the MAC address, can only be set once
  \item \code{bootdelay}, the delay in seconds before which U-Boot
    runs bootcmd
  \item \code{autostart}, if yes, U-Boot starts automatically an image
    that has been loaded into memory
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Scripts in environment variables}
  \begin{itemize}
  \item Environment variables can contain small scripts, to execute
    several commands and test the results of commands.
    \begin{itemize}
    \item Useful to automate booting or upgrade processes
    \item Several command can be chained using the \code{;} operator
    \item Tests can be done using
      \code{if command ; then ... ; else ... ; fi}
    \item Scripts are executed using \code{run <variable-name>}
    \item You can reference other variables using
      \code{${variable-name}}
    \end{itemize}
  \item Example
    \begin{itemize}
    \item \code{setenv mmc-boot 'mmc init 0; if fatload mmc 0 80000000
      boot.ini; then source; else if fatload mmc 0 80000000 uImage;
      then run mmc-bootargs; bootm; fi; fi'}
  \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Transferring files to the target}
  \begin{itemize}
  \item U-Boot is mostly used to load and boot a kernel image, but it
    also allows to change the kernel image and the root filesystem
    stored in flash.
  \item Files must be exchanged between the target and the development
    workstation. This is possible:
    \begin{itemize}
    \item Through the network if the target has an Ethernet
      connection, and U-Boot contains a driver for the Ethernet
      chip. This is the fastest and most efficient solution.
    \item Through a USB key, if U-Boot support the USB controller of
      your platform
    \item Through a SD or microSD card, if U-Boot supports the MMC
      controller of your platform
    \item Through the serial port
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{TFTP}
  \begin{itemize}
  \item Network transfer from the development workstation and U-Boot
    on the target takes place through TFTP
    \begin{itemize}
    \item {\em Trivial File Transfer Protocol}
    \item Somewhat similar to FTP, but without authentication and over
      UDP
    \end{itemize}
  \item A TFTP server is needed on the development workstation
    \begin{itemize}
    \item \code{sudo apt-get install tftpd-hpa}
    \item All files in \code{/var/lib/tftpboot} are then visible
      through TFTP
    \item A TFTP client is available in the \code{tftp-hpa} package,
      for testing
    \end{itemize}
  \item A TFTP client is integrated into U-Boot
    \begin{itemize}
    \item Configure the \code{ipaddr} and \code{serverip} environment
      variables
    \item Use \code{tftp <address> <filename>} to load a file
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{U-boot mkimage}
  \begin{itemize}
  \item The kernel image that U-Boot loads and boots must be prepared,
    so that a U-Boot specific header is added in front of the image
    \begin{itemize}
    \item This header gives details such as the image size, the
      expected load address, the compression type, etc.
    \end{itemize}
  \item This is done with a tool that comes in U-Boot, \code{mkimage}
  \item Debian / Ubuntu: just install the \code{u-boot-tools} package.
  \item Or, compile it by yourself: simply configure U-Boot for any
    board of any architecture and compile it. Then install \code{mkimage}:\\
    \code{cp tools/mkimage /usr/local/bin/}
  \item The special target \code{uImage} of the kernel Makefile can
    then be used to generate a kernel image suitable for U-Boot.
\end{itemize}
\end{frame}
