BORA SOM/BELK-L/pdf

From DAVE Developer's Wiki
Jump to: navigation, search


History[edit | edit source]

BELK History
Version Issue Date Notes
4.1.5 Sep 2021 Full support for BORA SOM


General Information[edit | edit source]

Release Notes[edit | edit source]

DAVE Embedded Systems adds to the latest Linux BSP from Xilinx the customization required to support the SOC platform. For this reason most of the documentation provided by Xilinx remains valid for the BELK development kit.

However, some customization is required, in particular at bootloader and linux kernel levels.

The following table reports the BELK releases information.

BELK version
Release number 4.1.5
Release type Minor (base on BELK 4.0.0 major release)
Status Released
Release date Sep 2021
Release notes Ver 4.1.5
Product support BORA
MVM (distro version) Ubuntu 14.04
U-Boot version 2017.01-belk-4.1.5
Linux version 4.9.0-bora-4.1.4
Drivers

SPI NOR Flash (boot)
UART debug (2-wire)
USB OTG
SD/MMC
CAN

Ethernet0 gigabit
NAND
RTC
I2C
ConfigID

Vivado version 2017.1
Build System Yocto Morty (2.2)

BELK 4.1.5[edit | edit source]

200px-Emblem-important.svg.png

New MVM must be installed for using BELK-4.1.0. The VM is available for download on DAVE's BORA Reserved Area for registered users.

Release notes:

  • Updated u-boot version for BORA Lite support (updated defconfig for NOR and SD boot)

Known Limitations[edit | edit source]

The following table reports the known limitations of this BELK release:

ID Component Subsystem Description
0001 BoraEVB External DDR3 bank (BoraEVB only) DDR3 bank can be populated on request. For more details please refer to Sales Department.
0002 BoraEVB ETH1 interface Please refer to this application note for second Ethernet interface support.
0003 BoraEVB RTC Date/time retention is limited to about 4 hours.
0004 BoraEVB System clock runs slower As per Xilinx issue, @333MHz (speedgrade -3) system clock is slower then expected

Downloadable binary images[edit | edit source]

All binary images for BELK are hosted on DAVE Embedded System mirror server. There you can find a sub directory for each version of this development kit.

U-boot performs 2-stage bootloader providing two files: boot.bin and u-boot.img. Both two files must be stored into SD card using dd command.


A summary of images with a brief description can be found into the table below:

Image BELK version 4.1.5
Platform BORAEVB
bootscript boot.scr
FPGA
Vivado example
fpga.bit
SPL boot.bin
u-boot u-boot.img
Linux kernel uImage
Device tree bora.dtb

Release types[edit | edit source]

BELK release type can be:

  • Major, when substantial changes are applied to the BSP (eg: major kernel version upgrades) or to the development kit (eg: new features, build system updates, ..). This usually means that a new DVDK is created for the BELK release
  • Maintenance, when minor updates and bug fixes are introduced. This usually means that the DVDK remains the same provided with the previous major version, and only an update of the source tree repositories (and the tftp binaries) is required

As an example, BELK 4.1.0 is a maintenance release, so it provides the DVDK released with the 4.0.0 major release; customers can easily upgrade to the 4.1.0 release by updating the software components as described in Synchronizing git repositories.



Virtual Machine[edit | edit source]

BELK-L contains all the required software and documentation to start developing Linux application on the BORA platform. In particular, BELK-L-S provides a virtual machine, called DVDK, with the following features:

  • VirtualBox virtual machine (.OVA archive)
  • based on Lubuntu 16.04 LTS (64-bit version)
  • pre-installed VirtualBox Guest Additions
  • LXDE desktop environment
  • boot disk with the distro and pre-configured basic Linux services:
    • TFTP: with base directory /srv/tftp/
    • NFS: configured through the /etc/exports file
  • secondary disk containing source code and tools:
    • bootloader (u-boot) source tree cloned from DAVE Embedded Systems public git repository
    • Linux kernel source tree cloned from DAVE Embedded Systems public git repository
    • external pre-built toolchain
    • Yocto BSP for BORA, BORA Lite and BORA Xpress SOMs
  • pre-installed Yocto-based root file systems with setup scripts, makefiles, example applications, ...
  • administrator account (dvdk) with autologin. Please note that the user account credentials are provided with the development kit (you can find them in the README file contained in the sw/dvdk folder of the kit distribution)
    • user: dvdk
    • password: dvdk

Please note that u-boot and kernel source trees are derived from the official trees released by Xilinx; these trees have been customized to add support for the BORA, BORA Lite and BORA Xpress SOMs

Host setup[edit | edit source]

As stated previously, host tools are based on a Managed Virtual Machine. As indicated here, microSD card delivered along with BORA Evaluation Kit includes basic version of MVM that is the default option.

Please follows the README file on the SD card to extract the *.ova archive and to install the MVM.

It is also worth remembering that access to git repositories is required to download target source code. To enable it, please refer to this page.

MVM can be downloaded here. For accessing BELK Reserved area please contact our helpdesk support channel

To install it, please refer to this page.



ConfigID management[edit | edit source]

ConfigID is a new feature of DAVE Embedded Systems products. It's main purpose is providing an automatic mechanism for the identification of the product model and configuration.

General information about ConfigID are provided here. The following sections details some Bora/BoraX specific information.

ConfigID hardware implementation on Bora/BoraX/BoraLite[edit | edit source]

BORA uses the first 32bytes OTP block on NOR SPI to store ConfigID (and its CRC32), UniqueID (and its CRC32)

ConfigID on BoraLite[edit | edit source]

For BORA Lite module configured for booting from NAND, the ConfigID is stored on internal I2C EPROM: see here for more information.

ConfigID software implementation on Bora/BoraX/BoraLite[edit | edit source]

U-Boot integrates the software routines for reading and displaying the ConfigID. Hereunder an example of SOM ConfigID at startup:

U-Boot 2014.07 (Jul 24 2015 - 14:30:55) [belk-2.2.0]

Board:  BORA
I2C:   ready
DRAM:  ECC disabled 1 GiB
NAND:  1024 MiB
MMC:   zynq_sdhci: 0
SF: Detected S25FL256S_64K with page size 256 Bytes, erase size 64 KiB, total 32 MiB
In:    serial
Out:   serial
Err:   serial
SOM ConfigID#: 00000002
SOM UniqueID#: fffffefc:fffffefc
CB ConfigID#: 00000001
CB UniqueID#: a600000f:24188b2d
Net:   Gem.e000b000
zynq-uboot>

For accesing these information on Linux procfs, the device tree must be modified (using u-boot fdt command). For example:

