Running VxWorks on Zynq-7000: BSP Setup and Boot Process
The Zynq-7000 All Programmable SoC integrates a dual-core ARM Cortex-A9 processing system with FPGA programmable logic. This architecture allows developers to combine software and hardware acceleration in a single device.
VxWorks provides a stable real-time operating system platform for Zynq devices, supporting both SMP and AMP configurations. With the appropriate BSP and boot configuration, VxWorks can run efficiently on Zynq development boards such as the ZC702.
This guide explains how to build and run the VxWorks 6.9 BSP for the Zynq-7000 platform, including:
- Zynq boot architecture
- Building the VxWorks kernel and bootloader
- Booting from SD card and FTP
- Building and debugging applications
- Accessing peripherals in both the Processing System (PS) and Programmable Logic (PL)
๐ฏ Learning Objectives #
After completing this guide, you will be able to:
- Understand the Zynq-7000 boot architecture
- Build a VxWorks kernel image using the Zynq BSP
- Configure a bootloader and boot image
- Boot VxWorks from SD card or FTP
- Build and deploy kernel modules
- Access memory-mapped peripherals in both PS and PL
๐ Overview of VxWorks on Zynq-7000 #
VxWorks from Wind River is a high-performance real-time operating system designed for embedded systems.
Key characteristics include:
- Deterministic real-time scheduling
- Modular architecture with configurable components
- Support for multiple processor architectures
- Built-in networking, storage, and debugging tools
For the Zynq-7000 platform, VxWorks supports:
- ARM Cortex-A9 dual-core processors
- Symmetric Multiprocessing (SMP)
- Asymmetric Multiprocessing (AMP)
- Integration with FPGA-based peripherals
This document serves as a practical starting point for developers deploying VxWorks on Zynq hardware.
๐งฉ Hardware and Software Requirements #
Software Requirements #
You will need the following development tools:
- Xilinx ISE Design Suite 14.6 or Vivado 2013.2
- Wind River Workbench with VxWorks 6.9.3
- Serial terminal software (for example Tera Term)
Hardware Requirements #
The reference platform used in this guide:
- Xilinx ZC702 development board
- Ethernet cable
- USB-UART cable
- SD card
๐๏ธ Zynq-7000 Boot Architecture #
Unlike traditional FPGA devices, the Zynq architecture uses the ARM processing system to control device configuration.
Booting a Zynq device typically involves three stages.
Stage 0 โ BootROM #
After power-on reset, the CPU executes code stored in the on-chip BootROM.
BootROM responsibilities include:
- Selecting the boot device
- Loading the first boot image
- Supporting secure and non-secure boot
- Providing basic drivers for NAND, NOR, QSPI, and SD
Boot mode is determined by hardware configuration pins, which are sampled during reset and stored in the BOOT_MODE register.
Supported boot sources include:
- NAND
- NOR
- Quad-SPI
- SD card
- JTAG
BootROM loads the First Stage Bootloader (FSBL) into on-chip memory before transferring control.
Stage 1 โ First Stage Bootloader (FSBL) #
The FSBL is responsible for initializing the system hardware.
Typical FSBL responsibilities include:
- Initializing DDR memory
- Configuring the processing system
- Programming the programmable logic (bitstream)
- Loading the second-stage bootloader or application
Before transferring control, the FSBL disables the cache and MMU to ensure compatibility with operating systems such as Linux or VxWorks.
Stage 2 โ VxWorks Bootloader #
The VxWorks bootloader loads the operating system image into memory.
Features of the VxWorks bootloader include:
- Interactive boot configuration
- Network boot support
- File system loading
- Boot parameter configuration
Unlike self-booting images used in production systems, a bootloader is particularly useful during development because it allows the OS image to be downloaded from a host system.
โ๏ธ Preparing the Development Environment #
Install the VxWorks development environment and ensure the Zynq BSP is available.
Steps:
- Install the VxWorks 6.9.3.1 toolchain
- Install the Base Tools Package
- Use the Product Maintenance tool to update installed components
- Verify that the Zynq-7000 BSP is installed
- Apply the latest BSP patches provided by Wind River
Keeping BSP patches up to date is important because vendor BSPs often receive asynchronous driver updates.
๐ ๏ธ Enabling SD Card Support in the BSP #
The default BSP configuration does not enable SD card storage.
Edit the BSP configuration file:
target/config/xlnx_zynq7k/config.h
Locate the following line:
#undef DRV_STORAGE_SDHC
Enable SD storage and DOS file system support:
#define DRV_STORAGE_SDHC
#define INCLUDE_DOSFS
#define INCLUDE_DOSFS_MAIN
#define INCLUDE_DOSFS_CHKDSK
#define INCLUDE_DOSFS_FMT
#define INCLUDE_DOSFS_FAT
#define INCLUDE_DOSFS_SHOW
#define INCLUDE_DOSFS_DIR_VFAT
#define INCLUDE_DOSFS_DIR_FIXED
#define INCLUDE_FS_MONITOR
#define INCLUDE_FS_EVENT_UTIL
#define INCLUDE_ERF
#define INCLUDE_XBD
#define INCLUDE_XBD_BLKDEV
#define INCLUDE_XBD_TRANS
#define INCLUDE_DEVICE_MANAGER
#define INCLUDE_XBD_BLK_DEV
#define INCLUDE_XBD_PART_LIB
#define INCLUDE_DISK_UTIL
This configuration enables:
- SDHC storage driver
- FAT file system support
- Disk management utilities
๐งฑ Building the VxWorks Kernel Image #
To create a VxWorks kernel image using Wind River Workbench:
- Launch Wind River Workbench
- Select File โ New โ Project
- Choose VxWorks Image Project
- Select the BSP:
xlnx_zynq7k
- Choose the PROFILE_DEVELOPMENT configuration
- Enable symbol table support in the kernel configuration
- Build the project
The resulting VxWorks kernel image is generated in:
<project>/default/
๐ง Building the BootROM Image #
Next, build the VxWorks bootloader.
From a VxWorks development shell:
cd <install_dir>/vxworks-6.9/target/config/xlnx_zynq7k
make clean
make bootROM
Rename the output file:
bootROM โ bootROM.elf
๐ฆ Creating the Boot Image #
Create a boot.bif file that defines the boot image layout.
ZC702_boot_image:
{
[bootloader] zynq_fsbl_0.elf
bootROM.elf
}
Generate the final boot image using the Xilinx bootgen tool:
bootgen -image boot.bif -o BOOT.BIN -w
Copy the following files to the SD card:
BOOT.BIN
vxWorks
๐พ Booting VxWorks from SD Card #
To boot the ZC702 board from an SD card:
- Insert the SD card into the board
- Configure the board boot switches for SD boot
- Connect UART and Ethernet cables
- Open a serial terminal:
Baud rate: 115200
- Power on the board
- Interrupt the boot process by pressing Enter
The bootloader prompt appears.
Configure boot parameters:
boot device: fs
file name: /sd0:1/vxWorks
Start the boot process:
@
To verify system operation, display running tasks:
-> i
๐ Booting VxWorks Using FTP #
VxWorks can also load the kernel image from a host machine.
Configure the host network:
Host IP: 192.168.1.1
Target IP: 192.168.1.2
Start an FTP server and create a user account.
At the boot prompt configure parameters:
boot device: gem0
file name: vxWorks
inet on ethernet: 192.168.1.2:ffffff00
host inet: 192.168.1.1
Start the boot process:
@
The kernel image will be downloaded from the FTP server.
๐งช Building and Running a Hello World Application #
Create a Downloadable Kernel Module (DKM) project in Workbench.
Example source file:
#include <stdio.h>
#include <taskLib.h>
void helloTask(void)
{
printf("Hello Wind River\n");
}
void helloStart(void)
{
taskSpawn(
"tHello",
100,
0,
4096,
(FUNCPTR)helloTask,
0,0,0,0,0,0,0,0,0,0);
}
After building the module, load and execute it from the target shell:
-> ld < hello.out
-> helloStart
Expected output:
Hello Wind River
๐ก Accessing Processing System GPIO #
Peripherals in the Zynq Processing System are memory mapped.
Example: toggle LED connected to MIO pin 10.
#include <stdio.h>
#include <unistd.h>
#include <sysLib.h>
#define GPIO_BASE 0xE000A000
#define GPIO_DIRM_0 0x204
#define GPIO_OEN_0 0x208
#define GPIO_DATA_0 0x040
#define LED_MASK (1 << 10)
void gpioBlink(void)
{
UINT32 val = LED_MASK;
sysOutLong(GPIO_BASE + GPIO_DIRM_0, LED_MASK);
sysOutLong(GPIO_BASE + GPIO_OEN_0, LED_MASK);
while (1)
{
sysOutLong(GPIO_BASE + GPIO_DATA_0, val);
taskDelay(sysClkRateGet());
val ^= LED_MASK;
}
}
This example toggles the LED once per second.
๐ Accessing Programmable Logic Peripherals #
Custom peripherals implemented in FPGA logic are accessed through AXI memory regions.
Example AXI GPIO driver:
#include <stdio.h>
#include <taskLib.h>
#include <sysLib.h>
#define AXI_GPIO_BASE 0x41200000
#define AXI_GPIO_DATA 0x00
#define AXI_GPIO_TRI 0x04
void axiGpioDemo(void)
{
UINT32 val = 0;
sysOutLong(AXI_GPIO_BASE + AXI_GPIO_TRI, 0x0);
while (1)
{
sysOutLong(AXI_GPIO_BASE + AXI_GPIO_DATA, val);
printf("GPIO value: %u\n", val);
val++;
taskDelay(sysClkRateGet());
}
}
Before accessing this peripheral, its address range must be added to the BSP MMU configuration.
Example MMU mapping entry:
{
0x41200000,
0x41200000,
PAGE_SIZE,
MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK |
MMU_ATTR_DEVICE_SHARED_MSK,
MMU_ATTR_VALID | MMU_ATTR_SUP_RWX |
MMU_ATTR_DEVICE_SHARED
},
After rebuilding the kernel, the PL peripheral becomes accessible to VxWorks applications.
๐งพ Conclusion #
Running VxWorks on the Zynq-7000 platform involves several coordinated steps:
- Understanding the BootROM โ FSBL โ Bootloader startup sequence
- Building the VxWorks kernel and bootloader
- Generating a boot image using bootgen
- Booting the system from SD card or FTP
- Developing applications using Downloadable Kernel Modules
Once the environment is configured, developers can leverage both the ARM processing system and FPGA programmable logic to build powerful real-time embedded systems.
This combination of VxWorks reliability and Zynq heterogeneous architecture provides a flexible platform for advanced embedded designs.