\documentclass[twoside,a4paper]{article}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{booktabs}
\usepackage{enumitem}
\usepackage{fancyhdr}
\usepackage{float}
\usepackage{fontspec}
\usepackage{hyperref}
\usepackage[margin=2cm,includefoot,footskip=1.5cm]{geometry}
\usepackage{graphicx}
\usepackage{minted}
\usepackage{tikz}
\usepackage{url}

\usetikzlibrary{calc, shapes.misc}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}

%\setmainfont[BoldFont=OpenSans-Bold, ItalicFont=OpenSans-Italic, Ligatures=TeX]{OpenSans-Regular.ttf}
%\setsansfont[BoldFont=OpenSans-Bold, ItalicFont=OpenSans-Italic, Ligatures=TeX]{OpenSans-Regular.ttf}

\newfontfamily\Roboto[BoldFont=Roboto-Bold, Ligatures=TeX]{Roboto-Regular.ttf}
\setmainfont[BoldFont=Roboto-Bold, ItalicFont=Roboto-Italic, Ligatures=TeX]{Roboto-Regular.ttf}
\setsansfont[BoldFont=Roboto-Bold, ItalicFont=Roboto-Italic, Ligatures=TeX]{Roboto-Regular.ttf}

\definecolor{background}{RGB}{58,46,86}
\definecolor{border}{RGB}{234,211,186}

\patchcmd{\section}{\thispagestyle{plain}}{\thispagestyle{fancy}}{}{}

\pagestyle{fancy}
\fancyhf{}
\fancyhead[C]{%
\begin{tikzpicture}[overlay, remember picture]%
    \fill[border] (current page.north west) rectangle ($(current page.north east)+(0,-1.5cm)$);
    \fill[background] (current page.north west) rectangle ($(current page.north east)+(0,-1.4cm)$);
    \node[anchor=north west, text=white, font=\Large\Roboto, minimum size=1.4cm, inner xsep=5mm] at (current page.north west) {\textbf{white}box};
\end{tikzpicture}
}
\fancyfoot[LE,RO]{\thepage}

\newcommand\fancytitlecover {
	\begin{tikzpicture}[remember picture, overlay, shorten >= -10pt]
    \fill[border] (current page.north west) rectangle (current page.south east);
    \fill[background] (current page.north west) rectangle ($(current page.south east)+(0,3mm)$);
	\end{tikzpicture}
}

\makeatletter
\renewcommand*{\maketitle}{
	\begin{titlepage}
	\fancytitlecover
	\color{white}
	\begin{center}
	\sffamily
	\vspace*{3cm}
	\huge \@title \\[1em]
	{\Large\Roboto \textbf{white}box}
	\vfill
	%\large \@author \\[1em]
	%\large \@date
	\end{center}
	\end{titlepage}
}
\makeatother

\makeatletter
\global\let\tikz@ensure@dollar@catcode=\relax
\makeatother

\begin{document}

\title{Trusted Boot Module \\[.5em]
\Large User Manual}
\author{}
\date{}
\maketitle

\tableofcontents
\newpage

\section{Introduction}

\section{Building ROTS}

\subsection{u-boot}