zynq-uboot> print loadfdt configid_fixupfdt
loadfdt=tftpboot ${fdtaddr} ${fdtfile}
configid_fixupfdt=if configid checkfdt ${fdtaddr} som_configid ${som_configid#}; then if configid checkfdt ${fdtaddr} cb_configid ${cb_configid#}; then configid fdt_uniqueid ${fdtaddr}; fi; fi

zynq-uboot> run loadfdt configid_fixupfdt
Gem.e000b000 Waiting for PHY auto negotiation to complete....... done
Using Gem.e000b000 device
TFTP from server 192.168.0.13; our IP address is 192.168.0.77
Filename 'bora/bora.dtb.as'.
Load address: 0x2000000
Loading: T ##
         1000 Bytes/s
done
Bytes transferred = 10019 (2723 hex)
FDT: property som_configid FDT: override 'som_configid' with '00000002'
FDT: property cb_configid match
FDT: override 'som_uniqueid' with 'fffffefc:fffffefc'
FDT: override 'cb_uniqueid' with 'a600000f:24188b2d'

It is possible to read the ConfigID/UniqueID via procfs. For example:

root@bora:~# for f in  /proc/device-tree/*id*; do echo -n "$f: "; cat $f; echo; done
/proc/device-tree/cb_configid: 00000001
/proc/device-tree/cb_uniqueid: a600000f:24188b2d
/proc/device-tree/som_configid: 00000002
/proc/device-tree/som_uniqueid: fffffefc:fffffefc
df646299:0b0579d4
root@axel-lite:~#



Logical structure of BELK[edit | edit source]

BELK starting from version 4.0.0 / BXELK starting from version 2.0.0[edit | edit source]

These kits introduce some significant differences with respect to the previous versions. The characterizing items are:

  • FSBL is no longer used as the first-stage bootloader. It is replaced by U-Boot SPL.
  • Yocto build system is fully integrated into the kit and it is used to build all the software running on the target. Consequently, the Vivado SDK tool chain is no longer used.
  • To simplify the installation of host-side tools, a Managed Virtual Machine (MVM) is provided, containing all the required tools.


The typical Linux-based Zynq design is composed of the following parts:

  • U-boot SPL (first-stage bootloader)
  • U-Boot (second-stage bootloader)
  • device tree file
  • Linux kernel
  • Root file system
  • Executable image of core #1 (in case of AMP systems)
  • FPGA bitstream.

Generally speaking, these parts (in the binary/synthesized form) are combined together in one monolithic file that is stored in a non-volatile memory such as SPI NOR flash. Generating this file is quite easy as described by Vivado documentation. However, in real world products, this may be too rigid because developers may want to handle these parts separately and independently. Thanks to the use of U-Boot dual stage bootloader, these binary files can be handled separately and independently instead of a unique monolithic file. U-boot SPL bootloader is responsible to correctly initialize the PS (Processing System) based on configurations from the Vivado project.

The role of Vivado[edit | edit source]

U-Boot SPL is based on one file (ps7_init.c) that is generated by Vivado. In turn, this file contains some initialization parameters that are set according to Zynq configuration.

The U-Boot sources provided by the BELK/BXELK include such file. Unless you need to modify the initial Zynq configuration, you don't need to generate a new ps7_init.c file. Therefore, from the standpoint of the software running on PS, the role of Vivado is limited to the generation of such file.

The role of Yocto[edit | edit source]

From the point of view of PS software, the role of Yocto build system is crucial. As shown in the following image, in fact, it is used to build:

  • U-Boot SPL (first-stage bootloader)
  • U-Boot (second-stage bootloader)
  • Linux kernel
  • Device tree
  • root file system
  • user applications.
Simplified flow of Yocto-based building process

The image shows the simplified flow of the Yocto-based building process. The modules within the dashed line are included in the Managed Virtual Machine (MVM) delivered along with the kit.

The binary images distributed with the kit are generated by this process.

200px-Emblem-important.svg.png

Please note that the whole build process requires a lot of hardware resources in terms of disk storage, RAM, and processing power. For this reason, it is discouraged to use the MVM to perform such build.

BELK from version 2.1.0 to version 3.0.2 / BXELK from version 1.0.0 to version 1.0.1[edit | edit source]

The structure of these kits is the same of the previous releases of BELK. In addition to those, a pre-built root file system image is provided. This image is generated by Yocto.

BELK up to version 2.0.0[edit | edit source]

These kits are characterized by the following items:

  • All the software running on the PS is built with the tool chain of the Vivado SDK
  • FSBL is used as the first-stage bootloader
  • no pre-built root file system images are provided.

To understand the structure of BELK, it is necessary to describe the basic organization of Xilinx Vivado Design Suite/Xilinx SDK and to recall briefly the recent history of development tools provided by Xilinx.

A little bit of history[edit | edit source]

At the time of this writing (October 2013) Xilinx is migrating from mature ISE 14.x Design Suite - that should be the last series of this suite - to the new Vivado environment. Both are composed by several programs and some of these are in common. From the general standpoint, the main difference between ISE and Vivado - even if ISE does support Zynq - is that the latter has been expressively conceived to support newer SoC architectures such as Zynq, besides traditional FPGAs. Thus, adopting Vivado as the default environment for BELK/BXELK would seem the natural choice. However, the migration process mentioned above has just begun and the majority of application notes and reference designs released by Xilinx still refers to ISE suite. Plus Vivado is still a little bit "green" and several bug fixes and improvements are introduced by every new release.

Since Bora was presented in 2013 and because this product addresses long longevity markets such as industrial and biomedical, DAVE Embedded Systems chose to build BELK/BXELK upon Vivado that undoubtedly represents today the future of Xilinx development environments.

Structure of BELK/BXELK reference designs[edit | edit source]

The typical Linux-based Zynq design is composed of the following parts:

  • FSBL
  • U-Boot
  • device tree file
  • Linux kernel
  • Root file system
  • Executable image of core #1 (in case of AMP systems)
  • FPGA bitstream.

Generally speaking, these parts - in the binary/synthesized form - are combined together in one monolithic file that is stored in a non-volatile memory such as SPI NOR flash. Generating this file is quite easy as described by Vivado documentation. However, in real world products, this may be too rigid because developers may want to handle these parts separately and independently.

Basic structure of Vivado Design Suite and integration into BELK[edit | edit source]

Vivado/SDK [1] can be viewed as a collection of programs required to deal with all of the development aspects related to Xilinx components (software running on ARM cores, FPGA fabric verification and programming, power estimation etc.). These include strictly FPGA-related tools such as Floorplanner and pure-software development tools such as SDK. The ambitious objective is to provide a complete, user-friendly, integrated environment that allows software developers to deal with FPGA development even if they are not familiar with this technology, by hiding a lot of its complexities [2]. As usual this ease of use comes at the expense of control and flexibility. This could not be acceptable in many cases where engineers need to control and customize many aspects of the project to implement what is required by system specifications. For this reason, BELK and BXELK have been built around Vivado but some deviations from the default development approach suggested by Xilinx have been introduced, in order to push the modularization and the maintainability of the projects to the maximum possible extent.

The following pictures show respectively the Vivado/SDK default development flow and how this has been integrated into the BELK infrastructure.

Vivado/SDK development flow (BELK <= 3.0.2 and BXELK <= 1.0.1)
Vivado/SDK integration into BELK/BXELK


[1] The Software Development Kit (SDK) is the Xilinx Integrated Design Environment for creating embedded applications on Zynq™-7000 All Programmable SoCs. SDK is the first application IDE to deliver true homogenous and heterogenous multi-processor design and debug, it is optionally included with the Vivado Design Suite or ISE Design Suite, or available as a separate free download for application developers.

[2] Nevertheless FPGA developers will find all the traditional tools that allow complete control of FPGA fabric.



Booting the system via NFS[edit | edit source]

It is assumed that the development environment has been set up properly as described here.

Assuming that:

  • the CPU module is booting with a working FSBL (or U-boot SPL for BELK-4.0.0/BXELK-2.0.0) and U-Boot image (either from flash NOR SPI or flash NAND or MicroSD card)
  • a kernel image is available and ready to be downloaded through tftp
  • the root file system has been uncompressed into a nfs share

the system can boot using the net_nfs[a] configuration, as described here.

  1. The net_nfs configuration, besides setting the system for booting from the network, triggers a command (program_fpga) which loads the FPGA binary from TFTP and programs the bitstream.



Development[edit | edit source]

Host setup and development flow[edit | edit source]

The software development environment for Processing Subsystem (PS) is quite complex because it is based on several tools. This document collects the resources, available in this wiki, which are related to these tools, in order to illustrate how to install and set up them.

First, it is strongly recommended the reading of this document to understand the general structure of the kit.

For setting up the development environment, please refer to the following documents:

To deepen target software-related aspects, these specific pages are available:

  • This page for detailed instruction on U-Boot building
  • This page for detailed instruction on Linux kernel building
  • This link shows hot to use Yocto build system to build the entire BSP, including U-Boot bootloader, Linux kernel and root file system.

About Programmable Logic (PL), please refer to this page that illustrates a simple reference design for BORA Evaluation kit and BORA Xpress Evaluation kit.



Introduction to development environment[edit | edit source]

The following pictures show a simplified scheme of the the development environment for an Embedded Linux system based on BORA or BORAX. The two main blocks are a host machine and a target machine.

BORA/BORAX development environment (BELK 4.0.0 or newer, BXELK 2.0.0 or newer)
BORA/BORAX development environment (BELK version up to 3.0.2, BXELK version up to 1.0.1)


In a typical environment, the host is used by the developer to (cross-)compile the code that is to run on the target. In our case, the target is a SOM, while the host is assumed to be a PC running the Linux operating system, either in a physical installation or as a virtual machine (for recent kits, this is the MVM).

The bootloader running on the target can download the Linux kernel image through the network (TFTP), as well as the bootloader binary images (useful when an update of the bootloader is required).

Moreover, the Linux kernel running on the target is able to mount the root file system from different physical media, for example from a directory exported via Network File System (NFS) by the host. This strategy (kernel image and RFS retrieved from the network) saves time during the development phase since no flash reprogramming or removable storage (SD, USB pen drives, external disks) is required to test new versions or updates of the software components.

In contrast with a typical embedded system, BORA/BORAX adds some complexity, due to the nature of the Zynq processor, which provides both a CPU core (aka PS, Processing System) and an integrated FPGA (aka PL, Programmable Logic). This means that additional tools are required to manage this complexity.

In particular

  • The Vivado® Design Suite is required for the generation of the PL bitstream
  • The Xilinx Software Development Kit (SDK) is required for building the first stage boot loader (FSBL) (BELK version up to 3.0.2, BXELK version up to 1.0.1)

Starting from BELK 4.0.0 and BXELK 2.0.0 U-boot SPL bootloader is used instead of FSBL, therefore Xilinx SDK is no longer required.

Software components[edit | edit source]

Xilinx Zynq-7000 development tools[edit | edit source]

Vivado® Design Suite[edit | edit source]

Xilinx provides the Vivado® Design Suite, a SoC-strength, IP-centric and system-centric, next generation comprehensive development environment for All Programmable SoCs. The Vivado® Design Suite is used to configure the PS for embedded processor hardware system development. Specification of the microprocessor, memory parameters, boot peripherals, MIO settings and the interconnection of these components, along with their respective detailed configuration, takes place in Vivado IP Integrator.

For any version of BELK/BXELK, Vivado is required to generate the PL bitstream.

Xilinx Software Development Kit[edit | edit source]

The Software Development Kit (SDK) is the Xilinx Integrated Design Environment for creating embedded applications on Zynq™-7000 All Programmable SoCs. SDK is the first application IDE to deliver true homogeneous and heterogeneous multi-processor design and debug, it is optionally included with the Vivado Design Suite or ISE Design Suite, or available as a separate free download for application developers. It is based on Eclipse and CDT and it directly interfaces to the Vivado embedded hardware design environment. The SDK offers support for complete software design and debug flows including multiprocessor and hardware/software debug capabilities, integrating editor, compilers, build tools, flash memory management, JTAG/GDB debug, custom libraries and device drivers.

As described here, in the context of BELK/BXELK, the SDK is no longer required for the version of BELK starting from 4.0.0 and for the version of BXELK starting from 2.0.0.

Toolchain[edit | edit source]

With the term toolchain we refer to the set of programs that allow the building of a generic application. For applications built to run on the same platform as the tool chain, we use a native toolchain. On the contrary, for applications built to run on a target architecture different from the host architecture, we use a cross-toolchain. In this case, all the tools involved in this process are lead by the “cross-” prefix. So we talk about cross-compiler, cross-toolchain and so on. The cross-toolchain used to build U-Boot, the Linux kernel and the applications is the GNU toolchain for the ARM architecture built for x86 hosts. In other words, the toolchain runs on x86 machines but generates binaries for ARM processors. As for all the software compliant to the GPL license, it is released in source code. Thus the first thing to do to set up the developing environment should be building the cross-toolchain. This is not a trivial task, it takes a lot of time and hard disk space. To avoid this tedious task, we suggest using a pre-built toolchain as explained in the following sections.

First-stage bootloader[edit | edit source]

Two different first-stage bootloaders are used, depending on the version of the kit.

U-Boot SPL (BELK 4.0.0 or newer, BXELK 2.0.0 or newer)[edit | edit source]

These kits use U-Boot SPL as first-stage bootloader. It is loaded by the internal bootrom during the boot process. U-Boot SPL is run to set up the PS and load the second stage bootloader (U-Boot).

U-Boot SPL is built with the same tool chain used to build the the other software modules, such as the Linux kernel and the applications.

Please note that U-Boot SPL is based on one file (ps7_init.c) that is generated by Vivado. In turn, this file contains some initialization parameters that are set according to Zynq configuration. The U-Boot sources provided by the BELK/BXELK include such file. Unless you need to modify the initial Zynq configuration, you don't need to generate a new ps7_init.c file. Therefore, from the standpoint of the software running on PS, Vivado is genrally not required.

FSBL (BELK version up to 3.0.2, BXELK version up to 1.0.1)[edit | edit source]

The first stage bootloader is loaded by the internal bootrom during the boot process. FSBL is run to set up the PS and load the second stage bootloader (U-Boot). The FSBL must be created using the Xilinx development tools and must be stored into the boot memory.

Second stage bootloader: U-Boot[edit | edit source]

U-Boot is a very powerful boot loader and it became the "de facto" standard on non-x86 embedded platforms. The main tasks performed by U-Boot are:

  • hardware initialization
  • starting a shell on the serial port allowing the user to interact with the system through the provided commands
  • automatic execution of the boot script (if any)

After system power-up, U-Boot prints some information about itself and about the system it is running on. Once the bootstrap sequence is completed, the prompt is printed and U-Boot is ready to accept user's commands. U-Boot manages an environment space where several variables can be stored. These variables are extremely useful to permanently save system settings (such as ethernet MAC address) and to automate boot procedures. This environment is redundantly stored in two physical sectors of boot flash memory; the default variables set is hard-coded in the source code itself. User can modify these variables and add new ones in order to create his/her own custom set of configurations. The commands used to do that are setenv and saveenv. This process allows the user to easily set up the required configuration. Once U-Boot prompt is available, it is possible to print the whole environment by issuing the command printenv. For further information on the use of U-Boot, please refer to http://www.denx.de/wiki/view/DULG/UBoot.

Kernel[edit | edit source]

Linux kernel for Zynq processors is maintained primarily by Xilinx, that constantly works in close cooperation with Linux community in order to push all the released drivers into the mainline kernel. Kernels released within BELK derive directly from Xilinx Zynq kernels, with patches added by DAVE Embedded Systems to support the BORA and BORAX hardware platforms.

Target root file system[edit | edit source]

The Linux kernel running on the target needs to mount a root file system. Building a root file system from scratch is definitively a complex task because several well-known directories must be created and populated with a lot of files that must follow some standard rules. Again we will use pre-packaged root file systems that makes this task much easier. Please note that using a pre-packaged root file system can lead to conflicts with the application binaries obtained using the pre-built cross-toolchain: as a general rule, dynamically linking an application against libraries built with a different toolchain can cause malfunctioning.



Build system[edit | edit source]

A build system is a set of tools, source trees, Makefiles, patches, configuration files and scripts that make it easy to generate all the components of a complete embedded Linux system. A build system, once properly set up, automates the configuration and cross-compilation processes, generating all the required targets (userspace packages such as libraries and programs, the o.s. kernel, the bootloader and root filesystem images) depending on the configuration. In particular, using an integrated build system prevents from problems caused by misaligned toolchains, since a unique toolchain is used to build all the software components, including the customer application. Some well known structured build systems are the following:

In the following section, we will refer to the system running the Xilinx tools (that can be either a Microsoft Windows machine or a GNU/Linux machine) as the "Zynq development server", and to the machine running the GNU/Linux tools as the "Linux development server".

As described here, the structure of the BELK/BXELK has changed over the years. That's why the istructions here indicated may differ according to the kit version.

Setting up the Zynq development server environment[edit | edit source]

The following software packages must be installed on the Zynq development server:

  • Vivado® Design Suite version 2017.1 (for BELK 4.0.0 or newer, BXELK 2.0.0 or newer)
  • Vivado® Design Suite version 2014.4 (for BELK version up to 3.0.2, BXELK version up to 1.0.1)
  • Xilinx Software Development kit (same version as the Vivado® Design Suite)
  • Python 2.7.x (C:\Python27 must be the installation directory on Windows)
  • A Git tool (e.g. for Windows: MsysGit http://msysgit.github.io/).

The Zynq 7000 development tools can be downloaded from the Xilinx website: http://www.xilinx.com/support/download/index.htm in the WebPACK™ Edition, which is a free version that provides instant access to the fundamental Vivado features and functionality at no cost. For the hardware requirements of the PC, please refer to http://www.xilinx.com/design-tools/vivado/memory.htm#zynq-7000. The Git tool is used to download the BORA/BORAX project files for Vivado from DAVE Embedded Systems' public git repositories, as described in the next section.

N.B. Sometimes the download of the Vivado 2014.4 full package fails because of some download system malfunctioning, but the problem is barely noticeable, except by performing the MD5 check of the downloaded file. In case of problems, we suggest using the Multi-File Download (available on the same web page), that splits the full package in a collection of smaller files. If you use the Multi-File Download to get the "Vivado (No SDK)" package, you must also download the "Software Development Kit - 2014.4" package.

How BORA/BORAX project files are managed[edit | edit source]

Since a Vivado project for the Zynq device is composed of a lot of files (including temporary and GUI-managed files), providing the BORA project files with the BELK is not considered as an efficient and user-friendly solution, for two main reasons:

  • we should provide a compressed archive for each version (updates, new features, bug fixes) of the project, wasting storage space and download bandwidth, introducing redundancy and complicating file management
  • there is no version control, which means that it's not possible to track changes to the project files, making development and release management complicated and error-prone

The best solution to these problems is that we create and maintain a Git repository to store and track only the main files of the Vivado project. Therefore, the developer can clone the repository and keep it in sync with our modifications. The following diagram shows how the solution works:

git-based Vivado project management

BELK also provides the tools for keeping the files modified within the Vivado tools in sync with the local Git repository: with this solution, all the modifications are tracked and developers can take advantage of all the benefits of using git as a version control system.

The public git repository for BORA/Zynq project files is git@git.dave.eu:dave/bora/bora.git. Please note that BELK distribution provides the git archive of the .git directory of the repository, so the user can immediately get access to the development tree (please refer to section Using the pre-packaged git archive).

Setting up the Linux development server environment[edit | edit source]

During development, the software developer needs to interact with the target system. This section describes the tools that must be installed and configured on the Linux host system for this purpose.

BELK 4.0.0 or newer, BXELK 2.0.0 or newer[edit | edit source]

Thanks to the use of the Managed Virtual Machine (MVM) (the Basic version), the process of setting up the Linux development server is dramatically simplified with respect to the previous versions of the kit. To put it simply, MVM is a virtual machine containing all the tools required for the development of the software running on the target. To install it, please refer to this page.


200px-Emblem-important.svg.png

If you purchased a previous version of the kit and want to upgrade it, it is necessary to download the MVM image first. For more details, please contact our Sales Department.


As described here, MVM includes the resources—in terms of network services, cross-toolchain, etc.—to implement the development host shown here.


200px-Emblem-important.svg.png

As the XUELK kit is based on Yocto, the implementation of the MVM follows the approach described here. As such, the reading of this section is highly recommended.

Building the Yocto BSP image and the associated SDKs[edit | edit source]

The Yocto BSP image includes the U-Boot binary, the Linux kernel image, and the target root file system. For more information about how to build it and how to build the associated SDKs, please refer to this page.

Building the U-Boot and the Linux kernel individually[edit | edit source]

The U-Boot and the Linux kernel are typically built without invoking the Yocto build system.

Please refer to the following links for the specific instructions describing these operations:

C/C++ application development and debugging[edit | edit source]

For C/C++ application development and debugging, please refer to this page.

BELK version up to 3.0.2, BXELK version up to 1.0.1[edit | edit source]

Since various heterogeneous tools are required to build the software components for the BORA/BORAX SOM, BELK/BXELK does not provide a fully structured build system. In particular, the Xilinx Zynq 7000 development tools are required to configure the system and build the FSBL, while the standard GNU tools are required to build U-Boot, kernel and user-space applications.


During development, user needs to interact with the target system. This section describes the tools that must be installed and configured on the Linux host system for this purpose.

TFTP Server[edit | edit source]

One of the most useful features of a bootloader during development is the capability to download the Linux kernel from the network. This saves a lot of time because developer doesn't have to program the image in flash every time he/she modifies it. U-Boot implements the TFTP protocol (see the tftp command), so the host system must be configured to enable the TFTP service. Installation and configuration of a TFTP server depends on the host Linux distribution.

NFS Server[edit | edit source]

One of the most important components of a Linux system is the root file system. A good development root file system provides the developer with all the useful tools that can help him/her on his/her work. Such a root file system can become very big in size, so it's hard to store it in flash memory. User could split the file system in different parts, mounting them from different media (flash, network, USB...). But the most convenient thing is to mount the whole root file system from the network, allowing the host system and the target to share the same files. In this way, the developer can quickly modify the root file system, even “on the fly” (meaning that the file system can be modified while the system is running).

The most common way to setup a system like the one described is by the use of network file system (NFS). Installation and configuration of NFS service on host machine depends on the Linux distribution. Here is described the procedure for some common distributions.

Pre-built toolchain[edit | edit source]

To start developing software for the BORA/BORAX platform, users need a proper toolchain, which can be pre-built or built-from-scratch. Building a toolchain from scratch is not a trivial task, even though using a recent build system is easier than in the past. So the recommended approach consists of using a pre-built toolchain.

Instructions for BELK 4.0.0 or newer and BXELK 2.0.0 or newer[edit | edit source]

The Managed Virtual Machine (MVM) delivered along with these versions of BELK/BXELK provides a script which can be used to set up the build environment easily. Use the following command to do that:

dvdk@vagrant-ubuntu-trusty-64:~$ cd
dvdk@vagrant-ubuntu-trusty-64:~$ source env.sh 
Instructions for BELK <= 3.0.2 and BXELK <= 1.0.1[edit | edit source]

The toolchain used as a reference for these versions of BELK/BXELK is the toolchain provided with the Xilinx SDK (usually installed into /opt/Xilinx/SDK/<Vivado_version>/gnu/arm/lin/bin). Once the toolchain is installed, it is convenient to create a bash script containing the following lines in order to set up the build environment quickly:

export PATH=<path_to_toolchain>:$PATH
export ARCH=arm
export CROSS_COMPILE=<toolchain_prefix>

For example, for the Vivado 2014.4 release, the variables are the following:

export PATH=/opt/Xilinx/SDK/2014.4/gnu/arm/lin/bin:$PATH
export ARCH=arm
export CROSS_COMPILE=arm-xilinx-linux-gnueabi-

Once the such a script is created (for example env.sh), it can be invoked like this:

source env.sh

Pre-built root file system[edit | edit source]

Linux needs a root file system: a root file system must contain everything needed to support the Linux system (applications, settings, data, ..). The root file system is the file system that is contained on the same partition on which the root directory is located. The Linux kernel, at the end of its startup stage, mounts the root file system on the configured root device and finally launches the /sbin/init, the first user space process and "father" of all the other processes. For more information on the Linux filesystem, please refer to http://www.thegeekstuff.com/2010/09/linux-file-system-structure/.

BELK provides a pre-built root file system, that can be used during the evaluation/development phase, since it provides a rich set of packages for working with the BORA platform. Since this pre-built root file system is not generated using the same cross-toolchain used for building the BELK software components, we recommend to choose one of the following options:

  • if a native compiler is available on the root file system, go for native compilation instead of cross-compilation
  • when you cross-compile, rely on static linking and avoid dynamic linking against the root file system libraries
  • build your application using the same cross-toolchain (when available) used for building the root file system

Please refer to this page and this FAQ for further details.

U-Boot, Linux kernel and Yocto BSP git repositories[edit | edit source]

BELK/BXELK source trees for U-Boot, Linux kernel and Yocto BSP are provided as git repositories, as detailed in the following table.

Component Remote git repository
U-Boot git@git.dave.eu:dave/bora/u-boot-xlnx.git
Linux kernel git@git.dave.eu:dave/bora/linux-xlnx.git
Yocto BSP git@git.dave.eu:dave/bora/bora-bsp.git

Access to DAVE Embedded Systems' git repositories is granted to development kit's owners only. Please refer to this page for detailed instructions on how to get access.

The components listed in the table above can be kept in sync and up to date with DAVE Embedded Systems' repositories. Once the git account has been enabled, the developer can:

  • clone the repository with the git clone <git_remote_repository> command
  • synchronize a source tree entering the repository directory and launching the git fetch origin command.

Please note that git fetch doesn't merge the commits on the current branch. To do that, the developer should run the git merge command or replace the fetch-merge process with a single git pull command. Please note that the recommended method is the fetch-merge process. For further information on Git, please refer to the official Git Documentation (http://git-scm.com/documentation).

Using the pre-packaged git archive (BELK <= 3.0.0 only)[edit | edit source]

BELK distribution provides (on request) the tar-gzipped archive of the .git directory of the repositories, so the user can immediately get access to the development trees (for example this is used when corporate security policies don't allow to use the git protocol).

Uncompressing the archive enables access to the hidden .git directories of the repositories; to get the source files, the developer must enter the project directory (eg: bora/linux-xlnx.git) and launch the git checkout <bora current branch> command, like in the following examples:

  • For u-boot: git checkout bora
  • For linux: git checkout bora

Once these steps are completed, don't forget to update the repositories, as described in this section.



Updating git repositories[edit | edit source]

In BELK/BXELK, the following source trees are clones of the correspondent DAVE Embedded Systems git repositories:

Component GIT Remote
U-Boot git@git.dave.eu:dave/bora/u-boot-xlnx.git
Linux kernel git@git.dave.eu:dave/bora/linux-xlnx.git
Yocto BSP git@git.dave.eu:dave/bora/bora-bsp.git
Vivado project git@git.dave.eu:dave/bora/bora.git

For more information about the access to these repositories, please refer to this link.

Updating the repositories from BELK 2.1.0[edit | edit source]

200px-Emblem-important.svg.png

To update the repositories from BELK 2.1.0, the following commands should be used:

git fetch origin
git checkout -b <new_branch_name> origin/bora

Synchronizing the repositories[edit | edit source]

When the account is enabled, you can synchronize a source tree entering the repository directory and launching the git fetch command. Please note that git fetch doesn't merge the commits on the current branch. To do that, you should run the git merge command or replace the fetch-merge process with a single git pull command. Please note that the recommended method is the fetch-merge process. For further information on Git, please refer to Git Documentation.



Building U-Boot[edit | edit source]

It is assumed that the development environment has been set up properly as described here.

  • start the Linux development server and login into the system
  • assuming that a local repository has not been created, clone the remote U-Boot git repository (the “-b” option is used to automatically checkout the current branch):

git clone git@git.dave.eu:dave/bora/u-boot-xlnx.git -b bora-4.x.x

  • Setup the server environment (please refer to this section)
  • enter the source tree directory and select the desired target by issuing one of the following commands:
    • For BELK <= 3.0.2 and BXELK <= 1.0.1:
      make bora_qspi_config 
      make bora_mmc_config 
      make bora_noflash_config
    • For BELK 4.0.0 and BXELK 2.0.0:
      make bora_qspi_defconfig 
      make bora_mmc_defconfig 
      make bora_noflash_defconfig 
      make borax_qspi_defconfig 
      make borax_mmc_defconfig 
      make borax_noflash_defconfig
    • BELK 4.1.1 or newer more targets have been added for BoraLite booting from NAND and for the application note AN006
      make bora_nand_defconfig 
      make bora_mmc_an006_defconfig
bora_qspi and borax_qspi: U-Boot is built to use NOR flashed based environment. The resulting binary files are used to boot from serial NOR flash.
bora_mmc and borax_mmc: U-Boot environment is placed in SD/MMC card. The resulting binary files are used to boot from SD/MMC card. However, NOR flash and NAND flash are accessible.
bora_noflash and borax_noflash: U-Boot environment is placed in SD/MMC card. The resulting binary files are used to boot from SD/MMC card. NOR flash and NAND flash are disabled.
bora_nand_defconfig: U-Boot environment is placed on NAND flash.
  • build U-Boot by issuing make command. This will generate U-Boot binary images.
    • file extension .elf must be manually added on u-boot if ELF file is required (for example to build boot.bin for uSD)

Subsequent builds just require make command, without targets, to update the binary images.


200px-Emblem-important.svg.png

By default, BoraEVB and BoraXEVB are configured to boot from NOR flash. Consequently, the U-Boot image stored in the NOR flash is built with bora_qspi_defconfig and borax_qspi_defconfig configuration respectively.


In order to download them to the target via TFPT protocol, once the build process is complete the binary images can be copied to the tftp root directory (e.g. /tftpboot/bora/) with the following commands:

  • For BELK 4.0.0 or newer and BXELK 2.0.0 or newer:
cp spl/boot.bin /tftpboot/bora/ 
cp u-boot.img /tftpboot/bora/
  • For BELK <= 3.0.2 and BXELK <= 1.0.1 :
cp u-boot.bin /tftpboot/bora/



Building Linux kernel[edit | edit source]

It is assumed that the development environment has been set up properly as described here.

  • start the Linux development server and login into the system
  • assuming that a local repository has not been created, clone the remote Linux git repository (the “-b” option is used to automatically checkout the current branch):
git clone git@git.dave.eu:dave/bora/linux-xlnx.git -b bora-4.x.x
  • setup the server environment (please refer to this section)
  • enter the source tree directory and run the following commands:
make bora_defconfig
make UIMAGE_LOADADDR=0x8000 uImage bora.dtb
The former command selects the default BORA configuration, while the latter builds the kernel binary image with the required u-boot header and the kernel device tree. Please note that the mkimage tool is required for building the uImage binary. This tool must be installed on the Linux development server (please refer to the package manager of the Linux distribution).

update the kernel configuration[edit | edit source]

Default Linux kernel configuration can be changed by using the standard menuconfig or nconfig as make target. Subsequent builds just require uImage make target to update the binary image.

make menuconfig

BELK-make-menuconfig.png

kernel modules[edit | edit source]

It is possible to build the kernel modules too, together with the kernel image:

make UIMAGE_LOADADDR=0x8000 uImage modules bora.dtb

then, the built modules have to be prepared for being installed in the rfs:

make INSTALL_MOD_PATH=<directory_for_modules> modules_install

and properly copy them in the target root file system

tftpboot[edit | edit source]

Default linux kernel configuration can be changed by using the standard menuconfig, xconfig, or gconfig make target. Subsequent builds just require uImage make target to update the binary image. Once the build process is complete, the kernel binary image is stored into the arch/arm/boot/uImage file. Both this file and the kernel device tree can be copied to the tftp root directory (eg. /tftpboot/bora/) with the following commands:

cp arch/arm/boot/uImage /tftpboot/bora
cp arch/arm/boot/dts/bora.dtb /tftpboot/bora



Advanced use of Yocto build system[edit | edit source]

Yocto can be used to build an entire Linux distribution from source. The build process can be summarized as follows:

  • Make sure that all the prerequisites are met
  • Initialize the build environment, as described in here.
  • Optionally ensure the conf/local.conf configuration file, which is found in the Build Directory, is set up how you want it. This file defines many aspects of the build environment including the target machine architecture through the MACHINE variable, the development machine's processor use through the BB_NUMBER_THREADS and PARALLEL_MAKE variables, and a centralized tarball download directory through the DL_DIR variable.
  • Build the image using the bitbake command. For more information about BitBake, please refer to the BitBake User Manual.

For more information regarding Yocto build system, go to its dedicated category page

Prerequisites[edit | edit source]

The following prerequisites are required. They need to be done once only. Some generic development tools are required on the host Linux machine:

  • git
  • curl
  • build-essential
  • diffstat
  • texinfo
  • gawk
  • chrpath
  • ia32-libs (if the host machine is running a 64-bit OS)
  • python-m2crypto.

These packages can be installed with the following command:

sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat libsdl1.2-dev xterm.

It is also recommended to switch the system shell from Ubuntu's standard dash to more universal bash:

:~$ sudo dpkg-reconfigure dash

Initializing the build environment[edit | edit source]

In the BELK, we have simplified the Yocto initialization phase, relying on the repo tool and on a BORA BSP git repository, so that the initialization can be completed with a few commands as reported below:

:~$ mkdir belk && cd belk
:~/belk$ curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > repo
:~/belk$ chmod a+x repo
:~/belk$ ./repo init -u git@git.dave.eu:dave/bora/bora-bsp.git -b bora
:~/belk$ ./repo sync

Build the Yocto image[edit | edit source]

Please note that even building the basic root file system requires a few hours to complete the process on a mid-hi range desktop PC (4-6 cores, 8-12 GiB RAM), also depending on the Internet connection speed (all source are fetched from the network). Nearly 20GiB of disk space is required for the build. Once completed the initialization phase, developers can launch the Yocto image build process with the following commands:

:~$ cd ~/belk
:~/belk$ source bora-bsp-init-env.sh build
:~/belk/build$ bitbake base-rootfs-image

The resulting files (kernel, devicetree and u-boot binaries, plus .tar.gz root file system) will then be available inside build/tmp/deploy/images/bora.

Build additional packages[edit | edit source]

To build additional packages the user must first enter the directory where the bora-bsp-init-env.sh is placed and source it:

:~$ cd ~/belk
:~/belk$ source bora-bsp-init-env.sh build

And then he/she can run any of the bitbake commands:

:~/belk/build$ bitbake memtester

The resulting packages (the default format is ipk) can be found inside build/tmp/deploy/ipk.

Using pre-built package archive[edit | edit source]

Starting from BELK 3.0.1 / BXELK 1.0.0, the archive of pre-built packages belonging to openembedded-core layer is available. This allows to install on the target these packages via smart command, as described here.

The address of those repositories are detailed in the following table:


Name URL Description
all https://yocto.dave.eu/belk-latest/all architecture indipendent packages
cortexa9hf_neon https://yocto.dave.eu/belk-latest/cortexa9hf_neon/ Cortex A9 hf packages
bora https://yocto.dave.eu/belk-latest/bora BELK/BXELK packages

Please note that:

  • to point to a specific BELK revision user can substitute latest keyword with the specific x.y.z release (e.g. https://yocto.dave.eu/belk-3.0.1/armv7a_vfp_neon)
  • not all releases of BELK have a dedicated repository. In case your specific version is missing you can use the generic latest release
  • most of the packages are available inside cortexa9hf_neon repository

Demo on youtube[edit | edit source]

Get smart with SMART package manager on ZYNQ



Creating and building example Vivado project[edit | edit source]

BELK/BXELK provides an example Vivado project for BORA/BORAX/BORALITE boards. This project allows to:

  • generate the PS configuration files to be used with U-boot SPL build
  • generate the bitstream of a simple PL design used to route PS' CAN0 and UART0 signals through EMIO (see also the following pictures).


Block diagram of BORA example project
Block diagram of BORAX example project
Block diagram of BORALITE example project

This article describes how two build this project. Two procedures are described, the former is command line based while the latter is GUI based.

The project is stored is a git repository, as described here.

It is assumed that the Zynq development environment has been set up properly (see this page for more details).

Command line based procedure[edit | edit source]

200px-Emblem-important.svg.png

The following procedure make use of ambient variables to address all our boards.
Define the correct ones according the target SoM.
For Bora SoM use:

  • export BASE_NAME=bora
  • export UBOOT_PS7_DIR=bora

For BoraLite SoM use:

  • export BASE_NAME=boralite
  • export UBOOT_PS7_DIR=bora

For BoraX SoM use:

  • export BASE_NAME=borax
  • export UBOOT_PS7_DIR=borax


  • start the Zynq development server and login into the system
  • assuming that a local repository has not been created, clone the remote BORA git repository:
    git clone git@git.dave.eu:dave/bora/bora.git
  • copy the <bora_repo>/boards/ directory to <vivado_install_dir>/data/boards/
cd <bora_repo>
sudo cp -r boards/ /opt/Xilinx/Vivado/<Vivado_version>/data/
  • launch the Vivado Design Suite with the following commands[a][b]:
. /opt/Xilinx/Vivado/<Vivado_version>/settings64.sh
vivado -mode tcl -source scripts/recreate_prj_${BASE_NAME}_BASE.tcl -notrace -tclargs "gen_bitstream"
  • At the end of the bitstream build process, the build_prj_* script allows to automatically export hardware and lauch SDK.
  • The bitstream file is now present in <bora_repo>/vivado/${BASE_NAME}.runs/impl_1/${BASE_NAME}_wrapper.bit and <bora_repo>/vivado/${BASE_NAME}.runs/impl_1/${BASE_NAME}_wrapper.bin.
  • By default FSBL is not used anymore in the boot process. U-Boot SPL (first-stage bootloader) is used instead. PS configuration files are used to build U-boot binaries.
    • Copy the ps7_init_gpl.c and ps7_init_gpl.h source files into U-boot source code directory using the following command example for Bora:
cp <bora_repo>/bd/${BASE_NAME}/ip/${BASE_NAME}_processing_system7_0_0/ps7_init_gpl.* <U-boot_src_dir>/board/dave/bora/${UBOOT_PS7_DIR}/
  • Follow U-boot build instructions to build U-boot using new PS configurations. Please note that the U-Boot binary images released along with BELK/BXELK were already built upon the ps7_init_gpl.c and ps7_init_gpl.h source files generated by the Vivado project described in this article. As such, it is not generally required to rebuild U-Boot.
    • The PS configurations are the same for Bora and BoraLite boards.

GUI based procedure[edit | edit source]

200px-Emblem-important.svg.png

The following procedure make use of ambient variables to address all our boards.
Define the correct ones according the target SoM.
For Bora SoM use:

  • export BORA_SOM=Bora
  • export BASE_NAME=bora
  • export UBOOT_PS7_DIR=bora

For BoraLite SoM use:

  • export BORA_SOM=BoraLite
  • export BASE_NAME=boralite
  • export UBOOT_PS7_DIR=bora

For BoraX SoM use:

  • export BORA_SOM=BoraX
  • export BASE_NAME=borax
  • export UBOOT_PS7_DIR=borax


  • start the Zynq development server and login into the system
  • assuming that a local repository has not been created, clone the remote BORA git repository:git clone git@git.dave.eu:dave/bora/bora.git
  • copy the <bora_repo>/boards/ directory to <vivado_install_dir>/data/boards/ :
cd <bora_repo>
sudo cp -r boards/ /opt/Xilinx/Vivado/<Vivado_version>/data/
  • launch the Vivado Design Suite GUI with the following commands[c]:
. /opt/Xilinx/Vivado/201x.y/settings64.sh
vivado
  • from the start page click on Create New Project
  • click Next
  • select the directory build project, insert the name of the project <prj_name> and click Next
  • select RTL Project, enable Do not specify sources at this time and click Next
  • on the Default Part form, click on the Boards button to filter the available boards. Select ${BORA_SOM} and click Next
  • check the summary page and click Finish
  • For the block design there are two possible ways:
    • Add the existing BD within the repo:
      • select Add sources from the Flow Navigator
      • click on Add or create design sources
      • select Add Files and add <bora_repo>/bd/${BASE_NAME}/${BASE_NAME}.bd
      • check that the option Copy sources into project is disabled and click finish
    • Create a new block design:
      • click on Create Block Design from the Flow Navigator
      • insert ${BASE_NAME} as Design name and click OK
      • this creates a new block design. From the Diagram tab, add a new IP:
        • click the Add IP side button, or
        • click Add IP on the upper suggestions bar
      • double click on ZYNQ7 Processing System
      • this adds the IP that models the PL component of Zynq. Launch Run Block Automation from the upper suggestions bar
      • check that Apply Board Preset is selected and click OK
        • this applies the default settings for BORA/BORAX and creates the I/O ports for the DDR and MIO pins
      • UART_0 and CAN_0 connections must be manually created:
        • right-clicking on each port (where mouse cursor switch to pencil) and selecting Make External or with keyboard shortcut Ctrl+T. The name of the external ports must be UART_0 and CAN_0 respectively, otherwise correct manually
      • manually connect the FCLK_CLK0 signal to M_AXI_GP0_ACLK and save the block design
      • from the sources tab, select the BORA block design ${BASE_NAME}.bd as Design Sources and from the context menu select Create HDL Wrapper
      • on the next window, select Let Vivado menage wrapper and auto-update and click OK
      • this creates the Verilog file ${BASE_NAME}_wrapper.v. If this file is not automatically included in the project, add it using the Add sources option
        • select Add or create design sources and click Next
        • select the >${BASE_NAME}_wrapper.v file from the <project_directory>/<prj_name>.srcs/sources_1/bd/${BASE_NAME}/hdl/ directory
  • select Add sources and click on Add or create constraints
  • select the ${BASE_NAME}_pinout.xdc and ${BASE_NAME}_timings.xdc files from the constr directory of the BORA repository
  • check that the option Copy constraints files into project is disabled and click finish
  • create the synthesis, implementation and bitstream clicking Generate Bitstream from the Flow Navigator and wait the completion of the operation
  • once completed, select Open Implemented Design
  • create the binary bitstream running the tcl script provided with the BORA repository. Launch Tools -> Run Tcl Script
  • select the generate_binary_bitstream.tcl file from the scripts directory from the BORA repository
  • The bitstream file is now present in <project_directory>/<prj_name>.runs/impl_1/${BASE_NAME}_wrapper.bit and <project_directory>/<prj_name>.runs/impl_1/${BASE_NAME}_wrapper.bin.
  • Copy the ps7_init_gpl.c and ps7_init_gpl.h source files into U-boot source code directory using the following command example for Bora:
cp <project_directory>/<prj_name>.srcs/sources_1/bd/${BASE_NAME}/ip/<prj_name>_processing_system7_0_0/ps7_init_gpl.* <U-boot_src_dir>/board/dave/bora/${UBOOT_PS7_DIR}/Follow U-boot build instructions to build U-boot using new PS configurations. Please note that the U-Boot binary images released along with BELK/BXELK were already built upon the ps7_init_gpl.c and ps7_init_gpl.h source files generated by the Vivado project described in this article. As such, it is not generally required to rebuild U-Boot.

  1. In a 32 bit system, Vivado settings are configured with the following command /opt/Xilinx/Vivado/<Vivado_version>/settings32.sh
  2. Passing the -tclargs "gen_bitstream" parameters allows for automatic building of the FPGA bitstream.
  3. In a 32 bit system, Vivado settings are configured with the following command /opt/Xilinx/Vivado/201x.y/settings32.sh

Downloading the bitstream to the device[edit | edit source]

Once the bitstream is ready, U-Boot itself can be used to download it onto the device. There are other options, however. For more details, please refer to this section.

Helloworld from UART0[edit | edit source]

Using the FPGA bitstream previously created, it is possible to use serial tty port on Linux. The serial port is mapped to /dev/ttyPS1 (this is because /dev/ttyPS0 is the console mapped to UART1).

Here below an example on C code for initializing and using UART0 through FPGA:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h> 
#include <termios.h>

int set_interface_attribs (int fd, int speed, int parity)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                printf("error %d from tcgetattr", errno);
                return -1;
        }

        cfsetospeed (&tty, speed);
        cfsetispeed (&tty, speed);

        tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
        // disable IGNBRK for mismatched speed tests; otherwise receive break
        // as \000 chars
        tty.c_iflag &= ~IGNBRK;         // disable break processing
        tty.c_lflag = 0;                // no signaling chars, no echo,
                                        // no canonical processing
        tty.c_oflag = 0;                // no remapping, no delays
        tty.c_cc[VMIN]  = 0;            // read doesn't block
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

        tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

        tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
                                        // enable reading
        tty.c_cflag &= ~(PARENB | PARODD);      // shut off parity
        tty.c_cflag |= parity;
        tty.c_cflag &= ~CSTOPB;
        tty.c_cflag &= ~CRTSCTS;

        if (tcsetattr (fd, TCSANOW, &tty) != 0)
        {
                printf("error %d from tcsetattr", errno);
                return -1;
        }
        return 0;
} 


int main()
{
	int fd;
	char *portname = "/dev/ttyPS1";

	char msg[] = "Hello World from BELK (FPGA PS0 UART)!\n\r";

	fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
	if (fd < 0)
	{
        	printf("error %d opening %s: %s", errno, portname, strerror (errno));
	        exit(1);
	}
	printf(msg);

	set_interface_attribs (fd, B115200, 0);  // set speed to 115,200 bps, 8n1 (no parity)
	write(fd, msg, strlen(msg));

	exit(0);
}


and then compile it:

dvdk@vagrant:~/bora/rfs/belk/home/root$ source ~/env.sh 
dvdk@vagrant:~/bora/rfs/belk/home/root$ $CC hello_UART0.c -o hello_UART0

The program executed print out the msg string on the serial console and on /dev/ttyPS1 port.




Building the Yocto BSP[edit | edit source]

Quick reference[edit | edit source]

Repository Information
Repository BSP Manifest Yocto BSP Layer
URL git@git.dave.eu:bora/bora-bsp.git git@git.dave.eu:bora/meta-bora.git
stable branch bora-morty bora-morty
stable tag belk-4.1.4 belk-4.1.4
Build targets
Name Description
dave-image-devel This image include tools for development/debugging
dave-image-networking In addition dave-image-devel, this image provides several networking tools

As known, in addition to a bootloader and the o.s. kernel, an embedded Linux system needs a root file system to operate. The root file system must contain everything needed to support the Linux system (applications, settings, data, etc.). The root file system is the file system that is contained on the same partition on which the root directory is located. The Linux kernel, at the end of its startup stage, mounts the root file system on the configured root device and finally launches the /sbin/init, the first user space process and "father" of all the other processes. For more information on the Linux filesystem, please refer to http://www.thegeekstuff.com/2010/09/linux-file-system-structure/.

BELK/BXELK provides one (or more) pre-built root file system, that can be used during the evaluation/development/deployment cycle. For instance, the root file system included in the bora-image-devel image is suited for the development phase, since it provides a relatively rich set of packages including tools and libraries used to debug the application code. The pre-built root file systems are located here: /home/dvdk/<target_name>/rfs/<kit_name>.

Besides the pre-built root file systems, BELK/BXELK also provides a rich repository containing pre-built applications and libraries. These packages can be easily installed on the target by using the smart tool. Please refer to this section for more details.

To generate the supported root file systems, the build of the Yocto BSP has to be run. The output of this process is an image containing the U-Boot binary file, the Linux kernel image, and the selected root file system image. The following sections describe in detail how to execute this operation.

For more general information regarding the Yocto build system, please refer the dedicated category page.

How to build the Yocto BSP images including the U-Boot binary file, the Linux kernel image, and the target root file system image[edit | edit source]

200px-Emblem-important.svg.png

The following procedure requires the access to the DAVE Embedded Systems' git repositories. The access to such repositories is granted to development kit's owners only. Please refer to this page for detailed instructions on how to get it.


200px-Emblem-important.svg.png

This process requires a lot of hardware resources in terms of disk storage, RAM, and processing power. For this reason, it also is recommended to consider the use of a physical machine. For more details on this topic, please refer to this document which talks about the advanced use of the Yocto build system.

Initialize the build environment[edit | edit source]

Before running the build, the environment must be initialized properly.

BELK/BXELK Yocto BSP uses git-repo tool to fetch all the required git repositories. To install it, please use the following commands:

dvdk@dvdk-vm:~/belk$ curl http://commondatastorage.googleapis.com/git-repo-downloads/repo-1 > repo
dvdk@dvdk-vm:~/belk$ chmod a+x repo
dvdk@dvdk-vm:~/belk$ ./repo init -u git@git.dave.eu:bora/bora-bsp.git -b bora-morty
dvdk@dvdk-vm:~/belk$ ./repo sync
dvdk@dvdk-vm:~/belk$ source bora-bsp-init-env.sh
unauthenticated git protocol error[edit | edit source]
200px-Emblem-important.svg.png

Since March 15th, 2022, GitHub stopped accepting DSA keys. RSA keys uploaded after Nov 2, 2021 will work only with SHA-2 signatures. The deprecated MACs, ciphers, and unencrypted Git protocol are permanently disabled.
For more details on this topic, please refer to this Technical Note.

Running the build[edit | edit source]

Please note that even the basic root file system requires a few hours to build on a mid/hi range desktop (4-6 cores, 8-12 GiB RAM) also depending on your Internet connection speed (all sources are fetched from the network). Nearly 20GiB of disk space is required for the build. The process may be slowed down significantly since the performances of a virtual machine are reduced if compared to the physical hardware. Thus, it's recommended to check the hardware capabilities of the host system and, when building with Yocto is required, to consider the following options:

  • Migrating the build system to a physical machine
  • Assuming that the host system has the required resources, extending the hardware capabilities of the default MVM (e.g. adding more cores and disk space).

Once completed the initialization phase, developers can launch the Yocto image build process with the following commands:

dvdk@dvdk-vm:~/belk/build$ bitbake <target-image-name>

Where <target-image-name> is one of the images listed in here.

Once the build process is completed, the resulting files (the U-Boot binaries, the Linux kernel image, the device tree blob, the .tar.gz compressed root file system image, etc.) will be available in build/tmp/deploy/images/bora.

Generating the SDKs[edit | edit source]

After creating an image as described in the previous version, the corresponding SDK can be generated by issuing the following command:

bitbake <target-image-name> -c populate-sdk

Again, replace <target-image-name> with one of the images listed in here.

Building additional packages[edit | edit source]

To build additional packages the user must first enter the directory where the bora-bsp-init-env.sh is placed and source it

dvdk@dvdk-vm:~/belk$ source bora-bsp-init-env.sh
dvdk@dvdk-vm:~/belk/build$

And then can run any of the bitbake command.

dvdk@dvdk-vm:~/belk/build$ bitbake memtester

The resulting packages (the default format is ipk) can be found inside build/tmp/deploy/rpm.

dvdk@dvdk-vm:~/belk/build$ ls -l tmp/deploy/rpm/cortexa9hf_neon/memtester*
-rw-r--r-- 1 dvdk dvdk 10692 Sep 12 16:05 tmp/deploy/rpm/cortexa9hf_neon/memtester-4.3.0-r0.cortexa9hf_neon.rpm
-rw-r--r-- 1 dvdk dvdk 27693 Sep 12 16:05 tmp/deploy/rpm/cortexa9hf_neon/memtester-dbg-4.3.0-r0.cortexa9hf_neon.rpm
-rw-r--r-- 1 dvdk dvdk  2872 Sep 12 16:05 tmp/deploy/rpm/cortexa9hf_neon/memtester-dev-4.3.0-r0.cortexa9hf_neon.rpm
-rw-r--r-- 1 dvdk dvdk  5903 Sep 12 16:05 tmp/deploy/rpm/cortexa9hf_neon/memtester-doc-4.3.0-r0.cortexa9hf_neon.rpm



System boot and recovery via microSD card[edit | edit source]

BELK provides a bootable microSD that can be used not only to quickly start the system, but also as a recovery method in case the primary boot device (eg. QSPI NOR flash) gets erased or corrupted. The following sections describe how to create a bootable SD card and how to configure the system for booting from SD. This article, for example, shows how to make use of such a card to restore the U-Boot image onto the NOR flash.


200px-Emblem-important.svg.png

It is worth remembering that the bootable microSD card described in this article is not configured to perform a full boot sequence, including the operating system bootstrap. The bootable microSD card delivered along with the kit is set up to do a full bootstrap sequence, instead. For more details, please refer to this section.

How to create a bootable microSD card[edit | edit source]

BELK <= 3.0.2 / BXELK <= 1.0.1[edit | edit source]

This section describes how to create a new bootable microSD card from scratch for BELK <= 3.0.2 and BXELK <= 1.0.1. The following components must be available:

  • FSBL built with Vivado 2014.4 as described here
  • U-boot built in elf format, as described in here
  • FPGA bitstream (optional).

The procedure is the following:

  • from the Vivado 2014.4 SDK, apply the required patches to the main.c project file.This step can be done in two ways:
    • manually, directly modifying the main.c file adding the following code snippets:
----CUT----
	/*
	 * Unlock SLCR for SLCR register write
	 */
	SlcrUnlock();

+	*((u32 *)0xF8000830) = 0x003F003F;
+	*((u32 *)0xF8000834) = 0x003F003F;

	/* If Performance measurement is required 
	 * then read the Global Timer value , Please note that the
----CUT----

----CUT----
	/*
	 * Read bootmode register
	 */
	BootModeRegister = Xil_In32(BOOT_MODE_REG);
	BootModeRegister &= BOOT_MODES_MASK;

+	// always init QSPI
+	InitQspi();
	
	/*
	 * QSPI BOOT MODE
	 */
#ifdef XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR
----CUT----
    • automatically, using the Apply Patch function and selecting the belk-sd-boot.patch file provided with the BELK (please refer to the following images):
Automatic patch applying (1/3)
Automatic patch applying (2/3)
Automatic patch applying (3/3)
  • once the patch is applied, rebuild the FSBL project
  • from the Xilinx Tools menu, select Create Zynq Boot Image
  • select Create New BIF file and insert path and name of the .bif file
  • in the Boot image partitions section, click on Add to browse and add the following files:
    • FSBL in .elf format, with bootloader as partition type
    • (optional) FPGA bitstream in .bit format, with partition type datafile
    • U-boot binary with .elf extension, with partition type datafile
  • in the Output path section, browse and select the path where saving the boot.bin file
  • on a PC, format the microSD card creating a FAT32 partition
  • copy the boot.bin file to the microSD card FAT32 partition.

BELK-4.0.0 / BXELK-2.0.0[edit | edit source]

This section describes how to create a new bootable microSD card from scratch for BELK-4.0.0 and BXELK-2.0.0. The following components must be available:

  • U-boot SPL and U-boot second stage built as described in here
  • FPGA bitstream (optional).

The procedure is the following:

  • on a PC, format the microSD card creating a FAT32 partition
  • copy the following files to the microSD card FAT32 partition:
    • U-boot SPL: boot.bin
    • U-boot second stage: u-boot.img
    • Fpga bitstream .bit (optional): fpga.bit

How to configure the system for microSD boot[edit | edit source]

For BORA / BORA Evaluation kit systems please refer to this link.

For BORA Xpress/ BORA xpress Evaluation kit systems please refer to this link.

For BORA Lite Evaluation kit systems please refer to this link.


200px-Emblem-important.svg.png

In case the microSD card provided along with the kit is used, the Programmable Logic is automatically programmed with the example design during the boot process.


Deployment[edit | edit source]

Restoring U-Boot on SPI NOR flash[edit | edit source]

This article describes how to restore U-Boot on SPI NOR flash in case it gets corrupted or it is deleted accidentally.

The example refers to BoraXEVB carrier board but the procedure is the same for BoraEVB board as well. The procedure was tested with the binaries released with BXELK 2.0.0. As such, it is valid for BELK 4.x as well.

At the end of the procedure, the default partitioning of the NOR flash will be restored. It is depicted in the following image.


NOR flash default partitioning scheme

Instructions[edit | edit source]

First of all, create a bootable microSD card as described here.

Then, boot the board with the microSD card and stop automatic boot process of U-Boot in order to access the console.

U-Boot SPL 2017.01-belk-4.0.0-rc1 (Jul 03 2017 - 01:00:18)
mmc boot
Trying to boot from MMC1
reading fpga.bit
spl_load_image_fat: error reading image fpga.bit, err - -1
spl: error reading image fpga.bit, err - 1
reading u-boot.img
reading u-boot.img


U-Boot 2017.01-belk-4.0.0-rc1 (Jul 03 2017 - 01:00:18 +0200)

Model: Bora
Board: Xilinx Zynq
I2C:   ready
DRAM:  ECC disabled 1 GiB
Relocating to 3ff2e000, new gd at 3eaedee8, sp at 3eaedec0
NAND:  1024 MiB
MMC:   sdhci@e0100000: 0 (SD)
reading bora.env

** Unable to read "bora.env" from mmc0:1 **
Using default environment

In:    serial@e0001000
Out:   serial@e0001000
Err:   serial@e0001000
Model: Bora
Board: Xilinx Zynq
SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 32 MiB
SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 32 MiB
SOM ConfigID#: 00000004
SOM UniqueID#: 2a0e92c4:03193a4b
ds2431_readmem(): error in chip reset
ds2431_readmem(): error in reading buffer
ds2431_readmem(): error in chip reset
ds2431_readmem(): error in reading buffer
CB ConfigID CRC mismatch for 0x00000000 (was 0x00000000, expected 0x2144df1c) at block 3 (offset 96): using default
CB ConfigID#: ffffffff
CB UniqueID#: 00000000:00000000
Net:   ZYNQ GEM: e000b000, phyaddr 7, interface rgmii-id
eth0: ethernet@e000b000
Hit ENTER within 3 seconds to stop autoboot
Bora>

Programming U-Boot from ethernet[edit | edit source]

Properly define the ethernet configuration parameter:

Bora> setenv ipaddr 192.168.0.91
Bora> setenv ethaddr 00:50:C2:1E:AF:B3
Bora> setenv serverip 192.168.0.23

Download via TFTP the U-Boot SPL and the U-Boot binary images. Then, burn them in NOR flash memory:

Bora> setenv SPL_base 0
Bora> setenv u-boot_base 0x40000
Bora> setenv update_spl 'sf probe 0 0 0;sf erase ${SPL_base} +${filesize};sf write ${loadaddr} ${SPL_base} ${filesize}'
Bora> setenv update 'sf probe 0 0 0;sf erase ${u-boot_base} +${filesize};sf write ${loadaddr} ${u-boot_base} ${filesize}'
zynq-uboot> tftpboot ${loadaddr} bora/u-boot/belk-4.1.4_borax_qspi_boot.bin
Gem.e000b000:7 is connected to Gem.e000b000.  Reconnecting to Gem.e000b000
Gem.e000b000 Waiting for PHY auto negotiation to complete... done
Using Gem.e000b000 device
TFTP from server 192.168.0.23; our IP address is 192.168.0.91
Filename 'bora/u-boot/belk-4.1.4_borax_qspi_boot.bin'.
Load address: 0x8000000
Loading: ##################
         782.2 KiB/s
done
Bytes transferred = 88940 (15b6c hex)
Bora> run update_spl
SF: Detected S25FL256S_64K with page size 64 KiB, total 32 MiB
SF: Successfully erased 131072 bytes @ 0x0
SF: program success 89036 bytes @ 0x0
Bora> tftpboot ${loadaddr} bora/u-boot/belk-4.1.4_borax_qspi_u-boot.img
Gem.e000b000:7 is connected to Gem.e000b000.  Reconnecting to Gem.e000b000
Gem.e000b000 Waiting for PHY auto negotiation to complete... done
Using Gem.e000b000 device
TFTP from server 192.168.0.23; our IP address is 192.168.0.91
Filename 'bora/u-boot/belk-4.1.4_borax_qspi_u-boot.img'.
Load address: 0x8000000
Loading: #################################################################
         #################################################################
         ####
         918 KiB/s
done
Bytes transferred = 683980 (a6fcc hex)
Bora> run update
SF: Detected S25FL256S_64K with page size 64 KiB, total 32 MiB
SF: Successfully erased 983040 bytes @ 0x40000
SF: program success 684100 bytes @ 0x40000
Bora>


Select the SPI NOR flash as boot device, remove the microSD card, and reset the board. The board should boot off the NOR flash as shown in the following image.

Bora> reset
resetting ...

U-Boot SPL 2017.01-belk-4.1.4 (Jul 28 2021 - 23:15:11)
qspi boot
Trying to boot from SPI

U-Boot 2017.01-belk-4.1.4 (Jul 28 2021 - 23:15:11 +0200), Build: belk-4.1.4

Model: Bora
Board: Xilinx Zynq
I2C:   ready
DRAM:  ECC disabled 1 GiB
Relocating to 3ff2e000, new gd at 3eaedee8, sp at 3eaedec0
NAND:  1024 MiB
MMC:   Card did not respond to voltage select!
Card did not respond to voltage select!
sdhci@e0100000 - probe failed: -95
Card did not respond to voltage select!

Card did not respond to voltage select!
** Bad device mmc 0 **
Using default environment

In:    serial@e0001000
Out:   serial@e0001000
Err:   serial@e0001000
Model: Bora
Board: Xilinx Zynq
SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 32 MiB
SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 32 MiB
SOM ConfigID#: 00000004
SOM UniqueID#: 2a0e92c4:03193a4b
ds2431_readmem(): error in chip reset
ds2431_readmem(): error in reading buffer
ds2431_readmem(): error in chip reset
ds2431_readmem(): error in reading buffer
CB ConfigID CRC mismatch for 0x00000000 (was 0x00000000, expected 0x2144df1c) at block 3 (offset 96): using default
CB ConfigID#: ffffffff
CB UniqueID#: 00000000:00000000
Net:   ZYNQ GEM: e000b000, phyaddr 7, interface rgmii-id
eth0: ethernet@e000b000
Hit ENTER within 3 seconds to stop autoboot

Notes about BELK 3.x.x/BXELK 1.x.x and older[edit | edit source]

Until BELK 3.x.x/BXELK 1.x.x, a little bit different partitioning scheme was used. It is illustrated in the following picture.


caption


This is due to the fact that those kits made use of the FSBL. Consquently, the header required by the Zynq'a bootrom and the FSBL binary image were stored at the bottom of the NOR flash. BELK 4.x.x and BXELK 2.x.x and newer are based on U-Boot SPL, instead. The U-Boot SPL binary image includes the header as well. This leads to a different partitioning.



Standalone boot[edit | edit source]

This document shows some examples related to configuring Bora/BoraX/BoraLite for standalone operativity.

We'll explain how to program and configure a BORA Xpress-based system to boot in standalone mode, without the need of a system microSD card or an NFS server. Only the flash memories available on the SoM itself will be used to store persistently all the software required.

The examples here documented are valid for BORA and for BORA Lite as well.


200px-Emblem-important.svg.png

It is worth remembering that the examples shown in this article don't make use of any image script. This technique is used by the bootable microSD card delivered along with the kit, instead. For more details, please refer to this section.

Use case #1[edit | edit source]

Introduction[edit | edit source]

This configuration makes use of one of the most common partitioning schemes, that is:

  • The NOR flash acts as boot memory; as such, it contains
    • bootrom header and FSBL (or header+U-Boot SPL)
    • U-Boot
    • U-Boot redundant environment
    • Even though these images are not strictly required to boot the system, the NOR flash also contains:
      • The Linux kernel image
      • The Linux Device Tree Blob (DTB)
      • The bitstream file for the Programmable Logic (PL).
  • The NAND flash contains a partition devoted to a read/write UBIFS root filesystem.

The resulting flash memory layout is illustrated in the following pictures.


NOR flash partitioning scheme


NAND flash partitioning scheme


In essence, the bootstrap sequence looks like this:

  • U-Boot fetches and programs the PL bitstream
  • Then it fetches the Linux kernel binary images (kernel and DTB) from the on-board NOR flash memory
  • Once started, the Linux kernel mount the root filesystem from a NAND partition.
Testbed[edit | edit source]

This configuration was tested with the following testbed:

  • SOM: DBXF4110D2R
  • carrier board: EVBBX0000C0R
  • software: BXELK 1.0.0

Program the root filesystem in NAND flash[edit | edit source]

This is a common step for both booting options.

  • Boot the system via SD or NFS as described into the System boot and recovery via microSD card and Booting the system via NFS
  • By default, the NAND is already partitioned to allow booting from NAND-only (see next section) and, thus, some partitions are reserved for FSBL, U-boot and kernel images. Here we won't modify this default configuration. The MTD partitions can be dumped with /proc/mtd (the partition's name should be self-explanatory)
root@bora:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00040000 00020000 "spl"
mtd1: 000c0000 00020000 "uboot"
mtd2: 00040000 00020000 "env1"
mtd3: 00040000 00020000 "env2"
mtd4: 00600000 00020000 "fpga"
mtd5: 00080000 00020000 "fdt"
mtd6: 00800000 00020000 "kernel"
mtd7: 3f000000 00020000 "nand-ubi"


200px-Emblem-important.svg.png

Please note that MTD partition index may change depending on flash device availability, flash device size, u-boot environment variables or kernel device driver load order. Always take care of looking inside /proc/mtd to match your specific layout


  • Format and initialize nand-ubi partition, which in our case is mtd7, using UBI with:
ubiformat /dev/mtd7
ubiattach -m 7
ubimkvol /dev/ubi0 -N rootfs -m

E.g.

root@bora:~# ubiformat /dev/mtd7
ubiformat /dev/mtd7
ubiformat: mtd7 (nand), size 1056964608 bytes (1008.0 MiB), 8064 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 8063 -- 100 % complete
ubiformat: 8060 eraseblocks have valid erase counter, mean value is 1
ubiformat: 4 bad eraseblocks found, numbers: 8060, 8061, 8062, 8063
ubiformat: formatting eraseblock 8063 -- 100 % complete
root@bora:~# ubiattach -m 7
[  275.247791] ubi0: attaching mtd7
[  280.486952] ubi0: scanning is finished
[  280.520370] ubi0: attached mtd7 (name "nand-ubi", size 1008 MiB)
[  280.526302] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[  280.533222] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[  280.539860] ubi0: VID header offset: 512 (aligned 512), data offset: 2048
[  280.546610] ubi0: good PEBs: 8060, bad PEBs: 4, corrupted PEBs: 0
[  280.552720] ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
[  280.559908] ubi0: max/mean erase counter: 3/2, WL threshold: 4096, image sequence number: 857573235
[  280.568946] ubi0: available PEBs: 7900, total reserved PEBs: 160, PEBs reserved for bad PEB handling: 156
[  280.578486] ubi0: background thread "ubi_bgt0d" started, PID 983
UBI device number 0, total 8060 LEBs (1039933440 bytes, 991.8 MiB), available 7900 LEBs (1019289600 bytes, 972.1 MiB), LEB size 129024 bytes (126.0 KiB)
root@bora:~# ubimkvol /dev/ubi0 -N rootfs -m
Set volume size to 1019289600
Volume ID 0, size 7900 LEBs (1019289600 bytes, 972.1 MiB), LEB size 129024 bytes (126.0 KiB), dynamic, name "rootfs", alignment 1
root@bora:~# 
  • Now mount the UBI volume using UBIFS in a temporary directory
mkdir -p /mnt/nand
mount -t ubifs ubi0_0 /mnt/nand

E.g.:

root@bora:~# mkdir -p /mnt/nand
root@bora:~# mount -t ubifs ubi0_0 /mnt/nand
[  327.559316] UBIFS (ubi0:0): default file-system created
[  327.565925] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 990
[  327.694738] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "rootfs"
[  327.702090] UBIFS (ubi0:0): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[  327.711995] UBIFS (ubi0:0): FS size: 1016967168 bytes (969 MiB, 7882 LEBs), journal size 33546240 bytes (31 MiB, 260 LEBs)
[  327.722998] UBIFS (ubi0:0): reserved for root: 4952683 bytes (4836 KiB)
[  327.729608] UBIFS (ubi0:0): media format: w4/r0 (latest is w4/r0), UUID 0D33F80E-E80A-43F7-BE9E-C2D24C4FCD14, small LPT model
  • you can now extract the root file system into that directory
tar jxvf dave-image-devel-bora.tar.bz2 . -C /mnt/nand
  • finally, you need to cleanly umount and detach the MTD partition
umount /mnt/nand/
ubidetach -m 7

E.g.

root@bora:~# umount /mnt/nand/
[  417.604700] UBIFS (ubi0:0): un-mount UBI device 0
[  417.609362] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" stops
root@bora:~# ubidetach -m 7
[  424.230219] ubi0: detaching mtd7
[  424.238132] ubi0: mtd7 is detached
root@bora:~#

You can now safely reboot or turn off the system.

Program the boot images in NOR flash[edit | edit source]

It is assumed that the following U-Boot's environment variables are defined:

fdt_base=0x00780000
fpga_base=0x00180000
kernel_base=0x00800000
loadk=tftpboot ${loadaddr} ${bootfile}
loadfdt=tftpboot ${fdtaddr} ${fdtfile}
loadfpga=tftpboot ${loadaddr} ${fpgafile}
updatek=sf probe 0 0 0;sf erase ${kernel_base} +${filesize};sf write ${loadaddr} ${kernel_base} ${filesize}
updatefdt=sf probe 0 0 0;sf erase ${fdt_base} +${filesize};sf write ${fdtaddr} ${fdt_base} ${filesize}
updatefpga=sf probe 0 0 0;sf erase ${fpga_base} +${filesize};sf write ${loadaddr} ${fpga_base} ${filesize}
spi_loadk=sf read ${loadaddr} ${kernel_base} 0x800000
spi_loadfdt=sf read ${fdtaddr} ${fdt_base} 0x80000
spi_loadfpga=sf read ${loadaddr} ${fpga_base} 0x600000
spi_programfpga=run spi_loadfpga; fpga load 0 ${loadaddr} 0x600000
  • Update the bootfile, fdtfile and fpgafile environment variables to fit the filename as found inside the TFTP server.
  • Program kernel and device tree on NOR flash with the following U-Boot command
zynq-uboot> sf probe; run loadfpga updatefpga loadk updatek loadfdt updatefdt

E.g.:

zynq-uboot> sf probe; run loadfpga updatefpga loadk updatek loadfdt updatefdt
SF: Detected S25FL128S_64K with page size 256 Bytes, erase size 64 KiB, total 16 MiB
Using Gem.e000b000 device
TFTP from server 192.168.0.23; our IP address is 192.168.0.209
Filename 'bora/borax-BELK-3.0.0-fpga.bin'.
Load address: 0x2080000
Loading: T #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ###############################################################
         823.2 KiB/s
done
Bytes transferred = 5979916 (5b3f0c hex)
SF: Detected S25FL128S_64K with page size 256 Bytes, erase size 64 KiB, total 16 MiB
SF: 6029312 bytes @ 0x180000 Erased: OK
SF: 5979916 bytes @ 0x180000 Written: OK
Using Gem.e000b000 device
TFTP from server 192.168.0.23; our IP address is 192.168.0.209
Filename 'bora/linux/belk-3.0.0_uImage'.
Load address: 0x2080000
Loading: T #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##############################
         545.9 KiB/s
done
Bytes transferred = 3477184 (350ec0 hex)
SF: Detected S25FL128S_64K with page size 256 Bytes, erase size 64 KiB, total 16 MiB
SF: 3538944 bytes @ 0x800000 Erased: OK
SF: 3477184 bytes @ 0x800000 Written: OK
Using Gem.e000b000 device
TFTP from server 192.168.0.23; our IP address is 192.168.0.209
Filename 'bora/linux/belk-3.0.0_bora.dtb'.
Load address: 0x2000000
Loading: T ##
         2 KiB/s
done
Bytes transferred = 10019 (2723 hex)
SF: Detected S25FL128S_64K with page size 256 Bytes, erase size 64 KiB, total 16 MiB
SF: 65536 bytes @ 0x780000 Erased: OK
SF: 10019 bytes @ 0x780000 Written: OK

In U-Boot environment please verify that the following default variables are set in order to be able to boot from NOR + NAND

nandargs=setenv bootargs ubi.mtd=7 root=ubi0_0 rootfstype=ubifs rw
spi_nand=sf probe; run spi_programfpga spi_loadk spi_loadfdt nandargs addcons addmisc; bootm ${loadaddr} - ${fdtaddr}


Reboot the system and configure U-Boot to apply the new configuration

=> setenv bootcmd run spi_nand
=> saveenv

Use case #2[edit | edit source]

Introduction[edit | edit source]

This configuration makes use the most common partitioning schemes for booting completely from NAND flash, that is:

  • The NAND flash acts as boot memory and root file system storage; as such, it contains
    • bootrom header and U-Boot SPL
    • U-Boot
    • U-Boot redundant environment
    • The Linux kernel image
    • The Linux Device Tree Blob (DTB)
    • The bitstream file for the Programmable Logic (PL).
    • The read/write UBIFS root filesystem.

The resulting flash memory layout is illustrated in the following pictures.

NAND flash partitioning scheme

In essence, the bootstrap sequence looks like this:

  • U-Boot fetches and programs the PL bitstream
  • Then it fetches the Linux kernel binary images (kernel and DTB) from the on-board NAND flash memory
  • The Linux kernel mount the root filesystem from a NAND partition.
Testbed[edit | edit source]

This configuration was tested with the following testbed:

  • SOM: DBTD4111I0R
  • carrier board: EVBBX0000C0R
  • software: BELK 4.1.0

Program the root filesystem in NAND flash[edit | edit source]

This step can be followed in the same way as described before

Program the boot images in NAND flash from U-Boot[edit | edit source]

It is assumed that the following U-Boot's environment variables are defined:

fdt_base=0x00780000
fpga_base=0x00180000
kernel_base=0x00800000
loadk=tftpboot ${loadaddr} ${bootfile}
loadfdt=tftpboot ${fdtaddr} ${fdtfile}
loadfpga=tftpboot ${loadaddr} ${fpgafile}
nand_updatek=nand erase.part kernel; nand write ${loadaddr} kernel ${filesize}
nand_updatefdt=nand erase.part fdt; nand write ${fdtaddr} fdt ${filesize}
nand_updatefpga=nand erase.part fpga; nand write ${loadaddr} fpga ${filesize}
nand_loadk=nand read ${loadaddr} kernel
nand_loadfdt=nand read ${fdtaddr} fdt
nand_loadfpga=nand read ${loadaddr} fpga
nand_programfpga=run nand_loadfpga; fpga load 0 ${loadaddr} 0x${filesize}
  • Update the bootfile, fdtfile and fpgafile environment variables to fit the filename as found inside the TFTP server.
  • Program kernel and device tree on NAND flash with the following U-Boot command
Bora> run loadfpga nand_updatefpga loadk nand_updatek loadfdt nand_updatefdt

E.g.:

Bora> run loadfpga nand_updatefpga loadk nand_updatek loadfdt nand_updatefdt
Using ethernet@e000b000 device
TFTP from server 192.168.0.13; our IP address is 192.168.0.90
Filename 'bora/belk-4.1.0_bora_BASE_fpga.bin'.
Load address: 0x2080000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ###########
         1.3 MiB/s
done
Bytes transferred = 4045564 (3dbafc hex)

NAND erase.part: device 0 offset 0x180000, size 0x600000
Erasing at 0x760000 -- 100% complete.
OK

NAND write: device 0 offset 0x180000, size 0x3dbafc
 4045564 bytes written: OK
Using ethernet@e000b000 device
TFTP from server 192.168.0.13; our IP address is 192.168.0.90
Filename 'bora/linux/belk-4.1.0_uImage'.
Load address: 0x2080000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ###########################
         1.3 MiB/s
done
Bytes transferred = 3796168 (39ecc8 hex)

NAND erase.part: device 0 offset 0x800000, size 0x800000
Erasing at 0xfe0000 -- 100% complete.
OK

NAND write: device 0 offset 0x800000, size 0x39ecc8
 3796168 bytes written: OK
Using ethernet@e000b000 device
TFTP from server 192.168.0.13; our IP address is 192.168.0.90
Filename 'bora/linux/belk-4.1.0_bora.dtb'.
Load address: 0x2000000
Loading: ##
         655.3 KiB/s
done
Bytes transferred = 10073 (2759 hex)

NAND erase.part: device 0 offset 0x780000, size 0x80000
Erasing at 0x7e0000 -- 100% complete.
OK

NAND write: device 0 offset 0x780000, size 0x2759
 10073 bytes written: OK
Bora>

In U-Boot environment please verify that the following default variables are set in order to be able to boot from NAND

nandargs=setenv bootargs ubi.mtd=7 root=ubi0_0 rootfstype=ubifs rw
mtdparts=mtdparts=pl35x-nand:256K(spl),768K(uboot),256K(env1),256K(env2),6M(fpga),512K(fdt),8M(kernel),-(nand-ubi)
addmisc=setenv bootargs ${bootargs} cma=16M ${mtdparts}
nand_nand=run nand_programfpga nand_loadk nand_loadfdt nandargs addcons addmisc; bootm ${loadaddr} - ${fdtaddr}

Reboot the system and configure U-Boot to apply the new configuration

=> setenv bootcmd run nand_nand
=> saveenv

Program the boot images in NAND flash from Linux[edit | edit source]

  • Get kernel and device tree images with the following tftp commands

E.g.:

root@bora:~# tftp -g -r bora/linux/belk-4.1.0_uImage 192.168.0.23
root@bora:~# tftp -g -r bora/linux/belk-4.1.0_bora.dtb 192.168.0.23
root@bora:~# tftp -g -r bora/belk-4.1.0_bora_BASE_fpga.bin 192.168.0.23
root@bora:~# ls -la
root@bora:~# ls -la
drwxr-xr-x    2 root     root          4096 Mar  5  2021 .
drwxrwxrwx    6 root     root          4096 Mar  5  2021 ..
-rw-r--r--    1 root     root         10073 Mar  5  2021 belk-4.1.0_bora.dtb
-rw-r--r--    1 root     root       4045564 Mar  5  2021 belk-4.1.0_bora_BASE_fpga.bin
-rw-r--r--    1 root     root       3796168 Mar  5  2021 belk-4.1.0_uImage
root@bora:~#
  • now the binary images have been retrieved form the tftp server (like the U-Boot tftp download)
  • check the mtd partitioning for identifying the proper /dev/mtdX device
root@bora:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00040000 00020000 "nand-SPL"
mtd1: 000c0000 00020000 "nand-uboot"
mtd2: 00040000 00020000 "nand-uboot-env1"
mtd3: 00040000 00020000 "nand-uboot-env2"
mtd4: 00600000 00020000 "nand-bitstream"
mtd5: 00080000 00020000 "nand-device-tree"
mtd6: 00800000 00020000 "nand-linux"
mtd7: 1f000000 00020000 "nand-rootfs"
root@bora:~#

It is possible to see the mtd partition for the NAND flash: i.e. mtd4 for the fpga bitstream, mtd5 for the device tree and mtd6 for the kernel

  • using the mtd partitioning, program the binary images in the proper /dev/mtdX device
  • the mtd-utils commands flash_erase and nandwrite can be used for this purposes: see here for more information
root@bora:~# flash_erase --help
Usage: flash_erase [options] MTD_DEVICE <start offset> <block count>
Erase blocks of the specified MTD device.
Specify a count of 0 to erase to end of device.

  -j, --jffs2       format the device for jffs2
  -N, --noskipbad   don't skip bad blocks
  -u, --unlock      unlock sectors before erasing
  -q, --quiet       do not display progress messages
      --silent      same as --quiet
      --help        display this help and exit
      --version     output version information and exit
root@bora:~# nandwrite --help
Usage: nandwrite [OPTION] MTD_DEVICE [INPUTFILE|-]
Writes to the specified MTD device.

  -a, --autoplace         Use auto OOB layout
  -m, --markbad           Mark blocks bad if write fails
  -n, --noecc             Write without ecc
  -N, --noskipbad         Write without bad block skipping
  -o, --oob               Input contains oob data
  -O, --onlyoob           Input contains oob data and only write the oob part
  -s addr, --start=addr   Set output start address (default is 0)
  -p, --pad               Pad writes to page size
  -b, --blockalign=1|2|4  Set multiple of eraseblocks to align to
      --input-skip=length Skip |length| bytes of the input file
      --input-size=length Only read |length| bytes of the input file
  -q, --quiet             Don't display progress messages
  -h, --help              Display this help and exit
      --version           Output version information and exit
root@bora:~#
  • program the binary images in each mtd device
root@bora:~# flash_erase /dev/mtd4 0 0
Erasing 128 Kibyte @ 5e0000 -- 100 % complete
root@bora:~# nandwrite -p /dev/mtd4 belk-4.1.0_bora_BASE_fpga.bin
Writing data to block 0 at offset 0x0
Writing data to block 1 at offset 0x20000
Writing data to block 2 at offset 0x40000
Writing data to block 3 at offset 0x60000
Writing data to block 4 at offset 0x80000
Writing data to block 5 at offset 0xa0000
Writing data to block 6 at offset 0xc0000
Writing data to block 7 at offset 0xe0000
Writing data to block 8 at offset 0x100000
Writing data to block 9 at offset 0x120000
Writing data to block 10 at offset 0x140000
Writing data to block 11 at offset 0x160000
Writing data to block 12 at offset 0x180000
Writing data to block 13 at offset 0x1a0000
Writing data to block 14 at offset 0x1c0000
Writing data to block 15 at offset 0x1e0000
Writing data to block 16 at offset 0x200000
Writing data to block 17 at offset 0x220000
Writing data to block 18 at offset 0x240000
Writing data to block 19 at offset 0x260000
Writing data to block 20 at offset 0x280000
Writing data to block 21 at offset 0x2a0000
Writing data to block 22 at offset 0x2c0000
Writing data to block 23 at offset 0x2e0000
Writing data to block 24 at offset 0x300000
Writing data to block 25 at offset 0x320000
Writing data to block 26 at offset 0x340000
Writing data to block 27 at offset 0x360000
Writing data to block 28 at offset 0x380000
Writing data to block 29 at offset 0x3a0000
Writing data to block 30 at offset 0x3c0000
root@bora:~# flash_erase /dev/mtd5 0 0
Erasing 128 Kibyte @ 60000 -- 100 % complete
root@bora:~# nandwrite -p /dev/mtd5 belk-4.1.0_bora.dtb
Writing data to block 0 at offset 0x0
root@bora:~# flash_erase /dev/mtd6 0 0
Erasing 128 Kibyte @ 7e0000 -- 100 % complete
root@bora:~# nandwrite -p /dev/mtd6 belk-4.1.0_uImage
Writing data to block 0 at offset 0x0
Writing data to block 1 at offset 0x20000
Writing data to block 2 at offset 0x40000
Writing data to block 3 at offset 0x60000
Writing data to block 4 at offset 0x80000
Writing data to block 5 at offset 0xa0000
Writing data to block 6 at offset 0xc0000
Writing data to block 7 at offset 0xe0000
Writing data to block 8 at offset 0x100000
Writing data to block 9 at offset 0x120000
Writing data to block 10 at offset 0x140000
Writing data to block 11 at offset 0x160000
Writing data to block 12 at offset 0x180000
Writing data to block 13 at offset 0x1a0000
Writing data to block 14 at offset 0x1c0000
Writing data to block 15 at offset 0x1e0000
Writing data to block 16 at offset 0x200000
Writing data to block 17 at offset 0x220000
Writing data to block 18 at offset 0x240000
Writing data to block 19 at offset 0x260000
Writing data to block 20 at offset 0x280000
Writing data to block 21 at offset 0x2a0000
Writing data to block 22 at offset 0x2c0000
Writing data to block 23 at offset 0x2e0000
Writing data to block 24 at offset 0x300000
Writing data to block 25 at offset 0x320000
Writing data to block 26 at offset 0x340000
Writing data to block 27 at offset 0x360000
Writing data to block 28 at offset 0x380000
root@bora:~#
  • once rebooted, configure U-Boot to apply the new configuration in NAND
...
...
Hit ENTER within 3 seconds to stop autoboot
Bora> setenv bootcmd 'run nand_nand'
Bora> saveenv
Saving Environment to SPI Flash...
SF: Detected s25fl256s_64k with page size 256 Bytes, erase size 64 KiB, total 64 MiB
Erasing SPI flash...Writing to SPI flash...done
Valid environment: 1
Bora> 
  • the system is then ready to boot retrieving the storage binary images from NAND
Bora> boot
NAND read: device 0 offset 0x180000, size 0x600000
 6291456 bytes read: OK

NAND read: device 0 offset 0x800000, size 0x800000
 8388608 bytes read: OK

NAND read: device 0 offset 0x780000, size 0x80000
 524288 bytes read: OK
## Booting kernel from Legacy Image at 02080000 ...
   Image Name:   Linux-4.9.0-belk-4.1.0-xilinx
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3796104 Bytes = 3.6 MiB
   Load Address: 00008000
   Entry Point:  00008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 02000000
   Booting using the fdt blob at 0x2000000
   Loading Kernel Image ... OK
   Loading Device Tree to 1effa000, end 1efff758 ... OK
Switching to NAND storage before starting Linux

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.9.0-belk-4.1.0-xilinx (jenkins@linuxserver2) (gcc version 6.2.1 20161016 (Linaro GCC 6.2-2016.11) ) #1 SMP PREEMPT Tue Dec 24 11:34:28 CET 2019
[    0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] OF: fdt:Machine model: Bora
[    0.000000] bootconsole [earlycon0] enabled
[    0.000000] cma: Reserved 16 MiB at 0x3f000000
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] On node 0 totalpages: 262144
[    0.000000] free_area_init_node: node 0, pgdat c0a2ddc0, node_mem_map ef7f7000
[    0.000000]   Normal zone: 1536 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 196608 pages, LIFO batch:31
...
...

