Introduction: Embedded Linux Tutorial - Zybo

This Embedded Linux hands-on tutorial for the Zybo will provide step-by-step instructions for customizing your hardware, compiling the Linux Kernel and writing driver and user applications. This documentation intends to integrate knowledge and skills in FPGA logic circuit design, standalone software programming, and Linux operating system and software development, and apply them to the Zybo.

In this tutorial, we will start from the Zybo Base System Design (available on the Zybo product page of the Digilent website). The system architecture for the Zybo Base System Design is shown in the first picture in this step.

In the Zybo Base System Design, we connect UART1 to USB-UART, SD0 to the SD Card Slot, USB0 to the USB-OTG port, Enet0 to the Giga-bit Ethernet Port, and Quad SPI to the on-board QSPI Flash. These cores are hard IPs inside the Processing System (PS) and connect to on-board peripherals via Multiplexed I/O (MIO) pins. The use of PS GPIO is is connected to BTNs 4 and 5. In the Programmable Logic (PL), we have an HDMI Tx Controller, VDMA, and GPIO IP cores to talk to the ADV7511 HDMI Transmitter Chip and I2S and GPIO IP Cores for ADAU1761 Audio Codec. More details of the hardware design can be found in the documentation inside the Zybo Base System Design package.

Before going through this tutorial, we recommend that you read Getting Started with Embedded Linux -- ZedBoard first. You can follow this tutorial with the Embedded Linux Development Guide (available on the Digilent Website Embedded Linux Page). The guide will provide you with the knowledge you may need in each step of the development.

In this tutorial, we are going to use Vivado 2014.1 Webpack in a Linux environment. All the screen shots and codes are done using Vivado Design Suite2014.1 in Fedora 19 x86_64.

Required Materials:

- Zybo Board

- Vivado 2014.1 Webpack

- Zybo Base System

- U-boot*

- Linux Kernel Source Code*

- Pre-built File System Image (available in the Zybo Linux Reference Design)

*Note: Use the Master-Next Branches until further notice

That’s it for the background information on this tutorial, now it’s time to get our hands dirty with some real design!

Step 1: Download Base System

Download the Zybo Base System Design from the website and unzip it into our working directory (our working directory is named tutorial throughout this tutorial). For more information on the hardware design, please refer to Project Guide under doc folder.

Step 2: Open the Base System Design

Source Vivado 2014.1 settings and open the design with Vivado Design Suite (vivado). You will see the Vivado window pop up.

Note: There are four settings files available in the Vivado toolset: settings64.sh for use on 64-bit machines with bash; settings32.sh for use on 32-bit machines with bash; settings32.csh for use on 32-bit machines with C Shell; and settings64.csh for use on 64-bit machines with C Shell.

Step 3: Delete Existing LED Core

We are going to detach LEDs from the GPIO core in the PS first. So, we need to click on the IP integrator and open the Block Diagram as shown in the first image in this step. Then we need to delete the current LED IP as shown in the second image. We will handle the modification of external pin location configuration (xdc file) in later steps.

Note: In Figure 4 there is a Yellow bar indicating the need for an upgrade. To upgrade hit show IP status, make sure all are selected and hit Upgrade Selected.

Step 4: Name Vendor

Before we can start implementing our myLed IP Core we need to name the Vendor that will automatically be applied in the IP packager. In Vivado 2014.1 this is not automatically done for you. To do this first go to the Project Settings under Project Manager on the left side of the window (image 1) and the project settings window will pop up. In the Project Settings Window select IP (image 2). Notice that the vendor is chosen as (none), this will cause a Vivado Internal Exception. You can name the Vendor whatever you like (image 3).

Step 5: Create MyLed IP

Now we can start implementing our myLed IP Core. Click Tools -> Create and Package IP… from the menu (image 1). The Create and Package New IP window will pop up (image 2), Click Next. In the next window name the new IP and click next again (image 3).

Step 6: Add Interfaces

The next window will be the Add Interfaces Window. This will create the AX14 Interface for the myLed peripheral. Make sure the interface type is Lite, the mode is Slave, the data width is 32 bits and the number of registers is 4. Change the Name to S_AXI rather than S00_AXI. We only need 1 register but the minimum we can select is 4. Then click next.

Step 7: Edit IP

The next window will prompt for the next steps to finish creating the IP. Change the Radio button to select Edit IP and Hit finish. We need to add user logic to the IP so that our slave is connected to the LED output.

Step 8:

After selecting finish the Create and Package IP window will disappear and the next window you will see is the edit_myLed window. This is where we will add our user logic.

Step 9: MyLed_v1_0_S_AXI

In the Project Manager, click the circle next to myLed_v1_0 and highlight myLed_v1_0_S_AXI (image 1). This contains the user logic inside of the myLed IP. We need to add two lines of code to complete the user logic for this module. First we need to create a user port which called led (image 2). Next we need to connect the internal slave to this user port. We will connect slv_reg0[3:0] as we have four LEDs (image 3).

Step 10: MyLed_v_0

Next we need to connect the user logic to myLed. In the project manager select the file myLed_v_0. To complete the IP there are two lines of code we need to add to this file. Under the comment that says Users to add ports here, add a port for the LEDs (image 1). Connect the led output from the previous file containing the user logic to myLed (image 2).

Step 11: Package IP

Now that our IP is created and the User Logic is defined, we need to package our IP. Under Project Manager on the left side of the window select Package IP. A new tab will open that is called Package IP. On the left side of this tap there are a series of labels. We need to complete those that do not have green check marks.