At the moment of writing, the mainline version of u-boot does not have support for SPI NOR flash on Allwinner SoCs such as the Allwinner A10, A20 and the A64.
A driver model compatible SPI driver for u-boot is has been worked on and the code can be found at \url{https://github.com/StephanvanSchaik/u-boot/tree/sunxi-spi}.
This driver has been tested on the following boards:

\begin{itemize}[noitemsep]
\item H2+ Orange Pi Zero with Macronix MX25L1605D 16 Mbit
\item A20 OLinuXino LIME 2 with Winbond W25Q128BV 128 Mbit
\item A64 Pine64+ with Winbond W25Q128BV 128 Mbit
\item A64 OLinuXino with Eon EN25Q64 64 Mbit
\end{itemize}

To compile u-boot with support for SPI NOR flash:

\begin{minted}[breaklines]{text}
git clone https://github.com/StephanvanSchaik/u-boot -b sunxi-spi
make clean
make A20-OLinuXino-Lime2_defconfig
CROSS_COMPILE=armv7a-hardfloat-linux-gnueabi- make
\end{minted}

After u-boot-sunxi-with-spl.bin has been built, we can put it on an SD card as follows to test it:

\begin{minted}[breaklines]{text}
dd if=u-boot-sunxi-with-spl.bin of=/dev/sda bs=1024 seek=8
\end{minted}

While U-boot also supports booting from SPI NOR flash, it has been disabled by default:

\begin{minted}[breaklines]{text}
make menuconfig
\end{minted}

Enable the CONFIG\_SPL\_SPI\_SUNXI option.
It is possible that the resulting binary will be too large.
In that case, an option like CONFIG\_SPL\_MMC\_SUPPORT can be disabled to save some space.
After the configuration options have been set up, rebuild the u-boot binary again.

\section{Flashing ROTS}

\subsection{Using an External Programmer}

In order to be able to program the SPI NOR flash with an external programmer, we will need an external programmer such as the BusPirate v3.6a or the BusPirate v4.0 and SOIC clip.
Figure~\ref{fig:winbond-pinout} illustrates the pin-out of a Winbond W25Q128.V SPI NOR flash, but any SPI NOR flash chip should be compatible with this pin-out.
The SPI NOR flash should have a circular shape at one of the corners, this corner should be bottom-right corner.
Once the pins of the SPI NOR flash are aligned with the pin-out in figure~\ref{fig:winbond-pinout}, we can clip the SPI NOR flash chip between the SOIC clip.

\begin{figure}[H]
\centering
\begin{tikzpicture}
% Draw the chip.
\node[draw=black,chamfered rectangle,align=center,fill=gray!10,minimum width=3.5cm,minimum height=3cm] (chip) {Winbond \\ W25Q128.V};
\node[draw=black,fill=gray!30,circle] at ($(chip.south west) + (.3,.3)$) {};

% Draw the pin-out at the bottom.
\path[draw] ($(chip.south)+(-1.2,0)$) -- ($(chip.south)+(-1.2,-.5)$) node[below] {CS};
\path[draw] ($(chip.south)+(-.4,0)$) -- ($(chip.south)+(-.4,-.5)$) node[below] {DO};
\path[draw] ($(chip.south)+(.4,0)$) -- ($(chip.south)+(.4,-.5)$) node[below] {\textbackslash WP};
\path[draw] ($(chip.south)+(1.2,0)$) -- ($(chip.south)+(1.2,-.5)$) node[below] {GND};

% Draw the pin-out at the top.
\path[draw] ($(chip.north)+(-1.2,0)$) -- ($(chip.north)+(-1.2,.5)$) node[above] {VCC};
\path[draw] ($(chip.north)+(-.4,0)$) -- ($(chip.north)+(-.4,.5)$) node[above] {H/R};
\path[draw] ($(chip.north)+(.4,0)$) -- ($(chip.north)+(.4,.5)$) node[above] {CLK};
\path[draw] ($(chip.north)+(1.2,0)$) -- ($(chip.north)+(1.2,.5)$) node[above] {DI};
\end{tikzpicture}
\caption{the pin-out of the Winbond W25Q128.V SPI NOR flash}
\label{fig:winbond-pinout}
\end{figure}

Figure~\ref{fig:bp36-connect} shows how to connect the BusPirate v3.6a with the SPI NOR flash chip.
Connect the \emph{Chip Select} (CS) pins using the white cable, the \emph{Master In Slave Out} (MISO) pin with the \emph{Data Out} (DO) pin using the black cable, the \emph{Master Out Slave In} (MOSI) pin with the \emph{Data In} (DI) pin using the grey cable and the \emph{Clock} (CLK) pins using the purple cable.
Further, the \emph{Ground} (GND) pins should be connected using the brown cable and the 5V and the VCC pins should be connected with the orange cable.
In order for the SPI NOR flash chip to function, the H/R pin of the SPI NOR flash chip should be pulled high, this can be done by connecting the 5V pin with the H/R pin.
Finally, to be able to program the chip in case write-protection has been configured before, we have to make sure that the \emph{Write-Protect} (WP) is pulled high to disable write-protection.

\begin{figure}[H]
\centering
\begin{tikzpicture}
% Draw the chip.
\node[draw=black,chamfered rectangle,align=center,fill=gray!10,minimum width=3.5cm,minimum height=3cm] (chip) {Winbond \\ W25Q128.V};
\node[draw=black,fill=gray!30,circle] at ($(chip.south west) + (.3,.3)$) {};

% Draw the pin-out at the bottom.
\path[line width=1.5mm,draw=black] ($(chip.south)+(-1.2,0)$) -- ($(chip.south)+(-1.2,-.7)$);
\path[line width=1.2mm,draw=white] ($(chip.south)+(-1.2,0)$) -- ($(chip.south)+(-1.2,-.7)$) node[below] {CS};
\path[line width=1.5mm,draw=black] ($(chip.south)+(-.4,0)$) -- ($(chip.south)+(-.4,-.7)$);
\path[line width=1.2mm,draw=black] ($(chip.south)+(-.4,0)$) -- ($(chip.south)+(-.4,-.7)$) node[below] {MISO};
\path[line width=1.5mm,draw=black] ($(chip.south)+(.4,0)$) -- ($(chip.south)+(.4,-.7)$);
\path[line width=1.2mm,draw=orange] ($(chip.south)+(.4,0)$) -- ($(chip.south)+(.4,-.7)$) node[below] {\textbackslash WP};
\path[line width=1.5mm,draw=black] ($(chip.south)+(1.2,0)$) -- ($(chip.south)+(1.2,-.7)$);
\path[line width=1.2mm,draw=brown] ($(chip.south)+(1.2,0)$) -- ($(chip.south)+(1.2,-.7)$) node[below] {GND};

% Draw the pin-out at the top.
\path[line width=1.5mm,draw=black] ($(chip.north)+(-1.2,0)$) -- ($(chip.north)+(-1.2,.7)$);
\path[line width=1.2mm,draw=orange] ($(chip.north)+(-1.2,0)$) -- ($(chip.north)+(-1.2,.7)$) node[above] {VCC};
\path[line width=1.5mm,draw=black] ($(chip.north)+(-.4,0)$) -- ($(chip.north)+(-.4,.7)$);
\path[line width=1.2mm,draw=orange] ($(chip.north)+(-.4,0)$) -- ($(chip.north)+(-.4,.7)$) node[above] {H/R};
\path[line width=1.5mm,draw=black] ($(chip.north)+(.4,0)$) -- ($(chip.north)+(.4,.7)$);
\path[line width=1.2mm,draw=purple] ($(chip.north)+(.4,0)$) -- ($(chip.north)+(.4,.7)$) node[above] {CLK};
\path[line width=1.5mm,draw=black] ($(chip.north)+(1.2,0)$) -- ($(chip.north)+(1.2,.7)$);
\path[line width=1.2mm,draw=gray] ($(chip.north)+(1.2,0)$) -- ($(chip.north)+(1.2,.7)$) node[above] {MOSI};
\end{tikzpicture}
\caption{connecting the BusPirate v3.6a with the SPI NOR Flash}
\label{fig:bp36-connect}
\end{figure}

Because the configuration of write-protection is vendor-specific, the mainline version of \emph{flashrom} does not support configuring write-protection.
Therefore, to be able to configure the write-protection of the SPI NOR flash chip, we have to use Google's fork of \emph{flashrom}.

Unlike the mainline version of flashrom, Google's fork has two flags to get the name and the
size of the Flash chip:

\begin{minted}[breaklines]{text}
./flashrom --programmer=buspirate_spi:dev=/dev/buspirate --flash-name
flashrom v0.9.4  : bc6cab1 : Oct 30 2014 07:32:01 UTC on Linux 4.9.4-gentoo (x86_64), built with libpci 3.1.10, GCC 4.8.x-google 20140307 (prerelease), little endian
vendor="Macronix" name="MX25L6406E"
./flashrom --programmer=buspirate_spi:dev=/dev/buspirate --get-size
flashrom v0.9.4  : bc6cab1 : Oct 30 2014 07:32:01 UTC on Linux 4.9.4-gentoo (x86_64), built with libpci 3.1.10, GCC 4.8.x-google 20140307 (prerelease), little endian
8388608
\end{minted}

Further, Google's fork of flashrom allows us to tag regions on the SPI NOR flash chip with a custom name.
Assuming that the SPI NOR flash chip is 8 MiB, that the u-boot image is 512 kiB and that the Linux image is 3.5 MiB, we will be using the following \path{layout.txt} file for the ROTS:

\begin{minted}[breaklines]{text}
000000:07ffff uboot
080000:3fffff linux
400000:7fffff initramfs
\end{minted}

We can then write \path{u-boot.bin}, \path{bzImage} and \path{initramfs.cpio.gz} to the SPI NOR flash chip by using the respective names of the regions.
To speed up the process of writing these images, we have to disable parsing the fmap and the verification of unmodified regions.
Furthermore, to maintain an optimal stability, an SPI speed of no more than 2 MHz is recommended when using the BusPirate v3.6a:

\begin{minted}[breaklines]{text}
./flashrom --programmer=buspirate_spi:spispeed=2M,dev=/dev/buspirate -l layout.txt -i uboot:u-boot.bin linux:bzImage initramfs:initramfs.cpio.gz -w --ignore-fmap --fast-verify
\end{minted}

Now that the images have been written to their respective regions, we can look at the write-protect ranges supported by the chip:

\begin{minted}[breaklines]{text}
./flashrom --programmer=buspirate_spi:dev=/dev/buspirate --wp-list
flashrom v0.9.4  : bc6cab1 : Oct 30 2014 07:32:01 UTC on Linux 4.9.4-gentoo (x86_64), built with libpci 3.1.10, GCC 4.8.x-google 20140307 (prerelease), little endian
Valid write protection ranges:
start: 0x000000, length: 0x000000
start: 0x7e0000, length: 0x020000
start: 0x7c0000, length: 0x040000
start: 0x7a0000, length: 0x080000
start: 0x700000, length: 0x100000
start: 0x600000, length: 0x200000
start: 0x400000, length: 0x400000
start: 0x000000, length: 0x800000
start: 0x000000, length: 0x800000
start: 0x000000, length: 0x400000
start: 0x000000, length: 0x600000
start: 0x000000, length: 0x700000
start: 0x000000, length: 0x780000
start: 0x000000, length: 0x7c0000
start: 0x000000, length: 0x7e0000
start: 0x000000, length: 0x800000
\end{minted}

Since we don't want our images to be tampered with, we want to enable write-protection for the full range.
We can configure the write-protected range as follows:

\begin{minted}[breaklines]{text}
./flashrom --programmer=buspirate_spi:spispeed=2M,dev=/dev/buspirate --wp-range 0x000000 0x800000
\end{minted}

After setting the range, we are still able to modify the contents of the entire SPI NOR flash chip.
To protect the range, we have to enable write protection as follows:

\begin{minted}[breaklines]{text}
./flashrom --programmer=buspirate_spi:spispeed=2M,dev=/dev/buspirate --wp-enable
\end{minted}

Upon enabling write-protection, the \emph{Write-Protect} (WP) pin has to be pulled low for the write-protection to be effective.
This prevents the user from disabling the write-protection feature, changing the write-protect range and from writing to the write-protected region.

\subsection{Using sunxi-fel}

Download and compile the \emph{sunxi-fel} tool as follows:

\begin{minted}[breaklines]{text}
git clone -b spiflash-a20-test https://github.com/ssvb/sunxi-tools.git
make
\end{minted}

Connect or reset while holding the recovery or FEL button.
Once the board has booted into FEL mode, we can detect the SPI NOR flash chip as follows:

\begin{minted}[breaklines]{text}
./sunxi-fel spiflash-info
Manufacturer: Winbond (EFh), model: 40h, size: 16777216 bytes.
\end{minted}

Then we can write the \path{u-boot.bin}, \path{bzImage} and \path{initramfs.cpio.gz} images as follows:

\begin{minted}[breaklines]{text}
./sunxi-fel -p spiflash-write 0x000000 u-boot.bin
./sunxi-fel -p spiflash-write 0x080000 bzImage
./sunxi-fel -p spiflash-write 0x400000 initramfs.cpio.gz
\end{minted}

\section{Booting ROTS}

After powering up the board, \emph{u-boot} will be loaded.
\emph{u-boot} will then load the Linux kernel image and the initramfs from the SPI NOR flash and boot the Linux kernel with the initramfs as follows:

\begin{minted}[breaklines]{text}
sf probe 0:0 6000000
sf read 42000000 80000 380000
sf read 43000000 400000 400000
bootm 0x42000000 0x43000000
\end{minted}

The ROTS kernel will now boot up and mount the initramfs as the rootfs.
At some point the kernel will run the init script in the initramfs.
When this happens the ROTS will start communicating with the TBM to fetch the time as well as the certificates.
Once these have been retrieved from the TBM, the ROTS will mount the external media such as hard disks and enumerate and verify possible boot images on those media.


\end{document}