Full bootstrap procedure[edit | edit source]

For the reader's convenience, the following box shows the full bootstrap procedure (please, click on the "Expand" link):

U-Boot SPL 2017.01-belk-4.1.1 (Jan 08 2020 - 16:52:16)
nand boot
Trying to boot from NAND
1024 MiB


U-Boot 2017.01-belk-4.1.1 (Jan 08 2020 - 16:52:16 +0100), Build: belk-4.1.1

Model: Bora
Board: Xilinx Zynq
I2C:   ready
DRAM:  ECC disabled 1 GiB
Relocating to 3ff14000, new gd at 3ead3ee8, sp at 3ead3ec0
NAND:  1024 MiB
MMC:   sdhci@e0100000: 0 (SD)
In:    serial@e0001000
Out:   serial@e0001000
Err:   serial@e0001000
Model: Bora
Board: Xilinx Zynq
SOM ConfigID#: 00000008
SOM UniqueID#: 01234567:89abcdef
CB ConfigID CRC mismatch for 0x00000000 (was 0x00000000, expected 0x2144df1c) at block 3 (offset 96): using default
CB ConfigID#: ffffffff
CB UniqueID#: 00000000:00000000
Net:   ZYNQ GEM: e000b000, phyaddr 7, interface rgmii-id
eth0: ethernet@e000b000
Hit ENTER within 3 seconds to stop autoboot