First select IP customization Parameters. At the top of that window select the option to Merge changes from IP Customization Parameters Wizard.

Step 12: Ports and Interfaces

Next select the IP Ports and Interfaces. Notice that your new LED IP is there.

Step 13: IP GUI Customization

Next Select IP GUI Customization. Our IP GUI is fine as is so we won’t make any changes here.

Now we can Review and Package our myLed IP. Select Review and Package IP and press the Re-Package IP button. Our IP is now completed and packaged.

Step 14: Add MyLed IP

We are going to add our IP to our design. Right-click anywhere on the block design and Click Add IP (image 1). Select the correct IP, myLed_v1.0, and press enter (image 2).

Step 15: Run Connection Automation

The AXI4-Lite bus of myLed IP Core needs to be connected to the processing system. At the top of the window click the blue text that says Run connection automation. This will connect the inputs of the myLed IP core. You should see that S_AXI is now connected to the first output of the AXI Interconnect.

Step 16: Create LED Port

Next we need to connect the myLed IP to an external port. The myLed IP core that we implemented will not connect to the existing LEDs_4Bits port so we need to make a new external port called led. Click on the existing LED port and press delete. To create the new port right click and select create port. Name the port, select output, select vector [3:0] and press enter.

Step 17: Connect LED Port

Next connect the led port to the myLed IP by clicking on the port and dragging a connection to myLed .

Step 18: Modify XDC

The final step is to specify the pin numbers for myled_0_LED_pin to physically connect our customized IP core to the on-board LEDs. In the Project Manager expand the Constraints section and select the base.xdc file (image 1). Within that file change the names of the external LED pins so that they match the name of our external led port (image 2).

Step 19: Generate Bitstream

Regenerate the bitstream for the hardware design by clicking on Generate Bitstream under Program and Debug on the left side of the window.

Step 20: U-Boot Source Code

*Note: Use the Master-Next Branches until further notice

Get the source code for U-Boot from the Digilent git repository. There are two ways to retrieve the source code:

Using git command:

If you have git installed in your distribution, you can clone the repository to your computer by command git clone https://github.com/Digilent/u-boot-Digilent-Dev.g... The whole Git Repository is around 55MB, as shown in image 1. If you want to get a separate branch, for example the next branch follow image 2. The next contains the u-boot that is not yet released. The clone url referenced above can be found on the Digilent git-hub page as seen in image 3.

Download a compressed package:

If you only want to use u-boot once and do not want to track the updates, you can also download a compressed package from github.com: https://github.com/Digilent/u-boot-digilent. Go to the drop down box that shows the branch and select tags. The most recent tag is zynq-beta-v2.2. (image 4).

If you downloaded the tar.gz, you can decompress it using command

tar zxvf u-boot-digilent-2012.04-digilent-13.01.tar.gz

If you downloaded the zip file, you can decompress it using command

unzip u-boot-digilent-2012.04-digilent-13.01.zip

Step 21: Compile U-Boot

To compile U-Boot, we need cross-compile tools which are provided by Vivado 2014.1. Those tools have a prefix arm-xilinx-linux-gnueabi- to the standard names for the GCC tool chain. The prefix references the platforms that are used. The Zybo board has two arm cores so we reference arm. In order to use the cross-platform compilers, please make sure Vivado 2014.1 settings have been sourced. If not, please refer to step 2. To configure and build U-Boot for Zybo, follow the image attached to this step.

Step 22: U-boot.elf

After the compilation,

the ELF (Executable and Linkable File) generated is named u-boot. We need to add a .elf extension to the file name so that Xilinx SDK can read the file layout and generate BOOT.BIN. In this tutorial, we are going to move the u-boot.elf to sd_image folder and substitute the u-boot.elf that comes along with Zybo Base System Design Package.

Step 23: Export Hardware for SDK

Export the hardware design (after step I-16) to Xilinx SDK by clicking on File -> Export -> Export Hardware for SDK…, as shown in the first image.

Leave the workspace as . Make sure that Launch SDK is checked and click OK, as shown in the second image.

Note: You may have to export twice.

Step 24: New Project

After SDK launches, the hardware platform project is already present in Project Explorer on the left of the SDK main window, as shown in image 1. We now need to create a First Stage Bootloader (FSBL). Click File->New->Project…, as shown in image 2.

Step 25: Application Project

In the New Project window, select Xilinx->Application Project, and then Click Next.

Step 26: Name the Project FSBL

We will name the project FSBL. Select hw_platform_0 for Target Hardware because it is the hardware project we just exported. Select standalone for OS Platform. Click Next.

Step 27: Create Zynq FSBL Template

Select Zynq FSBL as template, and click Finish.

Step 28: FSBL Hook

For the Zybo, we need set the mac address for the Ethernet in the fsbl hook. We want the mac address for the Ethernet to remain constant when we turn off and on the Zybo Board. You can swap the fsbl_hooks.c file in the FSBL project with the fsbl_hooks.c under source/vivado/SDK/fsbl in the Zybo Base System Design.

After you have saved the changes to fsbl_hooks.c,
the project will rebuild itself automatically. If it does not rebuild, Click Project->Clean to clean the project files, and Project->Build All to rebuild all the projects. The compiled ELF file is located in zybo_base_system/source/vivado/hw/zybo_bsd.sdk/SDK/SDK_Export/FSBL/Debug

Step 29: Create Boot Image

