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
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.
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.
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
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
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:
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:
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:
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.