NAND read: device 0 offset 0x180000, size 0x600000
 6291456 bytes read: OK

NAND read: device 0 offset 0x800000, size 0x800000
 8388608 bytes read: OK

NAND read: device 0 offset 0x780000, size 0x80000
 524288 bytes read: OK
## Booting kernel from Legacy Image at 02080000 ...
   Image Name:   Linux-4.9.0-belk-4.1.0-xilinx
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3796104 Bytes = 3.6 MiB
   Load Address: 00008000
   Entry Point:  00008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 02000000
   Booting using the fdt blob at 0x2000000
   Loading Kernel Image ... OK
   Loading Device Tree to 1effa000, end 1efff758 ... OK
Switching to NAND storage before starting Linux

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.9.0-belk-4.1.0-xilinx (jenkins@linuxserver2) (gcc version 6.2.1 20161016 (Linaro GCC 6.2-2016.11) ) #1 SMP PREEMPT Tue Dec 24 11:34:28 CET 2019
[    0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] OF: fdt:Machine model: Bora
[    0.000000] bootconsole [earlycon0] enabled
[    0.000000] cma: Reserved 16 MiB at 0x3f000000
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] On node 0 totalpages: 262144
[    0.000000] free_area_init_node: node 0, pgdat c0a2ddc0, node_mem_map ef7f7000
[    0.000000]   Normal zone: 1536 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 196608 pages, LIFO batch:31
[    0.000000]   HighMem zone: 65536 pages, LIFO batch:15
[    0.000000] percpu: Embedded 14 pages/cpu @ef7d2000 s26124 r8192 d23028 u57344
[    0.000000] pcpu-alloc: s26124 r8192 d23028 u57344 alloc=14*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260608
[    0.000000] Kernel command line: ubi.mtd=7 root=ubi0_0 rootfstype=ubifs rw console=ttyPS0,115200n8 debug earlyprintk cma=16M mtdparts=pl35x-nand:256K(spl),768K(uboot),256K(env1),256K(env2),6M(fpga),512K(fdt),8M(kernel),-(nand-ubi)
[    0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
[    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
[    0.000000] Memory: 1012740K/1048576K available (6144K kernel code, 234K rwdata, 1532K rodata, 1024K init, 323K bss, 19452K reserved, 16384K cma-reserved, 245760K highmem)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xf0800000 - 0xff800000   ( 240 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xf0000000   ( 768 MB)
[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0700000   (7136 kB)
[    0.000000]       .init : 0xc0900000 - 0xc0a00000   (1024 kB)
[    0.000000]       .data : 0xc0a00000 - 0xc0a3aa38   ( 235 kB)
[    0.000000]        .bss : 0xc0a3aa38 - 0xc0a8b834   ( 324 kB)
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000]  Build-time adjustment of leaf fanout to 32.
[    0.000000]  RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=2
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] efuse mapped to f0802000
[    0.000000] slcr mapped to f0804000
[    0.000000] L2C: platform modifies aux control register: 0x02060000 -> 0x02460000
[    0.000000] L2C: DT/platform modifies aux control register: 0x02060000 -> 0x02460000
[    0.000000] L2C-310 erratum 769419 enabled
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
[    0.000000] L2C-310 cache controller enabled, 8 ways, 512 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x46460001
[    0.000000] zynq_clock_init: clkc starts at f0804100
[    0.000000] Zynq clock init
[    0.000000] ps_clk frequency not specified, using 33 MHz.
[    0.000011] sched_clock: 64 bits at 333MHz, resolution 3ns, wraps every 4398046511103ns
[    0.007869] clocksource: arm_global_timer: mask: 0xffffffffffffffff max_cycles: 0x4ce07af025, max_idle_ns: 440795209040 ns
[    0.018886] Switching to timer-based delay loop, resolution 3ns
[    0.024888] clocksource: ttc_clocksource: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 537538477 ns
[    0.033935] timer #0 at f080c000, irq=17
[    0.038267] Console: colour dummy device 80x30
[    0.042597] Calibrating delay loop (skipped), value calculated using timer frequency.. 666.66 BogoMIPS (lpj=3333333)
[    0.053077] pid_max: default: 32768 minimum: 301
[    0.057856] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.064361] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.071995] CPU: Testing write buffer coherency: ok
[    0.076917] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[    0.082505] Setting up static identity map for 0x100000 - 0x100058
[    0.258338] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
[    0.258442] Brought up 2 CPUs
[    0.266978] SMP: Total of 2 processors activated (1333.33 BogoMIPS).
[    0.273357] CPU: All CPU(s) started in SVC mode.
[    0.278942] devtmpfs: initialized
[    0.285309] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
[    0.293073] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.303701] pinctrl core: initialized pinctrl subsystem
[    0.310076] NET: Registered protocol family 16
[    0.316253] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.358392] cpuidle: using governor ladder
[    0.398350] cpuidle: using governor menu
[    0.415353] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers.
[    0.423248] hw-breakpoint: maximum watchpoint size is 4 bytes.
[    0.429192] zynq-ocm f800c000.ocmc: ZYNQ OCM pool: 256 KiB @ 0xf0880000
[    0.436053] zynq-pinctrl 700.pinctrl: zynq pinctrl initialized
[    0.456378] vgaarb: loaded
[    0.459737] SCSI subsystem initialized
[    0.463985] usbcore: registered new interface driver usbfs
[    0.470006] usbcore: registered new interface driver hub
[    0.475316] usbcore: registered new device driver usb
[    0.481323] pps_core: LinuxPPS API ver. 1 registered
[    0.486156] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    0.495401] PTP clock support registered
[    0.501389] clocksource: Switched to clocksource arm_global_timer
[    0.522421] NET: Registered protocol family 2
[    0.527491] TCP established hash table entries: 8192 (order: 3, 32768 bytes)
[    0.534572] TCP bind hash table entries: 8192 (order: 4, 65536 bytes)
[    0.541005] TCP: Hash tables configured (established 8192 bind 8192)
[    0.547324] UDP hash table entries: 512 (order: 2, 16384 bytes)
[    0.553249] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)
[    0.559717] NET: Registered protocol family 1
[    0.564419] RPC: Registered named UNIX socket transport module.
[    0.570203] RPC: Registered udp transport module.
[    0.574963] RPC: Registered tcp transport module.
[    0.579663] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.586132] PCI: CLS 0 bytes, default 64
[    0.590711] hw perfevents: enabled with armv7_cortex_a9 PMU driver, 7 counters available
[    0.600381] futex hash table entries: 512 (order: 3, 32768 bytes)
[    0.607298] workingset: timestamp_bits=30 max_order=18 bucket_order=0
[    0.614340] jffs2: version 2.2. (NAND) (SUMMARY)  © 2001-2006 Red Hat, Inc.
[    0.622267] bounce: pool size: 64 pages
[    0.625984] io scheduler noop registered
[    0.629938] io scheduler deadline registered
[    0.634284] io scheduler cfq registered (default)
[    0.641598] dma-pl330 f8003000.dmac: Loaded driver for PL330 DMAC-241330
[    0.648161] dma-pl330 f8003000.dmac:         DBUFF-128x8bytes Num_Chans-8 Num_Peri-4 Num_Events-16
[    0.657287] e0000000.serial: ttyPS1 at MMIO 0xe0000000 (irq = 145, base_baud = 3125000) is a xuartps
[    0.666733] e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 146, base_baud = 3125000) is a xuartps
à[    0.675856] console [ttyPS0] enabled
[    0.675856] console [ttyPS0] enabled
[    0.682949] bootconsole [earlycon0] disabled
[    0.682949] bootconsole [earlycon0] disabled
[    0.692174] xdevcfg f8007000.devcfg: ioremap 0xf8007000 to f086f000
[    0.699073] [drm] Initialized
[    0.714985] brd: module loaded
[    0.725471] loop: module loaded
[    0.730823] libphy: Fixed MDIO Bus: probed
[    0.737912] libphy: mdio_driver_register: xgmiitorgmii
[    0.743111] CAN device driver interface
[    0.749380] libphy: MACB_mii_bus: probed
[    0.852145] macb e000b000.ethernet eth0: Cadence GEM rev 0x00020118 at 0xe000b000 irq 148 (00:50:c2:1e:af:e0)
[    0.862019] Micrel KSZ9031 Gigabit PHY e000b000.etherne:07: attached PHY driver [Micrel KSZ9031 Gigabit PHY] (mii_bus:phy_addr=e000b000.etherne:07, irq=-1)
[    0.876204] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
[    0.881981] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    0.888875] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.895372] ehci-pci: EHCI PCI platform driver
[    0.899915] usbcore: registered new interface driver usb-storage
[    0.906105] e0002000.usb supply vbus not found, using dummy regulator
[    0.912795] ULPI transceiver vendor/product ID 0x0424/0x0006
[    0.918368] Found SMSC USB331x ULPI transceiver.
[    0.923003] ULPI integrity check: passed.
[    0.928808] mousedev: PS/2 mouse device common for all mice
[    0.934751] i2c /dev entries driver
[    0.938424] cdns-i2c e0004000.i2c: 100 kHz mmio e0004000 irq 142
[    0.948144] rtc-ds3232 0-0068: rtc core: registered ds3232 as rtc0
[    0.955792] ina2xx 0-0041: power monitor ina226 (Rshunt = 10000 uOhm)
[    0.962591] tmp421 0-004f: Could not read configuration register (-6)
[    0.970543] cpufreq: cpufreq_online: CPU0: Running at unlisted freq: 666666 KHz
[    0.977828] cpufreq: cpufreq_online: CPU0: Unlisted initial frequency changed to: 666667 KHz
[    0.986424] Xilinx Zynq CpuIdle Driver started
[    0.991294] sdhci: Secure Digital Host Controller Interface driver
[    0.997421] sdhci: Copyright(c) Pierre Ossman
[    1.001749] sdhci-pltfm: SDHCI platform and OF driver helper
[    1.061455] mmc0: SDHCI controller on e0100000.sdhci [e0100000.sdhci] using DMA
[    1.069084] usbcore: registered new interface driver usbhid
[    1.075634] usbhid: USB HID core driver
[    1.082573] nand: device found, Manufacturer ID: 0xef, Chip ID: 0xd3
[    1.088843] nand: Unknown W29N08GV
[    1.092292] nand: 1024 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    1.100596] Bad block table found at page 524224, version 0x01
[    1.107676] Bad block table found at page 524160, version 0x01
[    1.114266] 8 cmdlinepart partitions found on MTD device pl35x-nand
[    1.120470] Creating 8 MTD partitions on "pl35x-nand":
[    1.125608] 0x000000000000-0x000000040000 : "spl"
[    1.142605] 0x000000040000-0x000000100000 : "uboot"
[    1.158482] 0x000000100000-0x000000140000 : "env1"
[    1.174374] 0x000000140000-0x000000180000 : "env2"
[    1.184974] mmc0: new high speed SDHC card at address 59b4
[    1.190236] 0x000000180000-0x000000780000 : "fpga"
[    1.201439] 0x000000780000-0x000000800000 : "fdt"
[    1.205848] mmcblk0: mmc0:59b4 USDU1 14.9 GiB
[    1.211140]  mmcblk0: p1 p2
[    1.211772] 0x000000800000-0x000001000000 : "kernel"
[    1.222910] 0x000001000000-0x000040000000 : "nand-ubi"
[    1.247391] NET: Registered protocol family 17
[    1.251856] can: controller area network core (rev 20120528 abi 9)
[    1.258008] NET: Registered protocol family 29
[    1.262407] can: raw protocol (rev 20120528)
[    1.266628] can: broadcast manager protocol (rev 20161123 t)
[    1.272303] can: netlink gateway (rev 20130117) max_hops=1
[    1.278132] Registering SWP/SWPB emulation handler
[    1.288204] ubi0: attaching mtd7
[    6.527574] ubi0: scanning is finished
[    6.559907] ubi0: attached mtd7 (name "nand-ubi", size 1008 MiB)
[    6.565877] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[    6.572720] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[    6.579380] ubi0: VID header offset: 512 (aligned 512), data offset: 2048
[    6.586165] ubi0: good PEBs: 8060, bad PEBs: 4, corrupted PEBs: 0
[    6.592244] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
[    6.599432] ubi0: max/mean erase counter: 4/2, WL threshold: 4096, image sequence number: 857573235
[    6.608473] ubi0: available PEBs: 0, total reserved PEBs: 8060, PEBs reserved for bad PEB handling: 156
[    6.617868] ubi0: background thread "ubi_bgt0d" started, PID 679
[    6.618911] rtc-ds3232 0-0068: hctosys: unable to read the hardware clock
[    6.632658] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 681
[    6.715428] UBIFS (ubi0:0): recovery needed
[    6.965346] UBIFS (ubi0:0): recovery completed
[    6.969793] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "rootfs"
[    6.977129] UBIFS (ubi0:0): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[    6.987017] UBIFS (ubi0:0): FS size: 1016967168 bytes (969 MiB, 7882 LEBs), journal size 33546240 bytes (31 MiB, 260 LEBs)
[    6.998035] UBIFS (ubi0:0): reserved for root: 4952683 bytes (4836 KiB)
[    7.004636] UBIFS (ubi0:0): media format: w4/r0 (latest is w4/r0), UUID 0D33F80E-E80A-43F7-BE9E-C2D24C4FCD14, small LPT model
[    7.017320] VFS: Mounted root (ubifs filesystem) on device 0:12.
[    7.025315] devtmpfs: mounted
[    7.031335] Freeing unused kernel memory: 1024K (c0900000 - c0a00000)
INIT: version 2.88 booting
Starting udev
[    9.081287] udevd[710]: starting version 3.2
[    9.111284] random: udevd: uninitialized urandom read (16 bytes read)
[    9.122792] random: udevd: uninitialized urandom read (16 bytes read)
[    9.129255] random: udevd: uninitialized urandom read (16 bytes read)
[    9.176143] udevd[711]: starting eudev-3.2
[    9.321128] random: udevd: uninitialized urandom read (16 bytes read)
[   10.176226] random: dd: uninitialized urandom read (512 bytes read)
Mon Dec 30 23:37:37 UTC 2019
INIT: Entering runlevel: 5
Configuring network interfaces... udhcpc (v1.24.1) started
Sending discover...
[   12.601808] macb e000b000.ethernet eth0: link up (100/Full)
Sending discover...
Sending discover...
No lease, forking to background
done.
Starting system message bus: [   19.305403] random: dbus-daemon: uninitialized urandom read (12 bytes read)
[   19.405678] random: dbus-daemon: uninitialized urandom read (12 bytes read)
dbus.
Starting Dropbear SSH server: [   19.538175] random: dropbear: uninitialized urandom read (32 bytes read)
dropbear.
Starting rpcbind daemon...done.
starting statd: done
Starting atd: OK
exportfs: can't open /etc/exports for reading
NFS daemon support not enabled in kernel
Starting system log daemon...0
Starting kernel log daemon...0
Starting internet superserver: xinetd.
 * Starting Avahi mDNS/DNS-SD Daemon: avahi-daemon