Now, we have all the files ready to create BOOT.BIN. Click Xilinx Tools -> Create Zynq Boot Image.

Step 30: Add FSBL, System.bit and U-boot.elf

In the Create Zynq Boot Image window, Click Browse to set the path for FSBL elf. Click Add to add the system.bit file found at /zybo_base_system/source/vivado/hw/zybo_bsd/zybo_bsd.sdk/SDK/SDK_Export/hw_platform_0/.Click Add to add the u-boot.elf file found at zybo_base_system/sd_image/. It is very important that the 3 files are added in this order, or else the FSBL will not work properly. It is also very important that you set FSBL.elf as the bootloader and system.bit and u-boot.elf as data files. In this tutorial, the sd_image folder is set as output folder for the BIN file. Click Create Image.

Step 31: Linux Kernel Source Code

*Note: Use the Master-Next Branches until further notice

Get the Linux kernel source code from Digilent git repository. There are two ways to retrieve the source code:

Using git command: If you have git installed in your distribution, you can clone the repository to your computer by command git clone https://github.com/DigilentInc/Linux-Digilent-Dev... The whole Git Repository is around 850MB, as shown in image 1.

Download a compressed package: If you only want to use u-boot once and do not want to track the updates, you can also download a compressed package from github.com: https://github.com/DigilentInc/Linux-Digilent-Dev. Click Tags on the top right corner of the page.The most recent tag is zynq-dt-for-3.14 (image 2).

If you downloaded the tar.gz, you can decompress it using command

tar zxvf linux-digilent-v3.6-digilent-13.01.tar.gz

If you downloaded the zip file, you can decompress it using command

unzip linux-digilent-v3.6-digilent-13.01.zip

Step 32: Configure the Kernel

We will start to configure the kernel with the default configuration for Zybo. The configuration is located at arch/arm/configs/xylinx_zynq_defconfig. To use the default configuration follow the image attached to this step.

Step 33: Compile the Linux Kernel

Follow the example in the image.

Step 34: Make Uimage

After the compilation, the kernel image is located at arch/arm/boot/zImage. However in this case the kernel image has to be a uimage (unzipped) rather than a zimage. To make the uimage follow the image in this step.

Step 35: Optional Path Change

Note: Depending on your distribution of linux you may get an error regarding the path of the mkimage. If this is the case you can change the path following the image in this step.

Step 36: Make Uramdisk

To boot the Linux Operating System on the Zybo, you need BOOT.BIN, a Linux kernel image (uImage), a device tree blob (DTB file), and a file system. BOOT.BIN has been created in Section III and uImage has been compiled in Section IV. We will now compile the DTB file. The default device tree source file is located in the Linux Kernel source at arch/arm/boot/dts/zynq-zybo.dts.

RAMDISK: For zynq only the ramdisk image has to be wrapped in a u-boot header in order for u-boot to boot with it. This is shown in the image in this step.

Step 37: Generate DTB File

Follow the example provided in the image.

Step 38: Copy File Image to SD Card

RAMDISK) Copy BOOT.BIN, devicetree.dtb, uImage and uramdisk.image.gz to the first partition of an SD card, as shown in the first image – RamDisk.

NOTE: The first partition of the SD card is mounted to /media/ZYBO_BOOT

Step 39: Boot From SD Card

Plug the SD Card into the Zybo. To boot from SD card, jumper 7 needs to be configured for USB as shown on the Zybo Board and Jumper 5 must be connected to SD. Connect UART port to PC with micro USB cable and set the UART terminal on PC to 115200 baud rate, 8 data bits, 1 stop bit, no parity, and no flow control. After powering on the board, the console should be seen at the UART terminal if you use RamDisk. More information about this file system can be found in Getting Started with Embedded Linux ZedBoard.

Step 40: Create a Drivers Directory

Create a directory named drivers in the Tutorial folder, as shown the image in this step. Inside the drivers directory, we will compose the driver for the myLed controller.

Step 41: Create the Makefile

We need a Makefile so that we can compile the driver. The Makefile is created in image 1.

After creating the file, hit I to change to insert mode and insert the following text in image 2. Make sure you use tab characters where appropriate.

Step 42: Create Myled.c

We will start with a simple driver that creates a file named myled under the Linux /proc file system. The status of the on-board LEDs can be changed by writing a number to the file. The driver is coded in the last four images and is attached

Step 43: Compile Driver

Compile and generate the driver module using make. Don’t forget to source Vivado settings.

Step 44: Add Myled to the Device Tree

We need to add the myLed device node into the device tree.

Make a copy of the default device tree source in the drivers folder, and modify it according to the second image. The compatibility string of the node is the same as we define in the driver source code (myled.c: line 182). The reg property defines the physical address and size of the node. The address here should match with the address of the myLed IP core in the address editor tab of the Vivado design, as shown in the last image.

Step 45: Recompile Device Tree Blob

Recompile the device tree blob as shown in the attached image.

Step 46: Copy Driver and Modified Device Tree to SD Card

Copy these two files to the first partition of the SD card, as shown in the image in this step. We are ready to test our driver on-board now.

Step 47: Boot From SD Card

Plug the SD card into the Zybo, and we can start testing our driver. Use the insmod command to install the driver module into the kernel. After the driver is installed, an entry named myled will be created under the /proc file system. Writing 0x0F to /proc/myled will light up LED 0~3. You can either remove the driver with command rmmod or power off the system by command poweroff. In both case, all the LEDs will be turned off, as shown in Figure 69 and 70. For instructions on using the terminal with the Zybo. please refer to Step V-4 or Section Boot from SD in Getting Started with Embedded Linux – ZedBoard.

