Digilent Arty board and Linux - Part 5 - Storing FPGA, Linux and Bootloader into the QSPI Flash

In the previous post we were able to execute Linux over our synthesized system configuring manually the FPGA, loading through Microblaze the Linux image to the DDR3 memory and launching the execution of that image.

This is a good way to test if all the configuration was correct, but as soon as we power off the system, all the process needs to be done again and we want a system which runs Linux when powered, as we are used to.

To achieve that, we need to store the three things from the title: The FPGA configuration, Linux image and a Bootloader which copies that image to RAM and launches it.

The first thing we will do is to program the FPGA config file to the quad SPI flash device included in the Arty. It is a Micron N25Q128 powered at 3.3 V.
Previously (as default) the binary generated file was a .bit file which is to be programmed through JTAG. Now we will create a .bin file:

  • On Vivado, open the synthesis view, clicking over "Open Synthesized Design", then go to Tools > Edit Device Properties... and select these settings:
    • General > Enable Bitstream compression: YES
      In order to use less size
    • Configuration > Configuration Rate (MHz): 33 
      To improve the speed. The flash memory can manage up to 108 MHz so we have margin to avoid errors
    • Configuration Modes > Select Master SPI x4 option
      This is the way that our Flash is connected.
  • Now click on BitStream Settings and Select .bin file option

At this time you can regenerate the Bitstream. Open the Hardware Manager, it is our tool to program our devices, either FPGA or Flash. In order to recognize our Flash through the configuration interface of the Artix 7 FPGA:

  • Right click over our xc7a35t part and select Add Configuration Memory Device...
  • Search for the Micron N25Q128-3.3V* and select it. You will be asked to program the configuration memory device. Accept it or go later to that option right clicking over the appeared device on the Hardware list and select Program Configuration Memory Device...
  • Search for your .bin image and click over Program with these options


Great!! Now we know how to program the FPGA configuration file to the Flash memory. It is time to do the same with the Linux image, but the FPGA will not execute the Linux image by its own, this is the task of the Bootloader.


The Bootloader

The bootloader is a little standalone code which access to the Quad SPI Flash memory, copies desired code to the RAM and jumps into this code to execute it.

In Vivado SDK, in the same way that we have a 'Hello World' predefined example, Xilinx provides a SREC image format example bootloader. Unfortunately I converted the .bin image that we previously created to .srec and it becomes excessively large (about 17MB). In this way, I had to modify it to make the boot process with a .bin image.

My first idea was to post all needed steps to modify the Xilinx example to get the .bin bootloader but finally it took more changes than I expected so I am posting the bootloader.c file and I will explain the main keystones to use it and adapt to your requirements.

You can download it from here

It is not fully optimized so please do not blame me if you see unused variables or something like that. 

  • Go to Vivado > File > Launch SDK
  • In the SDK, create a new project going to File > New > Application Project
  • Input your project name (for example "Arty_boot") and click Next. Then select the "SREC SPI Bootloader" template.
  • Now you can overwrite your bootloader.c file with mine

There are only three things to take into account when using the bootloader.

  • In the SDK open the the generated *_bsp folder, right click over it and select Board Support Package Settings. At Overview > Standalone > xilisf settings, set the serial_flash_family value to 5. This defines that we have a Micron Quad SPI flash device.
  • Now in the bootloader project source folder, open the blconfig.h file and set the FLASH_IMAGE_BASEADDR define value. In my case I set 0x00501000, because my Flash memory map looks in this way:

Flash Content Start Address
(From 0x00000000)
End Address
(To 0x00FFFFFF)
.bit FPGA config file
.elf bootlader file
0x00000000 0x004FFFFF (5 MB)
.bin with Linux image 0x00501000 0x00DFFFFF (9 MB)
User Files 0x00E00000 0x00FFFFFF (2 MB)

The reason why the Linux image starts from 0x00501000 instead of 0x00500000 is because the .bin file first data is the own file metadata and the process to upload the .bin file to the Flash memory does not delete it.

  • Define the FLASH_IMAGE_SIZE in the bootloader.c source, in this case is 0x00900000 (9 MB) (In the file I uploaded its size is configured for 8 MB)
Generating ".mcs" file containing FPGA configuration, Bootloader and Linux Image
At this time we have these three parts, it is time to merge them into a single file.
  • In Vivado, open the Project Manager view and go to Tools > Associate ELF Files...
    For both, Design and Simulation Sources, search for the generated bootloader .elf file and regenerate the Bitstream sources. From this point the .bit file will contain the bootloader too and Microblaze will execute it on start.
  • Once it ends and you have your .bit file, go to Hardware Manager view and then go to Tools > Generate Memory Configuration File. This is an screenshot of my configuration. 