[   20.449120] random: avahi-daemon: uninitialized urandom read (4 bytes read)
[   20.551133] random: avahi-daemon: uninitialized urandom read (4 bytes [ ok ]
Starting crond: OK
Starting tcf-agent: OK

Poky (Yocto Project Reference Distro) 2.2.1 bora /dev/ttyPS0

bora login: root
root@bora:~#

Use case #3[edit | edit source]

Introduction[edit | edit source]

This example makes use of the partitioning scheme illustrated in the following images.


NOR flash partitioning scheme


NAND flash partitioning scheme


In this case, the NOR flash is only used to store U-Boot and its environment. All the other images are stored onto the NAND flash. Specifically, the NAND flash has four partitions that are used to store respectively:

  • The uImage binary image, which, in turn, consists of the Linux kernel and a initramfs image, as per PetaLinux's default configuration.
    • This partition is associated with the device file /dev/mtd0
  • The PL bitstream
    • This partition is associated with the device file /dev/mtd1
  • The Device Tree Blob
    • This partition is associated with the device file /dev/mtd2
  • An auxiliary read/write filesystem used by the user-space applications for several purposes such as data logging
    • This partition is associated with the device file /dev/mtd3.

The resulting bootstrap sequence is like the following:

  1. U-Boot is retrieved from the NOR flash and copied into the SDRAM memory
  2. U-boot, in turn, reads from the NAND memory the uImage, the bitstream, the DTB, and copies them into the SDRAM memory
  3. U-Boot starts the Linux kernel
  4. Finally, the Linux kernel mounts the root filesystem from the SDRAM memory and starts user-space applications and daemons.

It is worth remembering that mtd0,mtd1, and mtd2 are used as raw partitions while mtd3 is associated with a block device in order to mount a filesystem, specifically UBIFS. To handle such filesystem, the Linux kernel must be built with the UBI/UBIFS support enabled and the root filesystem must include the mtd-utils-ubifs package (see the following image).


Selecting the mtd-utils-ubifs package in PataLinux root filesystem configuration


To setup the desired standalone configuration, several operations need to be carried out. They are detailed in the following sections. It is assumed that the SOM can boot from the NOR flash. If not, please see this page.

Testbed[edit | edit source]

The testbed used to test this configuration consists of the following boards:

  • SOM: DBXD4110S2R
  • Carrier board: EVBBX0000C0R
  • Software: BXELK 4.0.0 + PetaLinux 2017.1

Storing the images onto the raw partitions of the NAND memory[edit | edit source]

Before storing the images into the NAND flash, the bitstream must be converted. For more details, please refer to this page:

$ python /devel/dave/bora-DBRx/fpga/fpga-bit-to-bin.py -f bitstream.bit bitstream.bin
Design name: prj1;UserID=0XFFFFFFFF;Version=2017.4
Partname 7z030sbg485
Date 2019/02/01
Time 16:38:59
found binary data: 5979916


Once the U-Boot console is available, the binary files to be stored into the NAND flash can be downloaded via TFTP. The size of the partitions illustrated in the previous image determine the offsets to use with the nand erase/write commands. The following box shows the full procedure.

The first file to be stored is uImage:

Bora> nand info

Device 0: nand0, sector size 128 KiB
  Page size       2048 b
  OOB size          64 b
  Erase size    131072 b
  subpagesize      512 b
  options     0x       0
  bbt options 0x   20000
Bora> tftpboot ${loadaddr} borax/uImage
Using ethernet@e000b000 device
TFTP from server 192.168.0.13; our IP address is 192.168.0.81
Filename 'borax/uImage'.
Load address: 0x2080000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##################################################
         2.5 MiB/s
done
Bytes transferred = 9904184 (972038 hex)
Bora> nand erase 0 3000000

NAND erase: device 0 offset 0x0, size 0x3000000
Erasing at 0x2fe0000 -- 100% complete.
OK
Bora> nand write ${loadaddr} 0 ${filesize}

NAND write: device 0 offset 0x0, size 0x972038
 9904184 bytes written: OK
Bora>


Downloading and flashing of the bitstream file:

Bora> tftpboot ${loadaddr} borax/bitstream.bin
Using ethernet@e000b000 device
TFTP from server 192.168.0.13; our IP address is 192.168.0.81
Filename 'borax/bitstream.bin'.
Load address: 0x2080000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ###############################################################
         2.5 MiB/s
done
Bytes transferred = 5979916 (5b3f0c hex)
Bora> nand erase 3000000 f00000

NAND erase: device 0 offset 0x3000000, size 0xf00000
Erasing at 0x3ee0000 -- 100% complete.
OK
Bora> nand write ${loadaddr} 3000000 ${filesize}

NAND write: device 0 offset 0x3000000, size 0x5b3f75
 5980021 bytes written: OK


Downloading and flashing of the DTB:

Bora> tftpboot ${loadaddr} borax/bora.dtb
Using ethernet@e000b000 device
TFTP from server 192.168.0.13; our IP address is 192.168.0.81
Filename 'borax/bora.dtb'.
Load address: 0x2080000
Loading: ###
         746.1 KiB/s
done
Bytes transferred = 15280 (3bb0 hex)
Bora> nand erase 3f00000 100000

NAND erase: device 0 offset 0x3f00000, size 0x100000
Erasing at 0x3fe0000 -- 100% complete.
OK
Bora> nand write ${loadaddr} 3f00000 ${filesize}

NAND write: device 0 offset 0x3f00000, size 0x3bb0
 15280 bytes written: OK

Setting up the U-Boot environment[edit | edit source]

In order to boot the system as desired, the U-Boot environment must be configured properly. The most important variable is nandboot2 that can be created as follows:

Bora> setenv nandboot2 'run program_fpga2 loadunand loadfdtnand nandargs2 addip addcons addmisc; run configid_fixupfdt; bootm ${loadaddr} - ${fdtaddr}'
Bora> savee
Saving Environment to SPI Flash...
SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 32 MiB
Erasing SPI flash...Writing to SPI flash...done
Valid environment: 1


Another important variable that needs to be changed is mtdparts. It must be set like this in order to tell the kernel how the NAND flash is partitioned:

mtdparts=mtdparts=pl35x-nand:48M(data0),15M(data1),1M(data2),-(data3)


Similarly, other variables need to be created such as loadunand and loadfdtnand. The resulting environment should look like this:

Bora> print
DBXx_test_result=test_passed
addcons=setenv bootargs ${bootargs} console=${console},115200n8 debug earlyprintk
addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gateway}:${netmask}:${hostname}:${ethdev}
addmisc=setenv bootargs ${bootargs} cma=16M ${mtdparts}
baudrate=115200
bootaddr=0x101100
bootargs=ip=192.168.0.81:192.168.0.13:192.168.0.254:255.255.255.0:bora:eth0 console=ttyPS0,115200n8 debug earlyprintk cma=16M mtdparts=pl35x-nand:48M(data0),15M(data1),1M(data2),-(data3)
bootcmd=run nandboot2
bootdelay=3
bootfile=bora/linux/belk-4.0.0_uImage
bootscript=echo Running bootscript from ${recoverydev} ...; source ${loadaddr}
cb_configid#=ffffffff
cb_uniqueid#=00000000:00000000
configid_fixupfdt=if configid checkfdt ${fdtaddr} som_configid ${som_configid#}; then configid fdt_uniqueid ${fdtaddr}; fi
console=ttyPS0
ethact=ethernet@e000b000
ethaddr=00:50:C2:1E:AF:B3
ethdev=eth0
fdt_base=0x00780000
fdt_high=0x1F000000
fdtaddr=1f00000
fdtcontroladdr=3ffa0a90
fdtfile=bora/linux/belk-4.0.0_bora.dtb
fpga_base=0x00180000
fpgafile=bora/bora.bin
fsbl_base=0x40000
gateway=192.168.0.254
header_base=0
hostname=bora
ipaddr=192.168.0.81
jtag_vx=run vxargs; bootvx 0x200000
kernel_base=0x00800000
load=tftpboot ${loadaddr} bora/u-boot.bin
loadaddr=0x02080000
loadbootscript=fatload ${recoverydev} 0:1 ${loadaddr} ${script};
loadfdt=tftpboot ${fdtaddr} ${fdtfile}
loadfdtnand=nand read ${fdtaddr} 3f00000 100000
loadfpga=tftpboot ${loadaddr} ${fpgafile}
loadfpga2=nand read ${loadaddr} 3000000 f00000
loadfsbl=tftpboot ${loadaddr} bora/bora_fsbl.bin
loadhdr=tftpboot ${loadaddr} bora/boot_header
loadk=tftpboot ${loadaddr} ${bootfile}
loadunand=nand read ${loadaddr} 0 3000000
loadvx=tftpboot ${loadaddr} ${vxfile}
mmcargs=setenv bootargs root=/dev/mmcblk0p${mmcpart} rootwait rw
mmcdev=0
mmcpart=2
mmcrecovery=mmc dev 0; mmc rescan; setenv recoverydev mmc; run recovery
modeboot=qspiboot
mtdids=nand0=pl353-nand
mtdparts=mtdparts=pl35x-nand:48M(data0),15M(data1),1M(data2),-(data3)
mtdparts1=mtdparts=pl353-nand:512K(spl),512K(uboot),256K(env1),256K(env2),4M(fpga),256K(fdt),4M(kernel),-(nand-ubi)
nand_loadk=nand read ${loadaddr} kernel
nand_updatek=nand erase.part kernel; nand write ${loadaddr} nand-kernel ${filesize}
nandargs=setenv bootargs ubi.mtd=7 root=ubi0_0 rootfstype=ubifs rw
nandargs2=setenv bootargs 'root=/dev/nfs rw nfsroot=${serverip}:${rootpath},tcp'
nandboot2=run program_fpga2 loadunand loadfdtnand nandargs2 addip addcons addmisc; run configid_fixupfdt; bootm ${loadaddr} - ${fdtaddr}
net_nfs=ping ${serverip};run loadk loadfdt nfsargs addip addcons addmisc; run configid_fixupfdt; bootm ${loadaddr} - ${fdtaddr}
net_vx=run loadvx vxargs; bootvx ${loadaddr}
netmask=255.255.255.0
nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath},tcp
normalboot=net_nfs
program_fpga=run loadfpga;fpga load 0 ${loadaddr} 0x${filesize}
program_fpga2=run loadfpga2; fpga load 0 ${loadaddr} f00000
qspiboot=echo Booting from QSPI: use net_nfs && run net_nfs
ramdisk_size=0x200000
recovery=if run loadbootscript; then run bootscript; fi
rootpath=/opt/nfsroot/bora/belk-4.0.0
script=boot.scr
serial#_DBXx=00C5
serverip=192.168.0.13
som_configid#=00000005
som_uniqueid#=3a11013a:40b52447
stderr=serial@e0001000
stdin=serial@e0001000
stdout=serial@e0001000
u-boot_base=0x80000
update=sf probe 0 0 0;sf erase ${u-boot_base} +${filesize};sf write ${loadaddr} ${u-boot_base} ${filesize}
updatefdt=sf probe 0 0 0;sf erase ${fdt_base} +${filesize};sf write ${fdtaddr} ${fdt_base} ${filesize}
updatefpga=sf probe 0 0 0;sf erase ${fpga_base} +${filesize};sf write ${loadaddr} ${fpga_base} ${filesize}
updatefsbl=sf probe 0 0 0;sf erase ${fsbl_base} +${filesize};sf write ${loadaddr} ${fsbl_base} ${filesize}
updatehdr=sf probe 0 0 0;sf erase ${header_base} +${filesize};sf write ${loadaddr} ${header_base} ${filesize}
updatek=sf probe 0 0 0;sf erase ${kernel_base} +${filesize};sf write ${loadaddr} ${kernel_base} ${filesize}
usbrecovery=usb start; usb dev 0; setenv recoverydev usb; run recovery
vxargs=setenv bootargs gem(0,0)host:vxWorks.st h=${serverip} e=${ipaddr} g=${gatewayip} tn=${hostname} u=target pw=vxTarget f=0x0
vxfile=bora/vxWorks