Step 48: User Application: Led_blink

In this section, we will write a user application that makes the LEDs

blink by writing to /proc/myled. Create a directory named user_app in the Tutorial folder, as shown in the first image. Inside the user_app directory, we will compose the led_blink.c, as shown in the second and third image.

Step 49: Create Makefile and Compile Led_blink

Compose a Makefile and compile led_blink.c into led_blink.o, as shown in the three images in this step.

Step 50:

Insert the SD card into the computer, and copy the binary file led_blink onto the first partition of SD card.

Step 51: Run Led_blink

Plug the SD card into the ZYBO. Use the insmod command to install the driver module into the kernel. Run led_blink and the LED will start blinking.

Step 52: Feedback!

Just a reminder, this is a draft. There will be an official copy that will be released on Digilentinc.com.

I appreciate any feedback to make the official copy stronger.

Comments

author
Chaithanya0102 (author)2017-06-21

Hi,

I have reached step 39. I have copied boot.bin, devicetree.dtb, uimage and uramdisk.img.gz in ZYBO_BOOT in sdcard and tried to boot from SD card. But my terminal shows nothing :(

What might have gone wrong?

author
jessehbarreto (author)2017-05-26

I loved it!
I will do it.

But the Zybo Base System link isn't working tho. ='(

author
heinecke_jmh (author)2016-02-25

I needed to #include <linux/slab.h> so kmalloc and kfree were declared

author
TsotneP (author)2016-02-19

cool stuff

author
DamienC17 (author)2016-02-19

Hi, thank you for this really interesting tutorial.
I have a problem compiling the myled.c driver. Each time I try I get that error message:

make -C ../Linux-Digilent-Dev/ M=/home/damien/Desktop/boot2/drivers modules

make[1]: Entering directory `/home/damien/Desktop/boot2/Linux-Digilent-Dev'

CC [M] /home/damien/Desktop/boot2/drivers/myled.o

In file included from ./arch/x86/include/asm/bitops.h:16:0,

from include/linux/bitops.h:36,

from include/linux/kernel.h:10,

from /home/damien/Desktop/boot2/drivers/myled.c:1:

./arch/x86/include/asm/arch_hweight.h: In function ‘__arch_hweight64’:

./arch/x86/include/asm/arch_hweight.h:53:42: error: expected ‘:’ or ‘)’ before ‘POPCNT64’

asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)

^

./arch/x86/include/asm/alternative.h:98:31: note: in definition of macro ‘ALTINSTR_REPLACEMENT’

b_replacement(number)":\n\t" newinstr "\n" e_replacement(number) ":\n\t"

^

./arch/x86/include/asm/arch_hweight.h:53:7: note: in expansion of macro ‘ALTERNATIVE’

asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)

^

In file included from ./arch/x86/include/asm/segment.h:148:0,

from ./arch/x86/include/asm/ptrace.h:4,

from ./arch/x86/include/asm/alternative.h:8,

from ./arch/x86/include/asm/bitops.h:16,

from include/linux/bitops.h:36,

from include/linux/kernel.h:10,

from /home/damien/Desktop/boot2/drivers/myled.c:1:

./arch/x86/include/asm/processor.h: At top level:

./arch/x86/include/asm/cache.h:7:25: error: ‘CONFIG_X86_L1_CACHE_SHIFT’ undeclared here (not in a function)

#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)

^

./arch/x86/include/asm/cache.h:8:30: note: in expansion of macro ‘L1_CACHE_SHIFT’

#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)

^

include/linux/cache.h:12:25: note: in expansion of macro ‘L1_CACHE_BYTES’

#define SMP_CACHE_BYTES L1_CACHE_BYTES

^

./arch/x86/include/asm/processor.h:130:30: note: in expansion of macro ‘SMP_CACHE_BYTES’

} __attribute__((__aligned__(SMP_CACHE_BYTES)));

^

In file included from ./arch/x86/include/asm/thread_info.h:23:0,

from include/linux/thread_info.h:54,

from ./arch/x86/include/asm/preempt.h:6,

from include/linux/preempt.h:18,

from include/linux/spinlock.h:50,

from include/linux/seqlock.h:35,

from include/linux/time.h:5,

from include/linux/stat.h:18,

from include/linux/module.h:10,

from /home/damien/Desktop/boot2/drivers/myled.c:2:

./arch/x86/include/asm/processor.h:130:1: error: requested alignment is not an integer constant

} __attribute__((__aligned__(SMP_CACHE_BYTES)));

^

In file included from include/asm-generic/percpu.h:6:0,

from ./arch/x86/include/asm/percpu.h:522,

from ./arch/x86/include/asm/preempt.h:5,

from include/linux/preempt.h:18,

from include/linux/spinlock.h:50,

from include/linux/seqlock.h:35,

from include/linux/time.h:5,

from include/linux/stat.h:18,

from include/linux/module.h:10,

from /home/damien/Desktop/boot2/drivers/myled.c:2:

./arch/x86/include/asm/processor.h:154:39: error: requested alignment is not an integer constant

DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);

^

include/linux/percpu-defs.h:101:38: note: in definition of macro ‘DECLARE_PER_CPU_SECTION’

extern __PCPU_ATTRS(sec) __typeof__(type) name

^

./arch/x86/include/asm/processor.h:154:1: note: in expansion of macro ‘DECLARE_PER_CPU_SHARED_ALIGNED’

DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);

^

In file included from ./arch/x86/include/asm/thread_info.h:23:0,

from include/linux/thread_info.h:54,

from ./arch/x86/include/asm/preempt.h:6,

from include/linux/preempt.h:18,

from include/linux/spinlock.h:50,

from include/linux/seqlock.h:35,

from include/linux/time.h:5,

from include/linux/stat.h:18,

from include/linux/module.h:10,

from /home/damien/Desktop/boot2/drivers/myled.c:2:

./arch/x86/include/asm/processor.h:163:0: warning: "cache_line_size" redefined [enabled by default]

#define cache_line_size() (boot_cpu_data.x86_cache_alignment)

^

In file included from include/linux/printk.h:8:0,

from include/linux/kernel.h:13,

from /home/damien/Desktop/boot2/drivers/myled.c:1:

include/linux/cache.h:64:0: note: this is the location of the previous definition

#define cache_line_size() L1_CACHE_BYTES

^

In file included from ./arch/x86/include/asm/thread_info.h:23:0,

from include/linux/thread_info.h:54,

from ./arch/x86/include/asm/preempt.h:6,

from include/linux/preempt.h:18,

from include/linux/spinlock.h:50,

from include/linux/seqlock.h:35,

from include/linux/time.h:5,

from include/linux/stat.h:18,

from include/linux/module.h:10,

from /home/damien/Desktop/boot2/drivers/myled.c:2:

./arch/x86/include/asm/processor.h:252:1: error: requested alignment is not an integer constant

} __attribute__((packed)) ____cacheline_aligned;

^

./arch/x86/include/asm/processor.h:283:1: error: requested alignment is not an integer constant

} ____cacheline_aligned;

^

In file included from include/asm-generic/percpu.h:6:0,

from ./arch/x86/include/asm/percpu.h:522,

from ./arch/x86/include/asm/preempt.h:5,

from include/linux/preempt.h:18,

from include/linux/spinlock.h:50,

from include/linux/seqlock.h:35,

from include/linux/time.h:5,

from include/linux/stat.h:18,

from include/linux/module.h:10,

from /home/damien/Desktop/boot2/drivers/myled.c:2:

./arch/x86/include/asm/processor.h:285:39: error: requested alignment is not an integer constant

DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss);

^

include/linux/percpu-defs.h:101:38: note: in definition of macro ‘DECLARE_PER_CPU_SECTION’

extern __PCPU_ATTRS(sec) __typeof__(type) name

^

./arch/x86/include/asm/processor.h:285:1: note: in expansion of macro ‘DECLARE_PER_CPU_SHARED_ALIGNED’

DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss);

^

In file included from ./arch/x86/include/asm/atomic.h:235:0,

from include/linux/atomic.h:4,

from ./arch/x86/include/asm/thread_info.h:24,

from include/linux/thread_info.h:54,

from ./arch/x86/include/asm/preempt.h:6,

from include/linux/preempt.h:18,

from include/linux/spinlock.h:50,

from include/linux/seqlock.h:35,

from include/linux/time.h:5,

from include/linux/stat.h:18,

from include/linux/module.h:10,

from /home/damien/Desktop/boot2/drivers/myled.c:2:

./arch/x86/include/asm/atomic64_64.h:19:1: error: unknown type name ‘atomic64_t’

static inline long atomic64_read(const atomic64_t *v)

^

In file included from include/linux/linkage.h:4:0,

from include/linux/kernel.h:6,

from /home/damien/Desktop/boot2/drivers/myled.c:1:

./arch/x86/include/asm/atomic64_64.h: In function ‘atomic64_read’:

./arch/x86/include/asm/atomic64_64.h:21:24: error: request for member ‘counter’ in something not a structure or union

return ACCESS_ONCE((v)->counter);

^

include/linux/compiler.h:381:43: note: in definition of macro ‘ACCESS_ONCE’

#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))

^

./arch/x86/include/asm/atomic64_64.h:21:24: error: request for member ‘counter’ in something not a structure or union

return ACCESS_ONCE((v)->counter);

^

include/linux/compiler.h:381:50: note: in definition of macro ‘ACCESS_ONCE’

#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))

^

In file included from ./arch/x86/include/asm/atomic.h:235:0,

from include/linux/atomic.h:4,

from ./arch/x86/include/asm/thread_info.h:24,

from include/linux/thread_info.h:54,

from ./arch/x86/include/asm/preempt.h:6,

from include/linux/preempt.h:18,

from include/linux/spinlock.h:50,

from include/linux/seqlock.h:35,

from include/linux/time.h:5,

from include/linux/stat.h:18,

from include/linux/module.h:10,

from /home/damien/Desktop/boot2/drivers/myled.c:2:

./arch/x86/include/asm/atomic64_64.h: At top level:

./arch/x86/include/asm/atomic64_64.h:31:33: error: unknown type name ‘atomic64_t’

static inline void atomic64_set(atomic64_t *v, long i)

^

./arch/x86/include/asm/atomic64_64.h:43:41: error: unknown type name ‘atomic64_t’

static inline void atomic64_add(long i, atomic64_t *v)

^

./arch/x86/include/asm/atomic64_64.h:57:41: error: unknown type name ‘atomic64_t’

static inline void atomic64_sub(long i, atomic64_t *v)

^

./arch/x86/include/asm/atomic64_64.h:73:49: error: unknown type name ‘atomic64_t’

static inline int atomic64_sub_and_test(long i, atomic64_t *v)

^

./arch/x86/include/asm/atomic64_64.h:84:33: error: unknown type name ‘atomic64_t’

static inline void atomic64_inc(atomic64_t *v)

^

./arch/x86/include/asm/atomic64_64.h:97:33: error: unknown type name ‘atomic64_t’

static inline void atomic64_dec(atomic64_t *v)

^

./arch/x86/include/asm/atomic64_64.h:112:41: error: unknown type name ‘atomic64_t’

static inline int atomic64_dec_and_test(atomic64_t *v)

^

./arch/x86/include/asm/atomic64_64.h:125:41: error: unknown type name ‘atomic64_t’

static inline int atomic64_inc_and_test(atomic64_t *v)

^

./arch/x86/include/asm/atomic64_64.h:139:49: error: unknown type name ‘atomic64_t’

static inline int atomic64_add_negative(long i, atomic64_t *v)

^

./arch/x86/include/asm/atomic64_64.h:151:48: error: unknown type name ‘atomic64_t’

static inline long atomic64_add_return(long i, atomic64_t *v)

^

./arch/x86/include/asm/atomic64_64.h:156:48: error: unknown type name ‘atomic64_t’

static inline long atomic64_sub_return(long i, atomic64_t *v)

^

./arch/x86/include/asm/atomic64_64.h:164:37: error: unknown type name ‘atomic64_t’

static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)

^

./arch/x86/include/asm/atomic64_64.h:169:34: error: unknown type name ‘atomic64_t’

static inline long atomic64_xchg(atomic64_t *v, long new)

^

./arch/x86/include/asm/atomic64_64.h:183:39: error: unknown type name ‘atomic64_t’

static inline int atomic64_add_unless(atomic64_t *v, long a, long u)

^

./arch/x86/include/asm/atomic64_64.h:207:45: error: unknown type name ‘atomic64_t’

static inline long atomic64_dec_if_positive(atomic64_t *v)

^

In file included from ./arch/x86/include/asm/segment.h:148:0,

from ./arch/x86/include/asm/ptrace.h:4,

from ./arch/x86/include/asm/alternative.h:8,

from ./arch/x86/include/asm/bitops.h:16,

from include/linux/bitops.h:36,

from include/linux/kernel.h:10,

from /home/damien/Desktop/boot2/drivers/myled.c:1:

./arch/x86/include/asm/cache.h:12:31: error: ‘CONFIG_X86_INTERNODE_CACHE_SHIFT’ undeclared here (not in a function)

#define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT

^

include/linux/cache.h:57:35: note: in expansion of macro ‘INTERNODE_CACHE_SHIFT’

__attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT))))

^

include/linux/mmzone.h:108:3: note: in expansion of macro ‘____cacheline_internodealigned_in_smp’

} ____cacheline_internodealigned_in_smp;

^

In file included from include/linux/gfp.h:5:0,

from include/linux/kmod.h:22,

from include/linux/module.h:13,

from /home/damien/Desktop/boot2/drivers/myled.c:2:

include/linux/mmzone.h:108:1: error: requested alignment is not an integer constant

} ____cacheline_internodealigned_in_smp;

^

include/linux/mmzone.h:531:1: error: requested alignment is not an integer constant

} ____cacheline_internodealigned_in_smp;

^

In file included from include/linux/elf.h:4:0,

from include/linux/module.h:14,

from /home/damien/Desktop/boot2/drivers/myled.c:2:

./arch/x86/include/asm/elf.h: In function ‘elf_common_init’:

./arch/x86/include/asm/elf.h:178:3: error: ‘struct thread_struct’ has no member named ‘fs’

t->fs = t->gs = 0;

^

./arch/x86/include/asm/elf.h: At top level:

./arch/x86/include/asm/elf.h:368:1: error: requested alignment is not an integer constant

} ____cacheline_aligned;

^

In file included from include/linux/module.h:22:0,

from /home/damien/Desktop/boot2/drivers/myled.c:2:

./arch/x86/include/asm/module.h:57:2: error: #error unknown processor family

#error unknown processor family

^

In file included from /home/damien/Desktop/boot2/drivers/myled.c:2:0:

include/linux/module.h:302:27: error: field ‘arch’ has incomplete type

struct mod_arch_specific arch;

^

In file included from /home/damien/Desktop/boot2/drivers/myled.c:4:0:

./arch/x86/include/asm/io.h:42:31: fatal error: asm/early_ioremap.h: No such file or directory

#include <asm/early_ioremap.h>

^

compilation terminated.

make[2]: *** [/home/damien/Desktop/boot2/drivers/myled.o] Error 1

make[1]: *** [_module_/home/damien/Desktop/boot2/drivers] Error 2

make[1]: Leaving directory `/home/damien/Desktop/boot2/Linux-Digilent-Dev'

make: *** [all] Error 2

I can't figure out why... I could compile the kernel, uboot, the device tree and ramdisk without any issue...

If someone knows how to fix this, I'd be grateful !

Have a good day,

Damien.

author
骏鹏刘 (author)2015-08-17

Hey, Thanks for the update!

I followed the tutorial and Everything works fine until this step by having a error message:

arch/arm/kernel/asm.offsets.c:53:2: error: #error your compiler is too buggy; it is known to miscompile kernels

# error your compiler si too buggy; it is known to miscompile kernels

arch/arm/kernel/asm.offsets.c:54:2: error: #error and result in filesystem corruption and oopses.

#error and result in filesystem corruption and oopses.

make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 1

make: *** [prepare0] Error 2

What I am using is Vivado 2014.2, Ubuntu 64bit 14.04 LTS.

I think this error is trying to tell me I am using a wrong version of GCC compiler, but how can I solve it?

Thanks

Jimmy

author
GaneshK7 (author)2015-06-09

Dear All,

How to insert a driver module at the time of boot up?

In my zynq kernel there is no module or module.config file under /etc/ folder.

Please Guide


-Ganesh



author
hongrui (author)2015-06-04

Hi,kaitlyn1franz, I want to compile the u-boot on my virtual machine. The followting is the information in the terminal.

root@hongrui-virtual-machine:/mnt/hgfs/LinuxShare/u-boot-Digilent-Dev-zynq-beta-v2.2# make CROSS_COMPILE=arm-linux-gnueabi-zynq_zybo_config
System not configured - see README
make: *** [all] Error 1

I have installed the Vivado14.04 and SDK on my virtual machine, and the OS on my virtual is Ubutun12.04 32bits. In addition, I had generated the bitstream successfully before I began to compile the u-boot. In order to solve this problem, I try to modifiy the path as following,

root@hongrui-virtual-machine:/mnt/hgfs/LinuxShare/u-boot-Digilent-Dev-zynq-beta-v2.2# export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
root@hongrui-virtual-machine:/mnt/hgfs/LinuxShare/u-boot-Digilent-Dev-zynq-beta-v2.2# export PATH=/root/opt/Xilinx/SDK/2014.4/gnu/arm/lin/:$PATH

Then I try to compile the u-boot again,

root@hongrui-virtual-machine:/mnt/hgfs/LinuxShare/u-boot-Digilent-Dev-zynq-beta-v2.2# make CROSS_COMPILE=arm-xilinx-gnueabi-zynq_zybo_config
System not configured - see README
make: *** [all] Error 1

There is still an error.

Thank you.

author
NicanorG (author)2015-05-18

Can you record and play audio using the operating system installed here? Or would I have to write the driver for that?

Thank you very much.

author
Gelila (author)2015-01-21

Hi All,

Followed this tutorial
till the end and its a great one. But it describes the steps only with
RAMDisk and not with linaro. can any one suggest a similar tutorial but
with linaro as the os.

thanks

author
Commanderfranz (author)Gelila2015-01-21

hello Gelila,

The Zybo doesn't have a graphics card so it can't run linaro. To do that you would need a board such as the zedboard, or use a desktop remotely. Unfortunately you can't run linaro directly on the board.

author

Here:
https://www.instructables.com/id/Setting-up-the-Zyb...
The autor make the Zybo run Linaro.

author
Gelila (author)Commanderfranz2015-01-21

Thank you for replying.

Can you point me to a tutorial on how to run an opencv c++ code on the ZYBO with RAMDisk. I couldn't find one and I need it desperately for my project.

thanks in advance

author
MagnusP1 (author)2014-12-11

Where can I find ramdisk8M.image.gz (used in figure 52)? The tutorial says in the "Zybo Linux Reference Design" but provides no link to this design.

author
NicanorG (author)MagnusP12015-03-26

I'm also confused at this step. Is it optional?

author
MagnusP1 (author)NicanorG2015-03-28

I used the arm_ramdisk from http://www.wiki.xilinx.com/Build+and+Modify+a+Rootfs

author
jfrenzel (author)2015-03-21

I didn't seem to get image 3 exactly when selecting "Next" in image 2, but I'm running 2014.4. Instead, I needed to select "Create new AXI peripheral" and then I got the interfaces window.

author
jfrenzel (author)2015-03-21

I was running Vivado 2014.4 under Ubuntu and don't get the "Run connection automation" design assistance. Any ideas why? (My IP seems to be labeled "pre-production".)

author
Prilliquism (author)2014-10-19

Hi Kaitlyn,

I got pretty far in this tutorial but I got stuck when I tried to boot up the kernel. It looks like it stopped at

[ 1.380711] No filesystem could mount root, tried: ext3 ext2 ext4 vfat msdos
[ 1.387962] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)

I'm not sure what I did wrong. Any ideas?

author
raul.go.31 (author)Prilliquism2014-11-26

Hello Prilliquism,

I have the same problem using a ZYBO board, did you managed to solved it??:


[ 1.480055] No filesystem could mount root, tried: ext3 ext2 ext4 vfat msdos
[ 1.487252] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)
[ 1.495438] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.14.0-xilinx-13567-g906a2c9-dirty #2