The FullImage.mcs is our key file :)

It only remains to put it into flash memory. Follow the same steps of the beginning of this post and select the FullImage.mcs file. The process will last a little as Flash image is not too quick writting, but after some minutes you will end.

Now open a terminal on the Arty Serial COM port and click on the Prog button (near the micro USB) to reload the FPGA config. The bootloader process will appear and after few seconds the Linux image will be booting :)




[1] http://www.xilinx.com/support/documentation/sw_manuals/xilinx2014_2/ug908-vivado-programming-debugging.pdf

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

[3] http://www.xilinx.com/support/answers/64238.html

[4] https://forums.xilinx.com/t5/Welcome-Join/Vivado-promgen-equivalent/td-p/482998

[5] https://forum.trenz-electronic.de/index.php?topic=288.0


Digilent Arty board and Linux - Part 4 - Synthesize, Load and Run

Well, at this point we have generated the FPGA system, we obtained the Linux kernel image using the the Device Tree of our hardware, it is time to synthesize the system on the FPGA, load Linux and run!

The whole process is going to be done from the SDK (Eclipse), so open the Xilinx Vivado Suite, and then open the Xilinx SDK.
The last thing we did here is to create the Device Tree but now we do not want to modify it so Close the device_tree_bsp_0 clicking right over it and closing the project.

Connect the Arty board to your computer and locate the virtual COM port that has been created. The JTAG commands go over the same USB physical connection but two devices are created, the JTAG Debug Port and the virtual COM, separately, so we can from now open the COM port from Putty or similar, at 115200 baud.

  • In the SDK, go to Xilinx Tools > Program FPGA. As we exported the SDK including bitstream, the hardware system wrapper is here configured. Click on Program and wait until the process finishes.

    At this time, the FPGA is configured and Microblaze is running nothing.

  • Copy your created Linux image to the .sdk project subfolder.
  • In the SDK now go to Xilinx Tools > XMD console. The XMD console allows us to connect with the microblaze and perform actions like stop the processor, restart it or copy data to Flash or RAM through JTAG. This is just what we will do, to copy our Linux image to RAM.
  • To connect with the target, into the XMD console window type
    connect mb mdm 

    the processor information should appear: 

    WARNING: Processor Version 0x23 - UnSupported Version, New Features May Not Work
    JTAG chain configuration
    Device   ID Code        IR Length    Part Name
     1       0362d093           6        xc7a35t
    MicroBlaze Processor Configuration :
    Version............................0x23 - UnSupported Version
    MMU Type...........................Full_MMU
    No of PC Breakpoints...............1
    No of Read Addr/Data Watchpoints...0
    No of Write Addr/Data Watchpoints..0
    Instruction Cache Support..........on
    Instruction Cache Base Address.....0x80000000
    Instruction Cache High Address.....0x8fffffff
    Data Cache Support.................on
    Data Cache Base Address............0x80000000
    Data Cache High Address............0x8fffffff
    Exceptions  Support................on
    FPU  Support.......................off
    Hard Divider Support...............on
    Hard Multiplier Support............on - (Mul64)
    Barrel Shifter Support.............on
    MSR clr/set Instruction Support....on
    Compare Instruction Support........on
    PVR Supported......................on
    PVR Configuration Type.............Full
    Data Cache Write-back Support......off
    Fault Tolerance Support............off
    Stack Protection Support...........off
    Connected to "mb" target. id = 0
    Starting GDB server for "mb" target (id = 0) at TCP port no 1234

  • Now find  your Linux image by typing "dir" and moving into directories using "cd directory" or "cd .."
  • Once located, type the following command, with your image name
    dow simpleImage.artylinux
  • After finishing the download, the processor keeps stopped. To run the uploaded image simply type
    con 0x80000000

Now you should see the linux booting on your previously opened terminal!!

As configured in our kernel compilation, the user is root and the password is password.


Setting up the Ethernet

Once logged in you can set up the ethernet port to be connected to the internet. Firstly we need to assign the device MAC address by typing the following sentence

ifconfig eth0 hw ether 00:11:22:33:44:55

And edit the /etc/network/interfaces file to include the eth0, keeping as follows

#interface file auto-generated by buildroot

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
# Comment avobe an uncomment below to set static IP
# iface eth0 inet static
#  address
#  netmask
#  gateway

 Finally it is time to turn on the ethernet link

ifup eth0



Take into account that all this process has been done entirely on RAM, when you shutdown the board you loose all the image and any change you did. We will need to upload the image to the Flash memory


Syndicate content