Environment size: 4342/262139 bytes


Please note that the variable bootcmd is set to run the desired boot sequence (nandboot2).

Formatting the fourth partition of the NAND memory (mtd3)[edit | edit source]

After setting up the U-Boot environment, it is possible to start a full bootstrap sequence by issuing the boot command. Please refer to this section to see the dump of the serial console during the full bootstrap sequence.

Once the system has completed the bootstrap procedure, it is possible to format the mtd3 partition in order to store a UBIFS filesystem.

First of all, check that the NAND's partitions are defined properly:

root@bora-ubi:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 03000000 00020000 "data0"
mtd1: 00f00000 00020000 "data1"
mtd2: 00100000 00020000 "data2"
mtd3: 3c000000 00020000 "data3"


To format the partition and to mount the newly created filesystem, issue the following commands:

root@bora-ubi:~# ubiformat /dev/mtd3
ubiformat: mtd3 (nand), size 1006632960 bytes (960.0 MiB), 7680 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 7679 -- 100 % complete
ubiformat: 7676 eraseblocks have valid erase counter, mean value is 0
ubiformat: 4 bad eraseblocks found, numbers: 7676, 7677, 7678, 7679
ubiformat: formatting eraseblock 7679 -- 100 % complete
root@bora-ubi:~# ubiattach -m 3
[ 6543.803993] ubi0: attaching mtd3
[ 6549.149717] ubi0: scanning is finished
[ 6549.180746] ubi0: attached mtd3 (name "data3", size 960 MiB)
[ 6549.186339] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[ 6549.194291] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[ 6549.201006] ubi0: VID header offset: 512 (aligned 512), data offset: 2048
[ 6549.207708] ubi0: good PEBs: 7676, bad PEBs: 4, corrupted PEBs: 0
[ 6549.213824] ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
[ 6549.221038] ubi0: max/mean erase counter: 2/1, WL threshold: 4096, image sequence number: 2065859155
[ 6549.232175] ubi0: available PEBs: 7516, total reserved PEBs: 160, PEBs reserved for bad PEB handling: 156
[ 6549.244741] ubi0: background thread "ubi_bgt0d" started, PID 1456
UBI device number 0, total 7676 LEBs (990388224 bytes, 944.5 MiB), available 7516 LEBs (969744384 bytes, 924.8 MiB), LEB size 129024 bytes (126.0 KiB)
root@bora-ubi:~# ubimkvol /dev/ubi0 -N data3 -m
Set volume size to 969744384
Volume ID 0, size 7516 LEBs (969744384 bytes, 924.8 MiB), LEB size 129024 bytes (126.0 KiB), dynamic, name "data3", alignment 1
root@bora-ubi:~# mkdir -p /mnt/data3
root@bora-ubi:~# mount -t ubifs ubi0_0 /mnt/data3
[ 6634.342953] UBIFS (ubi0:0): default file-system created
[ 6634.349787] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 1473
[ 6634.536639] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "data3"
[ 6634.543901] UBIFS (ubi0:0): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[ 6634.553858] UBIFS (ubi0:0): FS size: 967421952 bytes (922 MiB, 7498 LEBs), journal size 33546240 bytes (31 MiB, 260 LEBs)
[ 6634.564767] UBIFS (ubi0:0): reserved for root: 4952683 bytes (4836 KiB)
[ 6634.571363] UBIFS (ubi0:0): media format: w4/r0 (latest is w4/r0), UUID 8B1F86F2-F2C3-4292-845F-77D3BF3E212A, small LPT model


It is now possible to verify that the filesystem was mounted properly:

root@bora-ubi:~# mount
rootfs on / type rootfs (rw)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
devtmpfs on /dev type devtmpfs (rw,relatime,size=503536k,nr_inodes=125884,mode=755)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
tmpfs on /var/volatile type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620,ptmxmode=000)
ubi0_0 on /mnt/data3 type ubifs (rw,relatime)


As expected, the available space on the ubi0_0 is less than the raw size of the partition:

root@bora-ubi:~# df
Filesystem           1K-blocks      Used Available Use% Mounted on
devtmpfs                503536         0    503536   0% /dev
tmpfs                   515312        36    515276   0% /run
tmpfs                   515312        40    515272   0% /var/volatile
ubi0_0                  887868        16    883016   0% /mnt/data3

Full bootstrap procedure[edit | edit source]

For the reader's convenience, the following box shows the full bootstrap procedure (please, click on the "Expand" link):

U-Boot SPL 2017.01-belk-4.0.1 (Jul 13 2017 - 16:08:49)
qspi boot
Trying to boot from SPI


U-Boot 2017.01-belk-4.0.1 (Jul 13 2017 - 16:08:49 +0200), Build: jenkins-BELK_u-boot-11

Model: Bora
Board: Xilinx Zynq
I2C:   ready
DRAM:  ECC disabled 1 GiB
Relocating to 3ff2e000, new gd at 3eaedee8, sp at 3eaedec0
NAND:  1024 MiB
MMC:   Card did not respond to voltage select!
Card did not respond to voltage select!
sdhci@e0100000 - probe failed: -95
Card did not respond to voltage select!

SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 32 MiB
In:    serial@e0001000
Out:   serial@e0001000
Err:   serial@e0001000
Model: Bora
Board: Xilinx Zynq
SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 32 MiB
SF: Detected s25fl128s_64k with page size 256 Bytes, erase size 64 KiB, total 32 MiB
SOM ConfigID#: 00000005
SOM UniqueID#: 3a11013a:40b52447
ds2431_readmem(): error in chip reset
ds2431_readmem(): error in reading buffer
ds2431_readmem(): error in chip reset
ds2431_readmem(): error in reading buffer
CB ConfigID CRC mismatch for 0x00000000 (was 0x00000000, expected 0x2144df1c) at block 3 (offset 96): using default
CB ConfigID#: ffffffff
CB UniqueID#: 00000000:00000000
Net:   ZYNQ GEM: e000b000, phyaddr 7, interface rgmii-id
eth0: ethernet@e000b000
Hit ENTER within 3 seconds to stop autoboot

NAND read: device 0 offset 0x3000000, size 0xf00000
 15728640 bytes read: OK

NAND read: device 0 offset 0x0, size 0x3000000
 50331648 bytes read: OK

NAND read: device 0 offset 0x3f00000, size 0x100000
 1048576 bytes read: OK
FDT: property som_configid FDT: override 'som_configid' with '00000005'
FDT: override 'som_uniqueid' with '3a11013a:40b52447'
FDT: override 'cb_uniqueid' with '00000000:00000000'
## Booting kernel from Legacy Image at 02080000 ...
   Image Name:   Linux-4.9.0-belk-4.0.0-xilinx
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    9904120 Bytes = 9.4 MiB
   Load Address: 00008000
   Entry Point:  00008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 01f00000
   Booting using the fdt blob at 0x1f00000
   Loading Kernel Image ... OK
   Loading Device Tree to 1effa000, end 1efff996 ... OK
Switching to NAND storage before starting Linux

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.9.0-belk-4.0.0-xilinx (dvdk@osboxes) (gcc version 6.2.1 20161016 (Linaro GCC 6.2-2016.11) ) #4 SMP PREEMPT Tue Mar 5 10:27:41 CET 2019
[    0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] OF: fdt:Machine model: Bora
[    0.000000] bootconsole [earlycon0] enabled
[    0.000000] cma: Reserved 16 MiB at 0x3f000000
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] On node 0 totalpages: 262144
[    0.000000] free_area_init_node: node 0, pgdat c102d8c0, node_mem_map ef7f7000
[    0.000000]   Normal zone: 1536 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 196608 pages, LIFO batch:31
[    0.000000]   HighMem zone: 65536 pages, LIFO batch:15
[    0.000000] percpu: Embedded 14 pages/cpu @ef7d1000 s26124 r8192 d23028 u57344
[    0.000000] pcpu-alloc: s26124 r8192 d23028 u57344 alloc=14*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260608
[    0.000000] Kernel command line: root=/dev/nfs rw nfsroot=${serverip}:${rootpath},tcp ip=192.168.0.81:192.168.0.13:192.168.0.254:255.255.255.0:bora:eth0 console=ttyPS0,115200n8 debug earlyprintk cma=16M mtdparts=pl35x-nand:48M(data0),15M(data1),1M(data2),-(data3)
[    0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
[    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
[    0.000000] Memory: 1007072K/1048576K available (6144K kernel code, 232K rwdata, 1576K rodata, 7168K init, 323K bss, 25120K reserved, 16384K cma-reserved, 245760K highmem)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xf0800000 - 0xff800000   ( 240 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xf0000000   ( 768 MB)
[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0700000   (7136 kB)
[    0.000000]       .init : 0xc0900000 - 0xc1000000   (7168 kB)
[    0.000000]       .data : 0xc1000000 - 0xc103a2e0   ( 233 kB)
[    0.000000]        .bss : 0xc103a2e0 - 0xc108b0f4   ( 324 kB)
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000]  Build-time adjustment of leaf fanout to 32.
[    0.000000]  RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=2
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] efuse mapped to f0802000
[    0.000000] slcr mapped to f0804000
[    0.000000] L2C: platform modifies aux control register: 0x02060000 -> 0x02460000
[    0.000000] L2C: DT/platform modifies aux control register: 0x02060000 -> 0x02460000
[    0.000000] L2C-310 erratum 769419 enabled
[    0.000000] L2C-310 enabling early BRESP for Cortex-A9
[    0.000000] L2C-310 full line of zeros enabled for Cortex-A9
[    0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled
[    0.000000] L2C-310 cache controller enabled, 8 ways, 512 kB
[    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x46460001
[    0.000000] zynq_clock_init: clkc starts at f0804100
[    0.000000] Zynq clock init
[    0.000000] ps_clk frequency not specified, using 33 MHz.
[    0.000011] sched_clock: 64 bits at 333MHz, resolution 3ns, wraps every 4398046511103ns
[    0.007866] clocksource: arm_global_timer: mask: 0xffffffffffffffff max_cycles: 0x4ce07af025, max_idle_ns: 440795209040 ns
[    0.018884] Switching to timer-based delay loop, resolution 3ns
[    0.024886] clocksource: ttc_clocksource: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 537538477 ns
[    0.033933] timer #0 at f080c000, irq=17
[    0.038249] Console: colour dummy device 80x30
[    0.042577] Calibrating delay loop (skipped), value calculated using timer frequency.. 666.66 BogoMIPS (lpj=3333333)
[    0.053057] pid_max: default: 32768 minimum: 301
[    0.057838] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.064341] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.071972] CPU: Testing write buffer coherency: ok
[    0.076891] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[    0.082480] Setting up static identity map for 0x100000 - 0x100058
[    0.238338] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
[    0.238441] Brought up 2 CPUs
[    0.246981] SMP: Total of 2 processors activated (1333.33 BogoMIPS).
[    0.253360] CPU: All CPU(s) started in SVC mode.
[    0.258930] devtmpfs: initialized
[    0.265358] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
[    0.273121] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.283743] pinctrl core: initialized pinctrl subsystem
[    0.290081] NET: Registered protocol family 16
[    0.296286] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.338362] cpuidle: using governor ladder
[    0.378348] cpuidle: using governor menu
[    0.394845] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers.
[    0.402735] hw-breakpoint: maximum watchpoint size is 4 bytes.
[    0.408680] zynq-ocm f800c000.ocmc: ZYNQ OCM pool: 256 KiB @ 0xf0880000
[    0.415532] zynq-pinctrl 700.pinctrl: zynq pinctrl initialized
[    0.435803] vgaarb: loaded
[    0.439188] SCSI subsystem initialized
[    0.443427] usbcore: registered new interface driver usbfs
[    0.448889] usbcore: registered new interface driver hub
[    0.454202] usbcore: registered new device driver usb
[    0.460236] pps_core: LinuxPPS API ver. 1 registered
[    0.465075] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    0.474261] PTP clock support registered
[    0.498445] clocksource: Switched to clocksource arm_global_timer
[    0.518806] NET: Registered protocol family 2
[    0.523753] TCP established hash table entries: 8192 (order: 3, 32768 bytes)
[    0.530869] TCP bind hash table entries: 8192 (order: 4, 65536 bytes)
[    0.537296] TCP: Hash tables configured (established 8192 bind 8192)
[    0.543630] UDP hash table entries: 512 (order: 2, 16384 bytes)
[    0.549530] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)
[    0.556004] NET: Registered protocol family 1
[    0.560678] RPC: Registered named UNIX socket transport module.
[    0.566459] RPC: Registered udp transport module.
[    0.571228] RPC: Registered tcp transport module.
[    0.575919] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.582400] PCI: CLS 0 bytes, default 64
[    1.102945] hw perfevents: enabled with armv7_cortex_a9 PMU driver, 7 counters available
[    1.112338] futex hash table entries: 512 (order: 3, 32768 bytes)
[    1.119158] workingset: timestamp_bits=30 max_order=18 bucket_order=0
[    1.126156] jffs2: version 2.2. (NAND) (SUMMARY)  c 2001-2006 Red Hat, Inc.
[    1.133986] bounce: pool size: 64 pages
[    1.137708] io scheduler noop registered
[    1.141742] io scheduler deadline registered
[    1.145977] io scheduler cfq registered (default)
[    1.153301] dma-pl330 f8003000.dmac: Loaded driver for PL330 DMAC-241330
[    1.159920] dma-pl330 f8003000.dmac:         DBUFF-128x8bytes Num_Chans-8 Num_Peri-4 Num_Events-16
[    1.169000] e0000000.serial: ttyPS1 at MMIO 0xe0000000 (irq = 145, base_baud = 3125000) is a xuartps
[    1.178412] e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 146, base_baud = 3125000) is a xuartps
à[    1.187538] console [ttyPS0] enabled
[    1.187538] console [ttyPS0] enabled
[    1.194636] bootconsole [earlycon0] disabled
[    1.194636] bootconsole [earlycon0] disabled
[    1.203842] xdevcfg f8007000.devcfg: ioremap 0xf8007000 to f086f000
[    1.210771] [drm] Initialized
[    1.226747] brd: module loaded
[    1.237253] loop: module loaded
[    1.242684] libphy: Fixed MDIO Bus: probed
[    1.249767] CAN device driver interface
[    1.256030] libphy: MACB_mii_bus: probed
[    1.359199] macb e000b000.ethernet eth0: Cadence GEM rev 0x00020118 at 0xe000b000 irq 148 (00:50:c2:1e:af:b3)
[    1.369069] Micrel KSZ9031 Gigabit PHY e000b000.etherne:07: attached PHY driver [Micrel KSZ9031 Gigabit PHY] (mii_bus:phy_addr=e000b000.etherne:07, irq=-1)
[    1.383239] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
[    1.389008] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    1.395903] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    1.402401] ehci-pci: EHCI PCI platform driver
[    1.406934] usbcore: registered new interface driver usb-storage
[    1.413140] e0002000.usb supply vbus not found, using dummy regulator
[    1.419839] ULPI transceiver vendor/product ID 0x0424/0x0006
[    1.425414] Found SMSC USB331x ULPI transceiver.
[    1.430048] ULPI integrity check: passed.
[    1.435825] mousedev: PS/2 mouse device common for all mice
[    1.441733] i2c /dev entries driver
[    1.445407] cdns-i2c e0004000.i2c: 100 kHz mmio e0004000 irq 142
[    1.458675] rtc-ds3232 0-0068: rtc core: registered ds3232 as rtc0
[    1.466248] ina2xx 0-0041: power monitor ina226 (Rshunt = 10000 uOhm)
[    1.474606] Xilinx Zynq CpuIdle Driver started
[    1.479492] sdhci: Secure Digital Host Controller Interface driver
[    1.485582] sdhci: Copyright(c) Pierre Ossman
[    1.489994] sdhci-pltfm: SDHCI platform and OF driver helper
[    1.548509] mmc0: SDHCI controller on e0100000.sdhci [e0100000.sdhci] using DMA
[    1.556145] usbcore: registered new interface driver usbhid
[    1.562699] usbhid: USB HID core driver
[    1.569627] nand: device found, Manufacturer ID: 0xef, Chip ID: 0xd3
[    1.575932] nand: Unknown W29N08GV
[    1.579320] nand: 1024 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    1.587634] Bad block table found at page 524224, version 0x01
[    1.594713] Bad block table found at page 524160, version 0x01
[    1.601301] 4 cmdlinepart partitions found on MTD device pl35x-nand
[    1.607504] Creating 4 MTD partitions on "pl35x-nand":
[    1.612653] 0x000000000000-0x000003000000 : "data0"
[    1.630900] 0x000003000000-0x000003f00000 : "data1"
[    1.636915] 0x000003f00000-0x000004000000 : "data2"
[    1.642873] 0x000004000000-0x000040000000 : "data3"
[    1.656664] NET: Registered protocol family 17
[    1.662102] can: controller area network core (rev 20120528 abi 9)
[    1.668256] NET: Registered protocol family 29
[    1.672658] can: raw protocol (rev 20120528)
[    1.676874] can: broadcast manager protocol (rev 20161123 t)
[    1.682548] can: netlink gateway (rev 20130117) max_hops=1
[    1.688386] Registering SWP/SWPB emulation handler
[    1.707302] rtc-ds3232 0-0068: setting system clock to 2019-03-05 11:36:06 UTC (1551785766)
[    4.838753] macb e000b000.ethernet eth0: link up (1000/Full)
[    4.898465] IP-Config: Complete:
[    4.901612]      device=eth0, hwaddr=00:50:c2:1e:af:b3, ipaddr=192.168.0.81, mask=255.255.255.0, gw=192.168.0.254
[    4.911871]      host=bora, domain=, nis-domain=(none)
[    4.916971]      bootserver=192.168.0.13, rootserver=192.168.0.13, rootpath=
[    4.924277] Warning: unable to open an initial console.
[    4.950584] Freeing unused kernel memory: 7168K (c0900000 - c1000000)
[    5.765125] udevd[688]: starting version 3.2
[    5.770394] random: udevd: uninitialized urandom read (16 bytes read)
[    5.776981] random: udevd: uninitialized urandom read (16 bytes read)
[    5.783499] random: udevd: uninitialized urandom read (16 bytes read)
[    5.799662] udevd[689]: starting eudev-3.2
[    5.833892] random: udevd: uninitialized urandom read (16 bytes read)
[    6.769401] random: dd: uninitialized urandom read (512 bytes read)
[   11.480222] random: fast init done
[   27.774344] NET: Registered protocol family 10