author
StMartin81 (author)raul.go.312015-02-03

The bootargs for the Linux kernel were wrong for me. It worked for me after I changed the bootargs in zynq-zybo.dts to the following:

bootargs = "console=ttyPS0,115200 root=/dev/ram0 rw init=/sbin/init earlyprintk rootwait devtmps.mount=1";

author

Did you already find a solution? I encountered the same problem

author
simux (author)2014-07-24

Hi Kaitlyn,

I think this totorial needs to be updated:

For Step 21, if I use git clone https://github.com/DigilentInc/u-boot-Digilent-Dev.git

then when I type "make CROSS_COMPILE=arm-xilinx-linux-gnueabi- zynq_zybo_config", I got nothing. I think this repository doesn't suit for ZYBO. The same thing happen to the process of building Linux Kernel according to your instructions.

author
gregsmart (author)simux2014-09-02

The reason for the problem is you didn't use the master-next branch. The Zybo release is still in beta so the main branch doesn't support it yet.

try git clone -b master-next .... for both u-boot and the kernel.

cheers,

Greg

author
MichaelF14 (author)gregsmart2014-12-29

Hi Greg,

I have addressed this to you as I see you have some competent responses.

I have just followed the hands-on tutorial from the digilent site also. I face the same problems on u-boot with the make command. First I tried the 2014.4 Vivado sdk shell which does not run the makefile correct due to a problem with 'rm' syntax (board/*/config.tmp). Then I have installed Cygwin, which now gives me following:

$ make CROSS_COMPILE=arm-xilinx-linux-gnueabi- zynq_ZYBO_config
/cygdrive/g/Michael/Github/u-boot-Digilent-Dev/mkconfig: line 2: $'\r': command not found
Makefile:784: recipe for target 'zynq_ZYBO_config' failed
make: *** [zynq_ZYBO_config] Error 127

I also tried using only small letters on zynq_zybo_config but it gives the same result.

Is it really needed to use a linux installation in order to cross compile u-boot?

cheers,

Michael

author
gregsmart (author)MichaelF142015-01-01

Hi Michael,

I have never tried to use Cygwin myself for something like this. Xilinx warns against using it and the preferred method is to use a virtual machine. I have been using virtual box, but recently I have switched to using dual-boot.

The error you described is an environment setup issue. Unfortunately this is not my strong area which is why I stick to the beaten path. I would have thought configuring and compiling the kernel would be difficult using Cygwin.

The problem with Zynq is you need proficiency in so many areas to get a system up and running. The only way to get started is to stick to the standard model, and only deviate as you gain the experience. I'm a hardware/FPGA/DSP person, so programming environments are something I am not that good with.

regards,

Greg

author
MichaelF14 (author)gregsmart2015-01-01

Hi Greg,

I appreciate your response.

The only reason I try to use Cygwin is mainly because the SDK make, seems to parse the makefile incorrectly. I agree it may be down to some environment problems, but I think there is more to it on Windows.

I have now made me a VM running OpenSUSE, and installed the package on there. Unfortunately I cannot use my design license from Xilinx as the MAC in the VM is detected as 00:00:00:....

Since I have a design license with my ZYBO, Xilinx does not provide me the opportunity to use a webpack license and the option is gray to me.

The linux SDK however, does seem to parse the makefile correctly though, but maybe there I also have some environment problems as GCC is installed there too.

I think I may have to try make dual boot and not a VM to overcome the license problem and start out with a minimum Linux install. If only Digilent had provided a u-boot ready for the board, the tutorial would have finished alot faster.

Wish you a great year 2015.

Br

Michael

author
MichaelF14 (author)MichaelF142015-01-03

Hi again,

Just as a status on my findings.

Stripping Windows installation of any gcc other than the SDK provided, didnt solve the problem. The make utility seems to not branch in the Makefile correctly. Also I found that using the Github Zip is not good. I had to use the command: git clone -b master-next https://github.com/DigilentInc/u-boot....

What the actual difference on Zip or git really is, I do not know and I am not going to investigate.

Next is that I needed to run the make commands in my linux VM where a gcc is installed parallel to the SDK. On Linux i used git to get the clone into the home directory to avoid any readonly problems.

The actual SDK was not really used, other than the arm-xilinx-linux-gnueabi-gcc and therefor i was not hindered by my license not working on other than Windows.

Last step is now to verify it will in fact boot on my zybo :o)

Anyone aware of a forum for zybo which is a bit like the www.zedboard.org ?

Would be great to have a place for experiences, tutorials and the like.

Br

Michael

author
wittlage (author)2014-12-03

Step 34: Are you sure that the "u" in uImage means "unzipped"? I always thought of it to be a prefix for files with an U-Boot header. Isn't it true that U-Boot's mkimage is called in this step?

author
raul.go.31 (author)2014-11-27

Hello, can you provide details to use Linaro?

author
rekrek (author)2014-10-19

Wow ! A bit to complex for me, but every steps are well detailed ! A++

I was looking for a hardware solution to read HDMI input and process the stream in realtime to generate color approximation of the edge of the screen to drive leds. Such systems are called ambilight (ambient light leds) and drive a strip of ws2812b leds.

Would the Zybo able to capture HDMI and process it realtime on the ARM (ex with boblight or prismatik)?

If you do get it to work, make a sd card image :)

I'd donate to download it (but make it opensource :)

author
gregsmart (author)2014-09-02

Hi Kaitlyn,

I had no problem getting this tutorial running. The reason I ran through was I am using the Zybo to drive a test harness and I want to try getting the framebuffer device running so I can run Linaro on it. The tutorial is really well put together.

I noticed that it's up on the Digilent site now. Here's a couple of (very minor) things I picked up running through it.

All through the tutorial you use "ZYBO", where the references should be to "zybo". I'm mostly referring to the device tree and kernel configuration.

The address map in Vivado is not set until right at the end of the tutorial. You should set this when you initially build the base reference design. There's no value rebuilding it.

Figure 55 is a screen grab, but it's from a Zedboard, not a Zybo. It should be updated.

thanks for this, I hope to see more, especially Linux with GUI running.

cheers,

Greg

About This Instructable

97,532views

53favorites

License:

More by Commanderfranz:Decoding VGA Signals With a Portable Logic AnalyzerHow to Use the Protocol Analyzer on the Discovery to Test SensorsAnalog Discovery 2 Quick Start
Add instructable to: