Digilent Arty board and Linux - Part 3 - Linux Kernel Image

 We created a basic FPGA system capable to run Linux in the Part 1 and generated the Device Tree file in the Part 2. At this time we will compile the Linux Kernel obtaining an image ready to be launched on our hardware synthesized into the Arty board.

 First thing we need is a computer running Linux, I always have some virtual machines to run with each OS depending on the task to perform. 

  • Install all needed dependencies for the compilation.
    sudo apt-get install build-essential bison flex gettext libncurses5-dev texinfo autoconf automake libtool
  • We need to include our device tree information so we create the board/arty folder and copy our artylinux.dts file into it.
    mkdir board/arty
    cp ../../artylinux.dts board/arty/
  • The next step is to define the kernel properties. This procedure can be done through different ways but the most graphical is to use the menuconfig option from the makefile. You can learn and play a lot searching on the internet. Here you can include packages, binaries or even package managers. Take into account that our Flash space is not too high (about 7MB), rememeber that we are into embedded world, not a general application computer ;)
    Here I present the selected properties to generate the _defconfig file. The _defconfig file is merely the text file with the output of the make menuconfig. 
            Target options
                    Target Architecture: Microblaze AXI (little endian)
                    Target Binary Format: ELF
            Build options
                            (wget --passive-ftp -nd -t 3) Wget command
                            (svn) Subversion (svn) command
                            (bzr) Bazaar (bzr) command
                            (git) Git command
                            (cvs) CVS command (NEW)
                            (tcp) Local files retrieval command (NEW)
                            (scp) Secure copy (scp) command (NEW)
                            (ssh) Secure shell (ssh) command (NEW)
                            (hg) Mercurial (hg) command (NEW)
                            (gzip -d -c) zcat command (NEW)
                            (bzcat) bzcat command (NEW)
                            (xzcat) xzcat command (NEW)
                            ()  Tar options (NEW)
                    ($(CONFIG_DIR)/defconfig) Location to save buildroot config
                    ($(TOPDIR)/dl) Download dir (NEW)
                    ($(BASE_DIR)/host) Host dir (NEW)
                    Mirrors and Download locations
                            (http://sources.buildroot.net) Backup download site (NEW)
                            (https://www.kernel.org/pub) Kernel.org mirror (NEW)
                            (http://ftp.gnu.org/pub/gnu) GNU Software mirror (NEW)
                            (http://rocks.moonscript.org) LuaRocks mirror (NEW)
                            (http://cpan.metacpan.org) CPAN mirror (Perl packages) (NEW)
                    (0) Number of jobs to run simultaneously (0 for auto) (NEW)
                    NO Enable compiler cache
                    NO Show options and packages that are deprecated
                    NO build packages with debugging symbols
                    strip command for binaries on target (strip)
                    () executables that should not be strupped
                    ()  directories that should be skipped when stripping (NEW)
                    gcc optimization level (optimize for size)
                    NO build code with Stack Smashing Protection (NEW)
                    libraries (shared only)
                    ($(CONFIG_DIR)/local.mk) location of a package override file (NEW)
                    ()  global patch directories
            Toolchain[*] Linux Kernel
                            Kernel version (4.3)
                            () Custom kernel patches (NEW)
                            Kernel configuration /Using a custom (def) config file)
                            (board/arty/artyLinux_defconfig) Configuration file path
                            () Additional configuration fragment files (NEW)
                            Kernel binary format (simpleImage)
                            -*- Build a Device Tree Blob (DTB)
                                    Device tree source (Use a custom device tree file)
                            (board/arty/artylinux.dts) Device Tree Source file paths
                            Linux Kernel Extensions
                            Linux Kernel Tools
            Target Packages
                    -*- BusyBox
                    (package/busybox/busybox.config) BusyBox configuration file to use? (NE$
                    ()    Additional BusyBox configuration fragment files (NEW)
                    [ ]   Show packages that are also provided by busybox (NEW)
                    [ ]   Enable SELinux support (NEW)
                    [ ]   Install the watchdog daemon startup script (NEW)
                    Audio and video applications  --->
                    Compressors and decompressors  --->
                    Debugging, profiling and benchmark  --->
                    Development tools  --->
                    Filesystem and flash utilities  --->
                    Fonts, icons, sounds and themes  --->
                    Games  --->
                    Graphic libraries and applications (graphic/text)  --->
                    Hardware handling  --->
                    Interpreter languages and scripting  --->
                    Libraries  --->
                    Mail  --->
                    Miscellaneous  --->
                    Networking applications  --->
                    Package managers  --->
                    Real-Time  ----
                    Security  --->
            Filesystem images
                    [ ] axfs root filesystem (NEW)
                    [ ] cloop root filesystem for the target device (NEW)
                    [ ] cpio the root filesystem (for use as an initial RAM filesystem) (NE$
                    [ ] cramfs root filesystem (NEW)
                    [ ] ext2/3/4 root filesystem (NEW)
                    *** initramfs needs a Linux kernel to be built ***
                    *** iso image needs a Linux kernel and one of grub, grub2 or isolinux t
                    [ ] jffs2 root filesystem (NEW)
                    [ ] romfs root filesystem (NEW)
                    [ ] squashfs root filesystem (NEW)
                    [*] tar the root filesystem (NEW)
                    Compression method (no compression)  --->
                    ()    other random options to pass to tar (NEW)
                    [ ] ubifs root filesystem (NEW)
                    [ ] yaffs2 root filesystem (NEW)
                    NO Bootloader
            Host Utilities
                    NO Host utilites
            Legacy config options
                    NO Legacy config options

 If you want to try my _defconfig file with my configuration, here are the generated files [first] [second].

  •  Locate each file in the following folders:
    • buildroot-2015.11/board/arty/artylinux_defconfig
    • buildroot-2015.11/configs/arty/artylinux_defconfig
  • From the buildroot-2015.11 root directory, type: 
    make arty_artylinux_defconfig

At this moment buildroot will do its magic. To download all dependencies, binutils, patches, gcc, etc, compile the crosstool, libs and compile the linux kernel.

The output binary file can be found at buildroot-2015.11/output/images/simpleImage.artylinux

The next step will be to load the image into the Arty board and to launch it, see it in the Part 4



Digilent Arty board and Linux - Part 2 - Linux Device Tree

We created a basic FPGA system capable to run Linux in the Part 1 around a Microblaze processor in a Xilinx Artix 7 FPGA (Arty evaluation board) and now it is time to build the Linux image.

For that task we are using Buildroot, an integrated tool to generate embedded Linux system including the generation of needed cross toolchain.

So the first thing we need to generate is the Linux Device Tree, which contains the hardware data needed by the booter and operative system to know how to deal with the created hardware. All memory map, existing buses, CPU details like cache configuration, interrupts or clock frequency, existing timers, UART modules details, etc.

  • To create our hardware we used IP cores from Xilinx, like AXI_Uartlite or the own Microblaze so we need to download the linux device tree for Xilinx, last version can be found in the following link. However I included the package file at the end containing used files.


    Extract device-tree-xlnx-master on Vivado project *.sdk subfolder.

  • On our Vivado project, go to File > Launch SDK. Once Eclipse is opened, go to Xilinx Tools > Repositories to include the new folder as a repository.
    Then click New ... and find the extracted folder.


  •  Go to File > New > Board Support Package and at the bottom, select device_tree. Default settings are ok to continue so click on Finish to create the project.
    A new window with the BSP settings is opened but with the default settings are enough to perform the example so click OK to go back to the Eclipse main view. In the future if you want to change the BSP settings you can double click to the .mss file and modify them.
    You can note the assigned drivers for each device:
    • axi_ethernetlite_0: emaclite
    • axi_timer_0: tmrctr
    • axi_uartlite_0: uartlite
    • microblaze_0_axi_intc: intc
    • microblaze_0_local_memory*: generic
    • mig_7series_0: mig_7series

It is time to create a .dts file containing the Linux Device Tree which will be included in the buildroot to build the kernel. We are going to merge the files "pl.dtsi" and "system.dts" created by the SDK.

  • Open the "pl.dtsi" and "system.dts" files. From the second one, copy the /dts-v1/; to the "pl.dtsi" file, previous to "/ {".
    In the same way, copy from "chosen {" to the closing "};" before the "cpus {" line. The result should look like the following screenshot.

Save the file as "artylinux.dts".

[PENDING] The MAC information for the ethernet interface needs to be located in the linux device tree in order to load the MAC address at the system start. I need to check where to put the information.


At this moment we have the Linux Device Tree for our created hardware, a file containing all needed information to compile and configure the booter and Linux kernel to be ran on our system.

The next step will be to compile the Linux kernel



[1] http://www.devicetree.org/specifications-pdf

[2] https://docs.numato.com/kb/neso-microblaze-linux-run-linux-neso-artix-7-fpga-module/

[3] https://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf


Syndicate content