PetaLinux 2017.2 bora-ubi /dev/ttyPS0

bora-ubi login:

Additional notes[edit | edit source]

  • mtd0, mtd1, and mtd2 are significantly larger than the files they store used in this example. This allows having a spare room to store larger images. For the sake of simplicity, U-Boot was configured to read the whole partitions (see how the loadunand, loadfdtnand, and loadfpga2 variables are defined). Obviously, this affect the overall boot time negatively. To optimize it, these variables have to be changed in order to read just the required amount of data according to the size of the actual stored files.
  • As stated previously, the root filesystem is initramfs and thus not persistent. Consequently, every time the system boots, the directory /mnt/data3 must be created before mounting the UBIFS file system stored in the NAND flash.



How to configure the network interfaces[edit | edit source]

For deploying an Embedded System, one of the most important configuration is the Network Interface configuration.

Once the Embedded Device is finally configured for stand-alone bootstrap, the network interface should be configured for reaching the device remotely via network connections like ssh, telnet, ftp, http, etc.

This Application Note briefly describes how it is possible to simply configure the network interfaces on SystemV (aka SysV) or systemd

Resources[edit | edit source]

For further details on network configuration, please refer - for example - to:

Examples[edit | edit source]

The following configuration assumptions are used in the paragraphs shown below:

  • IP address range of the LAN network 192.168.1.0 - 192.168.1.255
  • IP address of the gateway 192.168.1.254
  • IP address of the device 192.168.1.100

SysV[edit | edit source]

The configuration files for SysV can be found in pre-defined directorys as written here

Basically, for network configuration, it should be enough to properly configure the /etc/network/interfaces file.

# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)

Here below an example of configuration file:

Static IP address[edit | edit source]

The network interface is configured with a static IP address by creating the configuration entry in the /etc/network/interfaces file as the following:

auto eth0
iface eth0 inet static
 address 192.168.1.100
 netmask 255.255.255.0
 gateway 192.168.1.254

Dynamic IP addres (DHCP)[edit | edit source]

The network interface is configured - using a proper DHCP server on the network - by creating the configuration entry in the /etc/network/interfaces file as the following:

allow-hotplug eth0
iface eth0 inet dhcp

When the Linux kernel detects the physical interface eth0, the iface causes ifup to use DHCP to configure the interface.

DNS[edit | edit source]

If the resolvconf package is not installed, the DNS configuration can be done manually by editing the /etc/resolv.conf as the following:

nameserver 192.168.1.1

For example, it can be done on the command line echoing the string in this way:

root@axel-lite:~# echo "nameserver 192.168.1.1" > /etc/resolv.conf

loopback network interface[edit | edit source]

The following configuration entry in the /etc/network/interfaces file brings up the loopback network interface lo upon booting the system.

# The loopback interface
auto lo
iface lo inet loopback

This one always exists in the /etc/network/interfaces file.

systemd[edit | edit source]

The network configuration for systemd are basically found in the /etc/systemd/network/ directory.

The most simply way for configuring the network interface is to create/edit the file /etc/systemd/network/20-eth0.network as per the following paragraphs.

For more example and usage hints on systemd, please refer to our wiki page.

Static IP address[edit | edit source]

[Match]
Name=eth0

# Prevent the interface loading if the kernel boots from nfs
KernelCommandLine=!nfsroot

[Network]
Address=192.168.1.100
Gateway=192.168.1.254
DNS=192.168.1.1

Once modified, the networkd service should be resarted:

systemctl restart systemd-networkd

Dynamic IP addres (DHCP)[edit | edit source]

The network interface is configured - using a proper DHCP server on the network - by using the DHCP key in the configuration file as the following:

[Match]
Name=eth0

# Prevent the interface loading if the kernel boots from nfs
KernelCommandLine=!nfsroot

[Network]
DHCP=yes

When systemd network starts, it tries to use a DHCP server present in the network to configure the interface.

DNS[edit | edit source]

The DNS key (in the configuration file) is used only if the systemd-resolved service is enabled and the /etc/resolv.conf has a symbolic link to /run/systemd/resolve/stub-resolv.conf

ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

Once modified, the resolved service should be resarted:

systemctl restart systemd-resolved

loopback network interface[edit | edit source]

systemd contains native implementations of various tasks that need to be executed as part of the boot process.

For example, it sets the hostname or configures the loopback network device.

Apply configuration changes[edit | edit source]

After editing the above files, changes are applied after reboot or by restarting systemd-networkd.service:

root@imx6qdlxelk:~# systemctl restart systemd-networkd.service

Peripherals[edit | edit source]

Console UART[edit | edit source]

Kit Physical device Processor's resource Connector Type Linux device file Notes
BELK Boot Console UART1 J17 2-wire RS232 UART /dev/ttyPS0
BXELK Boot Console UART1 J17 2-wire RS232 UART /dev/ttyPS0



Ethernet[edit | edit source]

Ethernet port is associated to eth0 interface on the J8 connector. It can be managed with standard Linux commands. See for example http://www.tecmint.com/ifconfig-command-examples/.

LED[edit | edit source]

The two LEDs, connected to the ethernet PHY are configured as Tri-color dual-LED mode (see more info in the KSZ9031 datasheet): link/activity for 100mbit/s and link/activity/ for 1000mbit/s.




microSD card[edit | edit source]

microSD card on connector J21, if present, will be associated by the Linux kernel to the mmcblk0 device:

[   24.100643] mmc0: new high speed SDHC card at address 1234
[   24.106544] mmcblk0: mmc0:1234 SA16G 14.6 GiB
[   24.113268]  mmcblk0: p1 p2

Once detected, it can be mounted and accessed via usual Linux commands:

root@bora:~# mount /dev/mmcblk0p1 /mnt/mmcblk0p1/
root@bora:~# time cp LibreOffice_4.1.1_Win_x86.msi /mnt/mmcblk0p1/

real    0m39.971s
user    0m0.080s
sys     0m4.120s
root@bora:~# ls -la /mnt/mmcblk0p1/LibreOffice_4.1.1_Win_x86.msi
-rwxr-xr-x    1 root     root     215056384 Nov 15 15:57 /mnt/mmcblk0p1/LibreOffice_4.1.1_Win_x86.msi
root@bora:~# umount /mnt/mmcblk0p1/
root@bora:~#



CAN[edit | edit source]

See CAN Pinout page and BXELK Vivado project for more details.

Physical device Processor's resource Connector Type Notes
CAN BUS can0 J24 differential CAN bus

The following commands can be issued from command line in order to send and receive CAN frames:

root@bora:~# dmesg | grep -i can
[    0.643798] CAN device driver interface
[    0.997787] can: controller area network core (rev 20120528 abi 9)
[    1.008392] can: raw protocol (rev 20120528)
[    1.012661] can: broadcast manager protocol (rev 20120528 t)
[    1.018294] can: netlink gateway (rev 20130117) max_hops=1
root@bora:~# canconfig can0 stop
can0 state: STOPPED
root@bora:~# canconfig can0 bitrate 500000
can0 bitrate: 500000, sample-point: 0.875
root@bora:~# canconfig can0 start
can0 state: ERROR-ACTIVE
root@bora:~# cansend can0 -i 0x77 0x33 0x88 0x33 0x88 0x33 0x88 0x33
interface = can0, family = 29, type = 3, proto = 1
root@bora:~# cansend can0 -i 0x77 0x33 0x88 0x33 0x88 0x33 0x88 0x33
interface = can0, family = 29, type = 3, proto = 1
root@bora:~# cansend can0 -i 0x77 0x33 0x88 0x33 0x88 0x33 0x88 0x33
interface = can0, family = 29, type = 3, proto = 1
root@bora:~# candump can0
interface = can0, family = 29, type = 3, proto = 1
<0x100> [8] 12 34 56 78 9a bc de ff
<0x100> [8] 12 34 56 78 9a bc de ff
<0x100> [8] 12 34 56 78 9a bc de ff
<0x100> [8] 12 34 56 78 9a bc de ff
<0x100> [8] 12 34 56 78 9a bc de ff
^C
root@bora:~#

In case canutils package is missing, user can install it directly from DAVE's BORA package server using smart update && smart install canutils commands:

root@bora:~# smart update
Updating cache...               ######################################## [100%]

Fetching information for 'all'...
-> https://yocto.dave.eu/belk-3.0.1/all/repodata/repomd.xml
repomd.xml                      ######################################## [ 50%]
[snip]
Channels have 393 new packages.
Saving cache...

root@bora:~# smart install canutils
Loading cache...
Updating cache...               ######################################## [100%]

Computing transaction...

Installing packages (2):
  canutils-4.0.6-r0@armv7a_vfp_neon
  libsocketcan2-0.0.9-r0@armv7a_vfp_neon

27.8kB of package files are needed. 46.8kB will be used.

Confirm changes? (Y/n): y

[..snip..]

See Advanced use of Yocto build system for more information about using Yocto packages and smart



UART0[edit | edit source]

UART0 is a spare UART device available on the JP17 PMOD connector. This device is routed through the PL. See BXELK Vivado project for more details.

Physical device Processor's resource Connector Type Linux device file Notes
UART0 UART0 JP17 2-wire LVTTL UART /dev/ttyPS1



USB OTG[edit | edit source]

Host mode[edit | edit source]

For the USB Host mode an USB stick or another device must be pluged in at the system boot. See the issue related to USB not hotplug capable after the system boot.

This example shows how a memory stick is detected by the Linux kernel.

root@bora:~# [   37.340873] usb 1-1: new high-speed USB device number 2 using zynq-ehci
[   37.508377] usb 1-1: device v05e3 p0736 is not supported
[   37.514823] usb-storage 1-1:1.0: USB Mass Storage device detected
[   37.521869] scsi host0: usb-storage 1-1:1.0
[   38.522235] scsi 0:0:0:0: Direct-Access     Generic  STORAGE DEVICE   0272 PQ: 0 ANSI: 0
[   38.531274] sd 0:0:0:0: Attached scsi generic sg0 type 0
[   38.663662] sd 0:0:0:0: [sda] 30679040 512-byte logical blocks: (15.7 GB/14.6 GiB)
[   38.673145] sd 0:0:0:0: [sda] Write Protect is off
[   38.677862] sd 0:0:0:0: [sda] Mode Sense: 0b 00 00 08
[   38.684026] sd 0:0:0:0: [sda] No Caching mode page found
[   38.689257] sd 0:0:0:0: [sda] Assuming drive cache: write through
[   38.703539]  sda: sda1 sda2
[   38.715870] sd 0:0:0:0: [sda] Attached SCSI removable disk

To connect it to micro AB connector (J19), a cable like the one shown in the following picture has been used [1].

USB cable used to connect memory stick


Once mounted (at mnt/sda1 in the example), the memory stick can be accessed by regular commands:

root@bora:~# mount /dev/sda1 /mnt/sda1/
root@bora:~# mount
192.168.0.13:/opt/nfsroot/users/mgeromin/bora/belk on / type nfs (rw,relatime,vers=2,rsize=4096,wsize=4096,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.13,mountvers=1,mountproto=tcp,local_lock=all,addr=192.168.0.13)
devtmpfs on /dev type devtmpfs (rw,relatime,size=507916k,nr_inodes=126979,mode=755)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
tmpfs on /var/volatile type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620)
/dev/sda1 on /mnt/sda1 type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
root@bora:~# time cp LibreOffice_4.1.1_Win_x86.msi /mnt/sda1/

real    0m25.114s
user    0m0.010s
sys     0m4.070s
root@bora:~# umount /mnt/sda1/
root@bora:~# mount /dev/sda1 /mnt/sda1/
root@bora:~# md5sum LibreOffice_4.1.1_Win_x86.msi /mnt/sda1/LibreOffice_4.1.1_Win_x86.msi
4fa047c0590097ce201f49655365d772  LibreOffice_4.1.1_Win_x86.msi
4fa047c0590097ce201f49655365d772  /mnt/sda1/LibreOffice_4.1.1_Win_x86.msi
root@bora:~#

[1] This type of cables forces the ID signal of the USB port to be connected to ground, selecting the host mode on SBC Lynx side.

Device mode[edit | edit source]

The following examples shows how to configure Bora/BoraEVB or BoraX/BoraXEVB to act as a mass storage device.

First, a local file named mass is created to emulate a mass storage disk that is populated with a file named file.txt:

root@bora:~# dd if=/dev/zero of=mass count=16 bs=1M
16+0 records in
16+0 records out
root@bora:~# mkfs.ext3 mass
mke2fs 1.42.9 (28-Dec-2013)
mass is not a block special device.
Proceed anyway? (y,n) y
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
4096 inodes, 16384 blocks
819 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=16777216
2 block groups
8192 blocks per group, 8192 fragments per group
2048 inodes per group
Superblock backups stored on blocks:
        8193

Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
root@bora:~# mkdir loop
root@bora:~# mount -o loop mass loop
[   92.316783] kjournald starting.  Commit interval 5 seconds
[   92.316901] EXT3-fs (loop0): using internal journal
[   92.316908] EXT3-fs (loop0): mounted filesystem with writeback data mode
root@bora:~# echo dummy > loop/file.txt
root@bora:~# umount loop

Then the proper drivers are loaded on target side:

root@bora:~# modprobe g_mass_storage file=/home/root/mass
[  209.058156] Number of LUNs=8
[  209.061005] Mass Storage Function, version: 2009/09/11
[  209.066085] LUN: removable file: (no medium)
[  209.070349] Number of LUNs=1
[  209.073781] LUN: file: /home/root/mass
[  209.077444] Number of LUNs=1
[  209.080452] g_mass_storage gadget: Mass Storage Gadget, version: 2009/09/11
[  209.087381] g_mass_storage gadget: userspace failed to provide iSerialNumber
[  209.094393] g_mass_storage gadget: g_mass_storage ready
[  209.099572] zynq-udc: bind to driver g_mass_storage

Last, BoraEVB (or BoraXEVB) is connected to a Linux PC with a USB cable like this one:

USB cable used to connect BoraXEVB to PC


On PC side, BoraEVB (or BoraXEVB) is detected as a common USB mass storage device.



Temperature sensors[edit | edit source]

Bora SOM has a TMP421AIDCN temperature sensor onboard.

The following commands can be issued from command line in order to get the SOM temperatue:

  • read the PCB temperature
root@bora:~# cat /sys/devices/soc0/amba/e0004000.i2c/i2c-0/0-004f/hwmon/hwmon1/temp1_input

the returned value has to be divided by 1000 for a °C temperature

  • read the CPU temperature
root@bora:~# cat /sys/devices/soc0/amba/e0004000.i2c/i2c-0/0-004f/hwmon/hwmon1/temp2_input

the returned value has to be divided by 1000 for a °C temperature

Moreover, the SOC has an internal temperature sensor device which can be read using the following shell script:

root@bora:~# cat temp.sh
#!/bin/sh

# Tcpu
TEMP_RAW=`cat /sys/devices/soc0/amba/f8007100.adc/iio:device0/in_temp0_raw`
TEMP_OFFSET=`cat /sys/devices/soc0/amba/f8007100.adc/iio:device0/in_temp0_offset`
TEMP_SCALE=`cat /sys/devices/soc0/amba/f8007100.adc/iio:device0/in_temp0_scale`
TEMP=`awk "BEGIN {print (($TEMP_RAW+$TEMP_OFFSET)*$TEMP_SCALE)/1000}"`

echo "Cpu Temp: ${TEMP}"



Power consumption[edit | edit source]

Power consumption measure can be performed accessing the INA226 device connected to the I2C bus in the BoraEVB (U3). The following commands can be saved as a shell script (e.g. read_power_values) and run to collect the measurements data:

root@bora:~# cat read_power_values.sh
#!/bin/sh

path_dev=/sys/class/hwmon/hwmon0

IN1=`cat $path_dev/in1_input`
IN0=`cat $path_dev/in0_input`
VOLTAGE=`awk "BEGIN {print ($IN1-$IN0)/1000}"`
CURRENT=`cat $path_dev/curr1_input`
CURRENT=`awk "BEGIN {print ($CURRENT)/1000}"`
POWER=`cat $path_dev/power1_input`
POWER=`awk "BEGIN {print ($POWER)/1000000}"`
echo "Voltage: ${VOLTAGE}, Current: ${CURRENT}, Power:${POWER}"
root@bora:~# ./read_power_values.sh
Voltage: 3.308, Current: 0.64, Power:2.175
root@bora:~#