Ug1209 Embedded Design Tutorial
Ug1209 Embedded Design Tutorial
MPSoC: Embedded
Design Tutorial
Chapter 1: Introduction
About This Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
How Zynq UltraScale+ Devices Offer a Single Chip Solution. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
How the Vivado Tools Expedite the Design Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
What You Need to Set Up Before Starting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Introduction
Note: To install SDK as part of the Vivado Design Suite, you must choose to include SDK in the
installer. See Xilinx Software Development Kit, page 8.
The examples in this document were created using the Xilinx tools running on Windows 10,
64-bit operating system, and PetaLinux on Linux 64-bit operating system. Other versions of
the tools running on other Window installs might provide varied results. These examples
focus on introducing you to the following aspects of embedded design.
Note: The sequence mentioned in the tutorial steps for booting Linux on the hardware is specific to
the PetaLinux tools released for 2019.1, which must be installed on the Linux host machine for
exercising the Linux portions of this document.
• Chapter 2, Zynq UltraScale+ MPSoC Processing System Configuration describes
creation of a system with the Zynq UltraScale+ MPSoC Processing System (PS) and
running a simple “Hello World” application on Arm® Cortex®-A53 and Cortex-R5
processors. This chapter is an introduction to the hardware and software tools using a
simple design as the example.
• Chapter 3, Build Software for PS Subsystems describes steps to configure and build
software for processing blocks in processing system, including application processing
unit (APU), real-time processing unit (RPU), and platform management unit (PMU).
• Chapter 4, Debugging with SDK provides an introduction to debugging software using
the debug features of the Xilinx Software Development Kit (SDK). This chapter uses the
previous design and runs the software bare metal (without an OS) to show how to
debug. This chapter also lists Debug configurations for Zynq UltraScale+ MPSoC.
• Chapter 5, Boot and Configuration shows integration of components to configure and
create Boot images for a Zynq UltraScale+ system. The purpose of this chapter is to
understand how to integrate and load Boot loaders.
• Chapter 6, System Design Examples highlights how you can use the software blocks you
configured in Chapter 3 to create a Zynq UltraScale+ system.
• Appendix B, Additional Resources and Legal Notices provides links to additional
resources related to this guide.
Example Project
The best way to learn a tool is to use it. This guide provides opportunities for you to work
with the tools under discussion. Specifications for sample projects are given in the example
sections, along with an explanation of what is happening behind the scenes. Each chapter
and examples are meant to showcase different aspects of embedded design. The example
takes you through the entire flow to complete the learning and then moves on to another
topic.
Additional Documentation
Additional documentation is listed in Appendix B, Additional Resources and Legal Notices.
The Programmable Logic Section, in addition to the programmable logic cells, also comes
integrated with few high performance peripherals, including the following:
The PS and the PL in Zynq UltraScale+ can be tightly or loosely coupled with a variety of
high performance and high bandwidth PS-PL interfaces.
To simplify the design process for such sophisticated devices, Xilinx offers the Vivado
Design Suite, Xilinx Software Development Kit (SDK), and PetaLinux Tools for Linux. This set
of tools provides you with everything you need to simplify embedded system design for a
device that merges an SoC with an FPGA. This combination of tools enables hardware and
software application design, code execution and debug, and transfer of the design onto
actual boards for verification and validation.
When you install the Vivado Design Suite, SDK is available as an optional software tool that
you must choose to include in your installation. For details, refer to Installation
Requirements, page 10.
PetaLinux Tools
The PetaLinux tools set is an Embedded Linux System Development Kit. It offers a
multi-faceted Linux tool flow, which enables complete configuration, build, and deploy
environment for Linux OS for the Xilinx Zynq devices, including Zynq UltraScale+.
For more information, see the PetaLinux Tools Documentation: Reference Guide (UG1144)
[Ref 7].
The PetaLinux Tools design hub provides information and links to documentation specific to
PetaLinux Tools. For more information, see Documentation Navigator and Design Hubs.
You can accomplish all your hardware system development using the Vivado tools along
with IP integrator. This includes specification of the Zynq UltraScale+ Processing System,
peripherals, and the interconnection of these components, along with their respective
detailed configuration.
SDK is used for software development and is available either as part of the Vivado Design
Suite, or it can be installed and used without any other Xilinx tools installed on the machine
on which it is loaded. SDK can also be used to debug software applications.
The Zynq UltraScale+ Processing System (PS) can be booted and run without programming
the FPGA (programmable logic or PL). However, in order to use any soft IP in the fabric, or
to bond out PS peripherals using EMIO, programming of the PL is required. You can
program the PL using SDK or using the Vivado Hardware Manager.
For more information on the embedded design process, refer to the Vivado Design Suite
Tutorial: Embedded Processor Hardware Design (UG940) [Ref 2].
For more information about the Zynq UltraScale+ Processing System, refer to the Zynq
UltraScale+ Processing System Product Guide (PG201) [Ref 9].
Installation Requirements
Vivado Design Suite and SDK
Make sure that you have installed the 2019.1 Vivado HL System Edition tools. Visit
https://www.xilinx.com/support/download.html to confirm that you have the latest tools
version.
Ensure that you have both the Vivado Design Suite and SDK Tools installed. When you
install the Vivado Design Suite, SDK is available as an optional software tool that you must
elect to include in your installation by selecting the Software Development Kit check box,
as shown in the following figure. To install SDK by itself, you can deselect the other software
products and run the installer with only Software Development Kit selected.
IMPORTANT: Installation does not create an SDK desktop shortcut by default. You can launch the SDK
binary from C:\Xilinx\SDK\2019.1\bin\xsdk.bat.
PetaLinux Tools
Install the PetaLinux Tools to run through the Linux portion of this tutorial. PetaLinux tools
run under the Linux host system running one of the following:
This can use either a dedicated Linux host system or a virtual machine running one of these
Linux operating systems on your Windows development platform.
When you install PetaLinux Tools on your system of choice, you must do the following:
• Add common system packages and libraries to the workstation or virtual machine. For
more information, see the Installation Requirements from the PetaLinux Tools
Documentation: Reference Guide (UG1144) [Ref 7].
Prerequisites
• 8 GB RAM (recommended minimum for Xilinx tools)
• 2 GHz CPU clock or equivalent (minimum of 8cores)
• 100 GB free HDD space
By default, the installer installs the package as a subdirectory within the current directory.
Alternatively, you can specify an installation path. Run the downloaded PetaLinux installer.
Note: Ensure that the PetaLinux installation path is kept short. The PetaLinux build will fail if the path
exceeds 255 characters.
bash> ./petalinux-v2019.1-final-installer.run
Refer to Chapter 3, Build Software for PS Subsystems for additional information about the
PetaLinux environment setup, project creation, and project usage examples. A detailed
guide on PetaLinux Installation and usage can be found in the PetaLinux Tools
Documentation: Reference Guide (UG1144) [Ref 7].
Software Licensing
Xilinx software uses FLEXnet licensing. When the software is first run, it performs a license
verification process. If the license verification does not find a valid license, the license
wizard guides you through the process of obtaining a license and ensuring that the license
can be used with the tools installed. If you do not need the full version of the software, you
can use an evaluation license.For installation instructions and information, see the Vivado
Design Suite User Guide: Release Notes, Installation, and Licensing (UG973) [Ref 3].
The Zynq UltraScale+ device consists of Quad-Core Arm® Cortex®-A53 based APU,
Dual-Core Arm Cortex-R5 RPU, Mali 400 MP2 GPU, and many hard Intellectual Property
components (IPs), and Programmable Logic (PL). This offering can be used in two ways:
• The Zynq UltraScale+ PS can be used in a standalone mode, without attaching any
additional fabric IP.
• IP cores can be instantiated in fabric and attached to the Zynq UltraScale+ PS as a
PS+PL combination.
In addition to the basic PS configuration, this chapter will briefly touch upon the concept of
Isolation Configuration to create subsystems with protected memory and peripherals. This
advanced configuration mode in the PS Block enables you to setup subsystems comprising
Masters with dedicated memory and peripherals. The protection is provided by the XMPU
and the XPPU in Zynq UltraScale+ PS block. The isolation configuration also allows the
TrustZone settings for components to create and configure the systems in Secure and
Non-Secure Environments.
4. Click Finish. The New Project wizard closes and the project you just created opens in the
Vivado design tool.
2. Use the following information to make selections in the Create Block Design wizard.
3. Click OK.
The Diagram window view opens with a message that states that this design is empty. To
get started, you will next add some IP from the catalog.
The Zynq UltraScale+ MPSoC processing system IP block appears in the Diagram view,
as shown in the following figure.
X-Ref Target - Figure 2-2
1. Double-click the ZYNQ UltraScale+ Processing System block in the Block Diagram
window.
The Re-customize IP dialog box opens, as shown in the following figure. Notice that by
default, the processor system does not have any peripherals connected
X-Ref Target - Figure 2-3
2. Click Cancel to exit the dialog box without making changes to the design.
TIP: In the Block Diagram window, notice the message stating that designer assistance is available, as
shown in the following figure. When designer assistance is available, you can click the link to have
Vivado perform that step in your design.
X-Ref Target - Figure 2-4
3. You will now use a preset template created for the ZCU102 board. Click the Run Block
Automation Link.
4. Click OK to accept the default processor system options and make default pin
connections.
This configuration wizard enables many peripherals in the Processing System with some
multiplexed I/O (MIO) pins assigned to them according to the board layout of the
ZCU102 board. For example, UART0 and UART1 are enabled. The UART signals are
connected to a USB-UART connector through UART to the USB converter chip on the
ZCU102 board.
5. To verify, double-click on the Zynq UltraScale+ Processing System block in the block
diagram window.
Note the check marks that appear next to each peripheral name in the Zynq UltraScale+
device block diagram, signifying the I/O Peripherals that are active.
X-Ref Target - Figure 2-5
6. In the block diagram, click one of the green I/O Peripherals, as shown in the previous
figure. The IO Configuration dialog box opens for the selected peripheral.
X-Ref Target - Figure 2-6
This page enables you to configure low speed and high speed peripherals. For this
example, you will continue with the basic connection enabled using Board preset for
ZCU102.
For this example, because there is no design in PL, you can disable the PS-PL interface.
In this case, AXI HPM0 FPD and AXI HPM1 FPD Master Interfaces can be disabled.
Isolation Configuration
This section is for reference only. It explains the importance of Isolation Configuration
settings for different use-cases. Different use-cases may need to establish Isolation
Configurations on an as-need basis. Isolation configuration is optional and you can set it as
per your system requirement. Safety/Security critical use cases typically require isolation
between safe/non-safe or secure/non-secure portions of the design. This requires a
safe/secure region that contains a master (such as the RPU) along with its slaves (memory
regions and peripherals) to be isolated from non-safe or non-secure portions of the design.
In such cases, the TrustZone attribute can be applied to the dedicated peripherals or
memory locations. In this way only a valid and trusted master can access the secure slaves.
An other use-case requiring Isolation is for Platform and Power management. In this case,
independent subsystems can be created with Masters and slaves. This is used to identify
dependencies during run-time power management or warm restart for upgrade or recovery.
An example of this use-case can be found on the Zynq UltraScale+ Restart solution wiki
page. The Xilinx Memory Protection Unit (XMPU) and Xilinx Peripheral Protection Unit
(XPPU) in Zynq UltraScale+ provide hardware protection for memory and peripherals. These
protection units complement the isolation provided by TrustZone (TZ) and the Zynq
UltraScale+ MPSoC SMMU.
The XMPU and XPPU in Zynq UltraScale+ allow Isolation of resources at SoC level. Arm
MMU and Trustzone enable Isolation within Arm Cortex-A53 Core APU. Hypervisor and
SMMU allows setting Isolation between Cortex-A53 cores. From a tools standpoint, these
Protection Units can be configured using Isolation Configuration in Zynq UltraScale+ PS IP
wizard. The Isolation settings are exported as an initialization file which is loaded as a part
of the bootloader, in this case the First Stage Boot Loader (FSBL). For more details, see the
Zynq UltraScale+ MPSoC Technical Reference Manual (UG1085) [Ref 5].
1. Double-click the Zynq UltraScale+ Processing System in the block diagram window, if
it is not open.
2. Select Switch To Advanced Mode.
This tutorial does not use Isolation Configuration and hence, no Isolation related
settings are requested.
1. Right-click in the white space of the Block Diagram view and select Validate Design.
Alternatively, you can press the F6 key.
2. A message dialog box opens and states "Validation successful. There are no errors or
critical warnings in this design."
The Create HDL Wrapper dialog box opens. You will use this dialog box to create a HDL
wrapper file for the processor subsystem.
TIP: The HDL wrapper is a top-level entity required by the design tools.
7. Select Let Vivado manage wrapper and auto-update and click OK.
8. In the Block Diagram, Sources window, under Design Sources, expand
edt_zcu102_wrapper.
9. Right-click the top-level block diagram, titled edt_zcu102_i : edt_zcu102
(edt_zcu102.bd) and select Generate Output Products.
The Generate Output Products dialog box opens, as shown in the following figure.
X-Ref Target - Figure 2-9
This step builds all required output products for the selected source. For example,
constraints do not need to be manually created for the IP processor system. The Vivado
tools automatically generate the XDC file for the processor subsystem when Generate
Output Products is selected.
11. Click OK, if you see the message: “Out-of-context module run was launched for
generating output products”.
12. When the Generate Output Products process completes, click OK.
13. In the Block Diagram Sources window, click the IP Sources tab. Here you may see the
output products that you just generated, as shown in the following figure.
X-Ref Target - Figure 2-10
The Export Hardware dialog box opens. Make sure that the Export to field is set to the
default option of <Local to Project>.
X-Ref Target - Figure 2-11
TIP: The hardware is exported in a ZIP file (<project wrapper>.hdf). When SDK launches, the file
unzips automatically, and you can find all the files in the SDK project hardware platform folder.
TIP: You can also start SDK in standalone mode and use the exported hardware. To do this, start SDK,
and while creating a new project, point to the new target hardware that was exported.
SDK opens. Notice that when SDK launches, the hardware description file is loaded
automatically.
The system.hdf tab shows the address map for the entire Processing System, as
shown in the following figure.
The Vivado design tool exported the Hardware Platform Specification for your design
(system.hdf in this example) to SDK. In addition to system.hdf, the following additional
files are exported to SDK:
• psu_init.c
• psu_init.h
• psu_init.tcl
• psu_init_gpl.c
• psu_init_gpl.h
• psu_init.html
The system.hdf file opens by default when SDK launches. The address map of your
system read from this file is shown by default in the SDK window.
What's Next?
Now, you can start developing the software for your project using SDK. The next sections
help you create a software application for your hardware platform.
IMPORTANT: Ensure that SW6 Switch, on the bottom right, is set to JTAG boot mode as shown in the
following figure.
X-Ref Target - Figure 2-14
4. Power on the ZCU102 board using the switch indicated in the figure below.
Alternately, you can open SDK with a default workspace and later switch it to the correct
workspace by selecting File > Switch Workspace and then selecting the workspace.
6. Open a serial communication utility for the COM port assigned on your system. SDK
provides a serial terminal utility, which will be used throughout the tutorial; select
Window > Show View > Other > Terminal to open it.
7. Click the Connect button to set the serial configuration and connect it.
X-Ref Target - Figure 2-16
9. Click the Settings button to open the Terminal Settings dialog box.
10. Verify the port details in the device manager.
UART-0 terminal corresponds to COM port with Interface-0. For this example, UART-0
terminal is set by default, so for the COM port, select the port with interface-0.
The following figure shows the standard configuration for the Zynq UltraScale+ MPSoC
Processing System.
X-Ref Target - Figure 2-17
12. Use the information in the table below to make your selections in the wizard screens.
Table 2-3: New Application Project Settings for Standalone APU Application
Wizard Screen System Properties Setting or Command to Use
Application Project Project Name test_a53
Use Default Location Select this option
OS Platform standalone
Hardware Platform edt_zcu102_wrapper_hw_platform_0
Processor psu_cortexa53_0
Language C
Compiler 64-bit
Hypervisor Guest No
Board Support Package Select Create New and provide the name
of test_a53_bsp.
Templates Available Templates Hello World
SDK creates the test_a53 application project and test_a53_bsp board support
package (BSP) project under the Project Explorer. It automatically compiles both and
creates the ELF file.
The configurations associated with the application are pre-populated in the Main tab of
the launch configurations.
15. Click the Target Setup tab and review the settings.
Notice that there is a configuration path to the initialization Tcl file. The path of
psu_init.tcl is mentioned here. This file was exported when you exported your
design to SDK; it contains the initialization information for the processing system.
Note: There was no bitstream download required for the above software application to be
executed on the Zynq UltraScale+ evaluation board. The Arm Cortex-A53 quad core is already
present in the processing system. Basic initialization of this system to run a simple application is
done by the Device initialization Tcl script.
18. Power cycle the board and retain same connections and board settings for the next
section.
From UART0, the "Hello world" string goes byte-by-byte to the serial terminal application
running on the host machine, which displays it as a string.
IMPORTANT: Ensure that the SW6 switch is set to JTAG boot mode as shown in Figure 2-14 .
Alternately, you can open SDK with a default workspace and later switch it to the correct
workspace by selecting File > Switch Workspace and then selecting the workspace.
6. Open a serial communication utility for the COM port assigned on your system. SDK
provides a serial terminal utility, which will be used throughout the tutorial; select
Window > Show View > Terminal to open it.
The Com -port details can be found in the device manager on host machine. UART-0
terminal corresponds to Com-Port with Interface-0. For this example, UART-0 terminal is
set by default, so for the Com-port, select the port with interface-0.
The following figure shows the standard configuration for the Zynq UltraScale+ MPSoC
Processing System.
X-Ref Target - Figure 2-20
11. Use the information in the following table to make your selections in the wizard screens.
SDK creates the new run configuration, named hello_world_r5 Debug. The
configurations associated with the application are pre-populated in the Main tab of the
launch configurations.
14. Click the Target Setup tab and review the settings.
Notice that there is a configuration path to the initialization Tcl file. The path of
psu_init.tcl is mentioned here. This file was exported when you exported your
design to SDK; it contains the initialization information for the processing system.
From UART0, the "Hello world" string goes byte-by-byte to the serial terminal
application running on the host machine, which displays it as a string.
Additional Information
Board Support Package
The board support package (BSP) is the support code for a given hardware platform or
board that helps in basic initialization at power up and helps software applications to be run
on top of it. It can be specific to some operating systems with bootloader and device
drivers.
TIP: If you would like to regenerate the BSP, right click the BSP project under the Project Explorer and
select Re-generate BSP Sources.
If you would like to change the target BSP after project creation:
1. Create a New Board Support Package for your target.
2. In the Project Explorer, right click your application project and select Change Referenced BSP, and
point the new BSP you want to set.
Standalone OS
Standalone is a simple, low-level software layer. It provides access to basic processor
features such as caches, interrupts, and exceptions, as well as the basic processor features
of a hosted environment. These basic features include standard input/output, profiling,
abort, and exit. It is a single threaded semi-hosted environment.
IMPORTANT: The application you ran in this chapter was created on top of the Standalone OS. The BSP
that your software application targets is selected during the New Application Project creation process.
If you would like to change the target BSP after project creation, you can manage the target BSP by
right-clicking the software application and selecting Change Referenced BSP.
In Chapter 2, you created and exported the hardware platform from Vivado. This hardware
platform contains the hardware handoff file, the processing system initialization files
(psu_init), and the PL bitstream. In this chapter, you will use the hardware platform in
Xilinx® SDK and PetaLinux to configure software for the processing system.
This chapter serves two important purposes. One, it helps you build and configure the
software components that can be used in future chapters. Second, it describes the build
steps for a specific PS subsystem.
This section demonstrates configuring these units using system software. This can be
achieved either at the boot level using First Stage Boot Loader (FSBL) or via system
firmware, which is applicable to the platform management unit (PMU).
You will use the Zynq UltraScale+ hardware platform in SDK to perform the following tasks:
1. Create a First Stage Boot Loader (FSBL) for the Arm Cortex-A53 64-bit quad-core
processor unit (APU) and the Cortex-R5 dual-core real-time processor unit (RPU).
2. Create bare-metal applications for APU and RPU.
3. Create platform management unit (PMU) firmware for the platform management unit
using Xilinx SDK.
In addition to the bare-metal applications, this chapter also describes building U-Boot and
Linux Images for the APU. The Linux images and U-Boot can be configured and built using
the PetaLinux build system.
In this example, you will create an FSBL image targeted for Arm Cortex-A53 core 0.
By default, the FSBL is configured to show basic print messages. Next, you will modify the
FSBL build settings to enable debug prints.
For a list of the possible debug options for FSBL, refer to the fsbl_a53 > src >
xfsbl_debug.h file.
6. Click OK to accept the changes and close the Settings dialog box.
7. Right-click the fsbl_a53 application and select Clean Project.
Note: If the Project > Build Automatically setting is selected, SDK automatically builds the
application for you.
8. The FSBL executable is now saved as fsbl_a53 > debug > fsbl_a53.elf.
In this tutorial, the application name fsbl_a53 is to identify that the FSBL is targeted for
APU (the Arm Cortex-A53 core).
Create First Stage Boot Loader for Arm Cortex-R5 Based RPU
You can also create an FSBL for Arm Cortex-R5 Core by doing the following.
1. Click File > New > Application Project to open the New Project dialog box.
X-Ref Target - Figure 3-5
2. Use the information in the following table to make your selections in the New Project
wizard.
3. Click Finish.
This creates the board Support package and an FSBL application targeted for RPU Arm
Cortex-R5 Core 0 in Zynq UltraScale+.
For this example, you will use the test_a53 application that you created in Example Project:
Running the “Hello World” Application from Arm Cortex-A53 in Chapter 2
In test_a53, you selected a simple Hello World application. This application can be loaded
on APU by FSBL running on either APU or RPU.
SDK also provides few other bare-metal applications templates to make it easy to start
running applications on Zynq UltraScale+ devices. Alternatively, you can also select the
Empty Application template and copy or create your custom application source code in the
application folder structure.
This opens the helloworld.c source file for the test_a53 application.
Note: The r5_bsp board support package was created when you followed the steps in Create
First Stage Boot Loader for Arm Cortex-R5 Based RPU.
3. Click Finish.
The New Project wizard closes and SDK creates the testapp_r5 application project,
which can be found in the Project Explorer.
° Size: 0x10000000
The linker script modification is shown in following figure. The following figure is for
representation only. Actual memory regions may vary in case of Isolation settings.
X-Ref Target - Figure 3-8
This modification in the linker script ensures that the RPU bare-metal application
resides above 0x70000000 base address in the DDR, and occupies no more than 256 MB
of size.
10. Verify that the firmware was compiled and linked successfully to generate the
executable in pmu_fw > Debug > pmu_fw.elf.
IMPORTANT: This example needs a Linux Host machine. PetaLinux Tools Documentation: Reference
Guide (UG1144) [Ref 7] for information about dependencies for PetaLinux 2019.1.
IMPORTANT: This example uses the ZCU102 PetaLinux BSP to create a PetaLinux project. Ensure that
you have downloaded the ZCU102 BSP for PetaLinux as instructed in PetaLinux Tools, page 11.
The ZCU102 Petalinux-BSP is the default ZCU102 Linux BSP. For this example, you
reconfigure the PetaLinux Project based on the Zynq UltraScale+ hardware platform that
you configured using Vivado Design Suite in Chapter 2.
This command opens the PetaLinux Configuration window. If required, make changes in
the configuration. For this example, the default settings from the BSP are sufficient to
generate required boot images.
The following steps will verify if PetaLinux is configured to create Linux and boot images
for SD Boot.
The following steps will build the Linux images, verify them, and generate the boot
image.
11. Modify Device Tree to disable Heartbeat LED and SW19 push button, from the device
tree. Due to this the RPU R5-0 can use PS LED and SW19 switch for other designs in this
tutorial. This can be done by adding the following to the system-user.dtsi which
can be found in the following location:
<PetaLinux-project>/project-spec/meta-user/recipes-bsp/device-tr
ee/files/system-user.dtsi
13. In <PetaLinux-project>, build the Linux images using the following command:
$ petalinux-build
14. After the above statement executes successfully, verify the images and the timestamp in
the images directory in the PetaLinux project folder using the following commands:
$ cd images/linux/
$ ls -al
The Logs indicate that the above command includes PMU_FW and ATF in BOOT.BIN. You
can also add --pmufw <PMUFW_ELF> and --atf <ATF_ELF> in the above command.
Refer $ petalinux-package --boot --help for more details.
Note: The option to add bitstream, that is --fpga is missing from above command intentionally. This
is because the hardware configuration so far is only based on PS with no design in PL. In case a
bitstream is present in the design, --fpga can be added in the petalinux-package command as
shown below:
petalinux-package --boot --fsbl zynqmp_fsbl.elf --fpga system.bit --pmufw pmufw.elf
--atf bl31.elf --u-boot u-boot.elf
7. For port settings, verify COM port in the device manager and select the COM port with
interface-0.
8. Turn on the ZCU102 Board using SW1, and wait until Linux loads on the board.
1. Before starting this example, create a backup of the boot images created for SD card
setup using the following commands:
$ cd <Petalinux-project-path>/xilinx-zcu102-2019.1/images/linux/
$ mkdir sd_boot
$ cp image.ub sd_boot/
$ cp u-boot.elf sd_boot/
$ cp BOOT.BIN sd_boot/
c. Based on this, the offset for Linux Images is calculated as 0x1E40000 in QSPI Flash
device. This will be used in Chapter 5, while creating Boot image for QSPI
Boot-mode.
The following steps will set the Linux System Memory Size to about 1.79 GB.
In this chapter, you learned how to configure and compile Software blocks for Zynq
UltraScale+ devices using Xilinx tools. You will use these images in Chapter 6 to create Boot
images for a specific design example.
Next, you will debug software for Zynq UltraScale+ devices using Xilinx SDK in Chapter 4,
Debugging with SDK.
The SDK debugger enables you to see what is happening to a program while it executes.
You can set breakpoints or watchpoints to stop the processor, step through program
execution, view the program variables and stack, and view the contents of the memory in
the system.
Debug Executable
HOI
6SHFLI\
&UHDWH'HEXJ 6'.'HEXJ
KZBVHUYHU
&RQILJXUDWLRQ 3HUVSHFWLYH
GHWDLOV
KZBVHUYHU
3URJUDPUXQQLQJ
RQ+DUGZDUH
RU,66
;
• Executable ELF File: To debug your application, you must use an Executable and
Linkable Format (ELF) file compiled for debugging. The debug ELF file contains
additional debug information for the debugger to make direct associations between
the source code and the binaries generated from that original source. To manage the
build configurations, right-click the software application and select Build
Configurations > Manage.
• Debug Configuration: To launch the debug session, you must create a debug
configuration in SDK. This configuration captures options required to start a debug
session, including the executable name, processor target to debug, and other
information. To create a debug configuration, right-click your software application and
select Debug As > Debug Configurations.
• SDK Debug Perspective: Using the Debug perspective, you can manage the
debugging or running of a program in the Workbench. You can control the execution of
your program by setting breakpoints, suspending launched programs, stepping
through your code, and examining the contents of variables. To view the Debug
Perspective, select Window > Open Perspective > Debug.
You can repeat the cycle of modifying the code, building the executable, and debugging
the program in SDK.
Note: If you edit the source after compiling, the line numbering will be out of step because the
debug information is tied directly to the source. Similarly, debugging optimized binaries can also
cause unexpected jumps in the execution trace.
If you did not create a hello world application on APU or RPU, follow the steps in Create
Bare-Metal Application for Arm Cortex-A53 based APU, page 40 to create a new hello world
application.
After you create the Hello World Application, work through below example to debug the
software using SDK.
1. Follow the steps in Example Project: Running the “Hello World” Application from Arm
Cortex-A53 to set the target in JTAG mode and power ON.
2. In the C/C++ Perspective, right-click the test_a53 Project and select Debug As >
Launch on Hardware (System Debugger).
Note: The above step launches the System Debugger in the Debug perspective based on the
project settings. Alternatively, you can also create a Debug configuration which looks like
Figure 4-2.
Note: If the Debug Perspective window does not automatically open, select Window >
Perspective >Open Perspective > Other, then select Debug in the Open Perspective wizard.
The processor is currently sitting at the beginning of main() with program execution
suspended at line 0x0000000000000980. You can confirm this information in the
Disassembly view, which shows the assembly-level program execution also suspended
at 0x0000000000000980.
Note: If the Disassembly view is not visible, select Window > Show View > Disassembly.
3. The helloworld.c window also shows execution suspended at the first executable
line of C code. Select the Registers view to confirm that the program counter, pc register,
contains 0x0000000000000980.
Note: If the Registers window is not visible, select Window > Show View > Registers.
4. Double-click in the margin of the helloworld.c window next to the line of code that
reads print(“Hello World\n\r”);. This sets a breakpoint at the printf
command. To confirm the breakpoint, review the Breakpoints window.
Note: If the Breakpoints window is not visible, select Window > Show View > Breakpoints.
5. Select Run > Step Into to step into the init_platform () routine.
6. Select Run > Resume to continue running the program to the breakpoint.
Program execution stops at the line of code that includes the printf command. The
Disassembly and Debug windows both show program execution stopped at
0x0000000000000984.
Note: The execution address in your debugging window might differ if you modified the hello
world source code in any way.
7. Select Run > Resume to run the program to conclusion.
When the program completes, the Debug window shows that the program is suspended
in a routine called exit. This happens when you are running under control of the
debugger.
8. Re-run your code several times. Experiment with single-stepping, examining memory,
breakpoints, modifying code, and adding print statements. Try adding and moving
views.
TIP: You can use SDK tool debugging shortcuts for step-into (F5), step-return (F7), step-over (F6), and
resume (F8).
Additionally, you can debug in the command line mode using XSDB, which is encapsulated
as a part of XSCT. In this example, you will debug the bare-metal application testapp_r5
using XSCT.
This example is just to demonstrate the command line debugging possibility using
XSDB/XSCT. Based on the requirement, you can choose to debug the code using either the
System Debugger graphical interface or the command line debugger in XSCT. All XSCT
commands are scriptable and this applies to the commands covered in this example.
Set Up Target
1. Connect a USB cable between USB-JTAG J2 connector on target and the USB port on the
host machine.
2. Set the board in JTAG Boot mode, where SW6 is set as shown in following figure.
Alternatively, you can also open the XSCT console from Xilinx > XSCT Console.
5. In the XSCT Console, connect to the target over JTAG using the connect command:
xsct% connect
6. Command targets lists the available targets and allows you to select a target through its
ID.
The targets are assigned IDs as they are discovered on the JTAG chain, so the target IDs
can change from session to session.
For non-interactive usage such as scripting, the -filter option can be used to select
a target instead of selecting the target through its ID:
xsct% targets
The command targets now lists the targets and also shows the selected target
highlighted with as asterisk (*) mark. You can also use target number to select a Target,
as shown in the following figure.
X-Ref Target - Figure 4-6
Note the {} used in above command. These are required on windows machine to enable
backward slash (\) in paths. These braces can be avoided by using forward "/" in paths.
Considering Linux paths, use forward "/" because the paths in XSCT in Linux can work as
is, without any braces.
The command rst -processor clears the reset on an individual processor core.
This step is important, because when Zynq MPSoC boots up JTAG boot mode, all the
A53 and R5 cores are held in reset. You must clear the resets on each core, before
debugging on these cores. The rst command in XSDB can be used to clear the resets.
Note: The command rst -cores clears resets on all the processor cores in the group (such as
APU or RPU), of which the current target is a child. For example, when A53 #0 is the current
target, rst -cores clears resets on all the A53 cores in APU.
xsct% dow {C:\edt\edt_zcu102\edt_zcu102.sdk\testapp_r5\Debug\testapp_r5.elf}
Or
At this point, you can see the sections from the ELF file downloaded sequentially. The
XSCT prompt can be seen after successful download.
Now, configure a serial terminal (Tera Term, Mini com, or the SDK Serial Terminal
interface for UART-1 USB-serial connection).
2. For port settings, verify the COM port in the device manager. There are four USB UART
interfaces exposed by the ZCU102 board. Select the COM port associated with the
interface with the lowest number. So in this case, for UART-0, select the COM port with
interface-0.
3. Similarly, for UART-1, select COM port with interface-1. Remember that R5 BSP has been
configured to use UART-1, and so R5 application messages will appear on the COM port
with UART-1 terminal.
The following informative messages will be displayed when the core hits the breakpoint.
3. At this point, you can view registers when the core is stopped.
xsct% rrd
5. Step over a line of the source code and view the stack trace.
xsct% nxt
Info: Cortex-R5 #0 (target 6) Stopped at 0x100490 (Step)
xsct% bt
You can use the help running command to get a list of possible options for running
or debugging an application using XSCT.
X-Ref Target - Figure 4-9
At this point, you can see the R5 application print message on UART-1 terminal.
Removing optimization can lead to increased code size, resulting in failure to build the
FSBL. To disable the optimization (for debugging), some FSBL features (that are not
required), need to be disabled in xfsbl_config.h file of FSBL.
Now, create a new FSBL for this section instead of modifying the FSBL created in Chapter 3,
Build Software for PS Subsystems. This is to avoid disturbing the FSBL_a53 project, which
will be used extensively in rest of the chapters in this tutorial.
4. Use the information in the following table to make your selections in the New Project
dialog box.
5. Click Finish.
SDK creates the board Support package and an FSBL application. Now disable
Optimizations as shown below.
10. Go to the fsbl_debug>src>fsbl_config.h file. In the FSBL code include the options and
disable the following:
You can either debug the FSBL like any other standalone application (as shown in
Debugging Software Using SDK and Debugging Using XSCT), or debug FSBL as a part of a
Boot image by using the ‘Attach to running target’ mode of System Debugger.
This boot sequence also includes loading the PMU Firmware for the Platform Management
Unit (PMU). You can achieve the above configurations using a Xilinx SDK and PetaLinux Tool
flow. While Chapter 3 focused only on creating software blocks for each processing unit in
the PS, this chapter explains how these blocks can be loaded as a part of a bigger system.
The Create Boot Image wizard (Bootgen - Command Line tool) from SDK is used in
generating Boot Image. Create Boot Image Wizard’s or Bootgen’s principle function is to
integrate the partitions (hardware-bitstream and software), and allow you to specify the
security options in the design. It can also create the cryptographic keys.
Functionally, Bootgen uses a Bootgen Image Format (BIF) file as an input, and generates a
single file image in binary BIN or MCS format. Bootgen outputs a single file image which is
loaded into NVM (QSPI, SD Card). The Bootgen GUI facilitates the creation of the BIF input
file.
This chapter makes use of Processing System block. Design Example 1: Using GPIOs, Timers,
and Interrupts, covers Boot-image which will include the PS partitions used in this chapter
and a bitstream targeted for PL fabric.
System Software
The following system software blocks cover most of the Boot and Configuration for this
chapter. For detailed boot flow and various Boot sequences, refer to the “System Boot and
Configuration” chapter in the Zynq UltraScale+ MPSoC: Software Developers Guide
(UG1137) [Ref 6].
The First Stage Boot Loader initializes important blocks in the processing subsystem. This
includes clearing the reset of the processors, initializing clocks, memory, UART, and so on
before handing over the control of the next partition in DDR, to either RPU or APU. In this
example, the FSBL loads bare-metal application in DDR and handsoff to RPU R5 in Lockstep
mode, and similarly loads U-Boot to be executed by APU A53 Core-0. For more information,
see the Zynq UltraScale+ MPSoC: Software Developers Guide (UG1137) [Ref 6].
For this chapter, you can use the FSBL executable that you created in Chapter 3. In FSBL
application, the xfsbl_translation_table.S differs from translation_table.S
(of A53) in only one aspect, to mark DDR region as reserved. This is to avoid speculative
access to DDR before it is initialized. Once the DDR initialization is done in FSBL, memory
attributes for DDR region is changed to “Memory” so that it is cacheable.
1. Using BootROM to load PMU Firmware, as described in Boot Sequence for SD-Boot
2. Using FSBL to load PMU Firmware, as described in Boot Sequence for QSPI Boot Mode
3. Load PMU Firmware in JTAG boot mode, as described in Boot Sequence for QSPI-Boot
Mode Using JTAG.
U-Boot
The U-Boot acts as a secondary boot loader. After the FSBL handoff, the U-Boot loads Linux
on Arm A53 APU. After FSBL, the U-Boot configures the rest of the peripherals in the
processing system based on board configuration. U-Boot can fetch images from different
memory sources like eMMC, SATA, TFTP, SD, and QSPI. For this example, U-Boot and all
other images are loaded from the SD card. Therefore, for this example, the Board will be set
to SD-boot mode.
U-Boot can be configured and built using the PetaLinux tool flow. For this example, you can
use the U-Boot image that you created in Chapter 3 or from the design files shared with this
document. See Design Files for This Tutorial, page 163 for information about downloading
the design files for this tutorial.
The FSBL loads ATF to be executed by APU, which keeps running in EL3 awaiting a service
request. The ATF starts at 0xFFFEA000. The FSBL also loads U-Boot in DDR to be executed by
APU, which loads Linux OS in SMP mode on APU. It is important to note that the PL
Bitstream should be loaded before ATF is loaded. The reason is FSBL uses the OCM region
which is reserved for ATF for holding a temporary buffer in the case where bitstream is
present in .BIN file. Because of this, if bitstream is loaded after ATF, FSBL will overwrite the
ATF image with its temporary buffer, corrupting ATF image. Hence, bitstream should be
positioned in .BIF before ATF and preferably immediately after FSBL and PMUFW.
The ATF (bl31.elf) is built by default in PetaLinux and can be found in the PetaLinux
Project images directory.
For more details on ATF, refer to the “Arm Trusted Firmware” section in the “Security”
chapter of the Zynq UltraScale+ MPSoC: Software Developers Guide (UG1137) [Ref 6].
For loading Linux on APU, the following images will be used from PetaLinux:
• ATF - bl31.elf
• U-Boot - u-boot.elf
• Linux images - image.ub, which contains:
° Kernel image
° Filesystem - rootfs.cpio.gz.u-boot
In addition to Linux on APU, this example also loads a bare-metal Application on RPU R5 in
Lockstep mode.
For this example, refer the testapp_r5 application that you created in Create Bare-Metal
Application for Arm Cortex-R5 based RPU, page 41.
Alternatively you can also find the testapp_r5.elf executable in the design files that
accompany this tutorial. See Design Files for This Tutorial, page 163 for information about
downloading the design files for this tutorial.
1. In the Create Boot Image dialog box, click Add to open the Add partition dialog box.
2. In the Add Partition dialog box, click Browse to select the FSBL executable.
3. For FSBL, ensure that the partition type is selected as bootloader and the correct
destination CPU is selected by the tool. The tool is configured to make this selection
based on the FSBL executable.
Note: Ignore the Exception Level drop down, as FSBL is set to EL3 by default. Also, leave the
Trustzone setting unselected for this example.
1. Click Add to open the Add Partition dialog box, shown in the following figure.
Now, add the U-Boot partition. You can find u-boot.elf for sd_boot mode in
<PetaLinux_project>/images/linux/sd_boot
You can also create BOOT.bin images using the BIF attributes and the Bootgen command.
the_ROM_image:
{
[bootloader, destination_cpu=a53-0]
[bootloader]C:\edt\edt_zcu102\edt_zcu102.sdk\fsbl_a53\Debug\fsbl_a53.elf
[pmufw_image]C:\edt\edt_zcu102\edt_zcu102.sdk\pmu_fw\Debug\pmu_fw.elf
[destination_cpu = a53-0, exception_level=el-3,
trustzone]C:\edt\design_files\bl31.elf
[destination_cpu =
r5-lockstep]C:\edt\edt_zcu102\edt_zcu102.sdk\testapp_r5\Debug\testapp_r5.elf
[destination_cpu = a53-0,
exception_level=el-2]C:\edt\design_files\sd_boot\u-boot.elf
}
SDK calls the following Bootgen command to generate the BOOT.bin image for this
configuration:
6. Start a terminal session, using Tera Term or Minicom depending on the host machine
being used, as well as the COM port and baud rate for your system, as shown in
following figure.
X-Ref Target - Figure 5-8
8. Select the COM port associated with the interface with the lowest number. In this case,
for UART-0, select the COM port with interface-0.
9. Similarly, for UART-1, select COM port with interface-1.
Remember that the R5 BSP has been configured to use UART-1, and so R5 application
messages will appear on the COM port with the UART-1 terminal.
10. Turn on the ZCU102 Board using SW1, and wait until Linux loads on the board.
At this point, you can see the initial Boot sequence messages on your Terminal Screen
representing UART-0.
You can see that the terminal screen configured for UART-1 also prints a message. This
is the print message from the R5 bare-metal Application running on RPU, configured to
use UART-1 interface. This application is loaded by the FSBL onto RPU.
The bare-metal application has been modified to include the UART interrupt example.
This application now waits in the waiting for interrupt (WFI) state until a user input is
encountered from Keyboard in UART-1 terminal.
X-Ref Target - Figure 5-9
Meanwhile, the boot sequence continues on APU and the images loaded can be
understood from the messages appearing on the UART-0 terminal. The messages are
highlighted in the following figure.
X-Ref Target - Figure 5-10
Figure 5-10: Messages from APU During Zynq UltraScale+ Boot Sequence
The U-Boot then loads Linux Kernel and other images on Arm Cortex®-A53 APU in SMP
mode. The terminal messages indicate when U-Boot loads Kernel image and the kernel
start up to getting a user interface prompt in Target Linux OS. The Kernel loading and
starting sequence can be seen in the following figure.
Note: This section assumes that you have created PetaLinux Images for QSPI Boot mode by
following steps from Create Linux Images using PetaLinux for QSPI Flash.
1. If SDK is not already running, start it and set the workspace as indicated in Chapter 3.
2. Select Xilinx > Create Boot Image.
3. Select Zynq MP as the Architecture.
4. Select the Create new BIF file option.
5. Ensure that the Output format is set to BIN.
6. In the Basic tab, browse to and select the Output BIF file path and Output path.
X-Ref Target - Figure 5-12
d. Click OK.
6. Click Add to add the R5 bare-metal executable.
a. Add the R5 executable and enable it in lockstep mode, as shown in the following
image.
b. Click OK.
X-Ref Target - Figure 5-16
TIP: See Create Linux Images using PetaLinux for QSPI Flash, to understand the offset value.
You can also create qspi_BOOT.bin images using the BIF attributes and the Bootgen
command. You can view the BIF attributes for this configuration by clicking Preview BIF
Changes. For this configuration, the BIF file contains following attributes:
the_ROM_image:
{
[bootloader,
destination_cpu=a53-0]C:\edt\edt_zcu102\edt_zcu102.sdk\fsbl_a53\Debug\fsbl_a53.elf
[destination_cpu = pmu]C:\edt\edt_zcu102\edt_zcu102.sdk\pmu_fw\
Debug\pmu_fw.elf
[destination_cpu = a53-0, exception_level=el-3,
trustzone]C:\edt\design_files\bl31.elf
[destination_cpu =
r5-lockstep]C:\edt\edt_zcu102\edt_zcu102.sdk\testapp_r5\Debug\testapp_r5.elf
[destination_cpu = a53-0,
exception_level=el-2]C:\edt\design_files\qspi_boot\u-boot.elf
SDK calls the following Bootgen command to generate the qspi_BOOT.bin image for
this configuration.
Note: In this boot sequence, the First Stage Boot Loader (FSBL) loads PMU firmware. This is because
the PMU Firmware was added as a datafile partition type. Ideally, the Boot ROM code can load the
PMU Firmware for PMU as witnessed in the earlier section. For more details on PMU Firmware, refer
to the “Platform Management” chapter in the Zynq UltraScale+ MPSoC: Software Developers Guide
(UG1137) [Ref 6].
5. For port settings, verify the COM port in the device manager. There are four USB UART
interfaces exposed by the ZCU102.
6. Select the COM port associated with the interface with the lowest number. In this case,
for UART-0, select the COM port with interface-0.
7. Similarly, for UART-1, select COM port with interface-1.
Remember, R5 BSP has been configured to use UART-1, so R5 application messages will
appear on the COM port with UART-1 terminal.
X-Ref Target - Figure 5-22
At this point, you can see initial Boot sequence messages on your Terminal Screen
representing UART-0.
You can see that the terminal screen configured for UART-1 also prints a message. This
is the print message from the R-5 bare-metal Application running on RPU, configured to
use UART-1 interface. This application is loaded by the FSBL onto RPU.
The bare-metal application has been modified to include the UART interrupt example.
This application now waits in the WFI state until a user input is encountered from
Keyboard in UART-1 terminal.
X-Ref Target - Figure 5-23
Meanwhile, the boot sequence continues on APU and the images loaded can be
understood from the messages appearing on the UART-0 terminal. The messages are
highlighted in the following figure.
The U-Boot then loads Linux Kernel and other images on Arm Cortex-A53 APU in SMP
mode. The terminal messages indicate when U-Boot loads Kernel image and the kernel
start up to getting a user interface prompt in Linux Kernel. The Kernel loading and
starting sequence can be seen in following figure.
X-Ref Target - Figure 5-25
The following sections demonstrate the basic steps involved in this Boot mode.
Open the XSCT Console in SDK by clicking the XSCT button .Alternatively, you can
also open the XSCT console by selecting Xilinx > XSCT Console.
4. In the XSCT console, connect to the target over JTAG using the connect command:
xsct% connect
5. The targets command lists the available targets and allows you to select a target using
its ID.
The targets are assigned IDs as they are discovered on the JTAG chain, so the IDs can
change from session to session.
Note: For non-interactive usage such as scripting, you can use the -filter option to select a
target instead of selecting the target using its ID.
xsct% targets
By default JTAG Security gates are enabled. Disable the security gates for DAP, PL TAP
and PMU (this will make PMU MB target visible to Debugger).
Verify if the PMU MB target is listed under the PMU device. Now, load and run PMUFW
This step is important, because when Zynq UltraScale+ boots up in JTAG bootmode, all
the APU and RPU cores are held in reset. You must clear resets on each core before
performing debugging on these cores. You can use the rst command in XSCT to clear
the resets.
Note: rst -cores clears resets on all the processor cores in the group (such as APU or RPU) of
which the current target is a child. For example, when A53 #0 is the current target, rst -cores
clears resets on all the A53 cores in APU.
Verify FSBL messages on Serial Terminal and stop FSBL after couple of seconds
xsct% stop
2. Configure a serial terminal (Tera Term, Mini com, or SDK Serial Terminal interface for
UART-0 USB-serial connection).
3. For serial terminal settings, see Figure 5-22.
X-Ref Target - Figure 5-28
6. In the target serial terminal, press any key to stop the U-Boot auto boot.
2. After successfully writing the image to QSPI, turn off the board and set up the ZCU102
board as described in Set Up the ZCU102 Board, page 86.
You can see Linux loading on the UART-0 terminal and the R5 application executing in the
UART-1 terminal.
This chapter focused mostly on system boot and different components related to system
boot. In the next chapter, you will focus on applications, Linux and Standalone (bare-metal)
applications which will make use of PS peripherals, PL IPs, and processing power of APU
Cores and RPU cores.
initial development phase, its support is disabled by default to conserve OCM space. In this
section, you will modify the FSBL to enable the USB Boot Mode. Considering the FSBL
project is used extensively throughout this tutorial, we will not modify the existing FSBL
project. Instead, this section will make use of new FSBL project.
3. Click Finish.
4. In the Project Explorer tab, expand the fsbl_usb_boot project and open
xfsbl_config.h from:
fsbl_usb_boot > src > xfsbl_config.h
from Host Machine USB port using DFU Utility. The size of OCM (256 KB) limits the size of
boot image downloaded by BootROM in USB boot mode. Considering this, and subject to
size requirement being met, only FSBL and PMUFW are stitched into the first Boot.bin,
which is copied to OCM. Rest of the Boot partitions will be stitched in another Boot image
and copied to DDR to be loaded by the FSBL which is already loaded and running at this
stage. Follow the below steps to create Boot images for this boot mode.
For this, follow the below steps to modify system-user.dtsi in the PetaLinux Project
<PetaLinux-project>/project-spec/meta-user/recipes-bsp/device-tree/
files/system-user.dtsi.
&uart1
{
status = "disabled";
};
&dwc3_0 {
dr_mode = "peripheral";
maximum-speed = "super-speed";
};
Note: 2019.1 release does not support USB 3.0 slave boot mode support. For USB 3.0 slave boot
mode support see the Xilinx Answer 72409.
2. Build PetaLinux with the following changes.
$ petalinux-build
The following steps describe how to create a usb_boot.bin comprising rest of the
partitions.
Note: Copy the newly generated U-Boot to C:\edt\usb_boot\. The u-boot.elf is also
available in Design Files for This Tutorial.
1. In SDK, select Xilinx > Create Boot Image.
2. Select FSBL and rest of the partitions and set them as shown in the following figure. For
this you can also choose to import the BIF File from SD Boot Sequence.
Note: Ensure that you have set the correct exception levels for ATF (EL-3, Trustzone) and U-Boot
(EL-2) partitions. These settings can be ignored for other partitions.
1. Set ZCU102 for USB Boot mode by setting SW6 (1-OFF, 2-OFF, 3-OFF, and 4-ON), as
shown below:
X-Ref Target - Figure 5-31
2. Connect a USB 3.0 Cable to J96 USB 3 ULPI Connector, and the other end of the Cable to
USB port on Host Machine.
3. Connect a USB Micro cable between USB-UART port on Board (J83) and Host Machine.
4. Start a terminal session, using Tera Term or Minicom depending on the host machine
being used, as well as the COM port and baud rate for your system, as shown in
Figure 5-31.
5. Power ON the board.
The following steps will load the boot images via USB using DFU utility, which can be found
in SDK\2019.1\tps\lnx64\dfu-util-0.9.
Alternatively you can also install DFU utility on Linux using Package Manager supported by
Linux Distribution being used.
The USB device should be enumerated with VendorId : ProductId which is 03fd:0050.
You should see something like below:
Found DFU: [03fd:0050] ver=0100, devnum=30, cfg=1, intf=0, alt=0, name="Xilinx DFU
Downloader", serial="2A49876D9CC1AA4"
Note: If you do not see the ‘Found DFU’ message, verify the connection and retry.
2. Now download the BOOT.bin that was created in Creating Boot Images for USB Boot.
$ sudo dfu-util -d 03fd:0050 -D <USB_Boot_Image_Path>/Boot.bin
3. Now download the usb_boot.bin. Before this start another terminal session for
UART-1 serial console.
$ sudo dfu-util -d 03fd:0050 -D <USB_Boot_Image_Path>/usb_boot.bin
4. On U-Boot prompt, type Enter to terminate autoboot. Verify from the UART1 console
that the R5 application is also loaded successfully.
5. In U-Boot console start DFU_RAM to enable downloading Linux Images
U-boot> run dfu_ram
6. Download Linux Image Image.ub using following Command from Host Machine
Terminal:
$ sudo dfu-util -d 03fd:0300 -D <PetaLinux_project>/images/linux/image.ub -a 0
7. On U-Boot prompt type Enter to terminate auto-boot. Verify from UART1 console that
the R5 application is also loaded successfully.
Note: At this point, use Zadig utility to install drivers for "Usb download gadget" with device ID
03fd:0300. Without this, zadig software does not show "Xilinx DFU Downloader" after booting
U-Boot on target.
8. In U-Boot console start DFU_RAM to enable downloading Linux Images
U-boot> run dfu_ram
9. Download Linux Image image.ub using following Command from Host Machine
Terminal
$ dfu-util.exe -d 03fd:0300 -D image.ub -a 0
The section Secure Boot System Design Decisions outlines high level secure boot decisions
which should be made early in design development. The Hardware Root of Trust section
discusses the use of a Root of Trust (RoT) in boot. The Boot Image Confidentiality and DPA
section discusses methods to use AES encryption.
The Boot Image Confidentiality and DPA section discusses the use of the operational key
and key rolling techniques as countermeasures to a DPA attack. Changing the AES key
reduces the exposure of both the key and the data protected by the key.
A red key is a key in unencrypted format. The Black Key Storage section provides a method
for storing the AES key in encrypted, or black format. Black key store uses the physically
unclonable function (PUF) as a Key Encryption Key (KEK).
The Practical Methods in Secure Boot section provides steps to develop and test systems
that use AES encryption and RSA authentication.
• Boot Mode
• AES Key Storage Location
• AES Storage State (encrypted or unencrypted)
• Encryption and Authentication requirements
• Key Provisioning
The boot modes which support secure boot are Quad Serial Peripheral Interface (QSPI), SD,
eMMC, and NAND. The AES key is stored in either eFUSEs (encrypted or unencrypted),
Battery Backed Random Access Memory (BBRAM) (unencrypted only), or in external NVM
(encrypted only).
DPA resistance requirements are dictated by whether the adversary has physical access to
the device.
Table 5-2 can be a good reference while deciding on features required to meet a specific
secure system requirement. Next sections will discuss the features in more detail.
The HROT is based on the CSU, eFUSEs, BBRAM, and isolation elements. The HROT is
responsible for validating that the operating environment and configuration have not been
modified. The RoT acts as an anchor for boot, so an adversary can not insert malicious code
before detection mechanisms start.
Firmware and software run on the HROT during boot. Zynq UltraScale provides immutable
BootROM code, a first stage boot loader, device drivers, and the XILSKEY and XILSECURE
libraries which run on the HROT. These provide a well-tested, proven in use API so that
developers do not create security components from scratch with limited testing.
Data Integrity
Data integrity is the absence of corruption of hardware, firmware and software. Data
integrity functions verify that an adversary has not tampered with the configuration and
operating environment.
Zynq UltraScale+ verifies the integrity of partition(s) using both symmetric key (AES-GCM)
and asymmetric key (RSA) authentication. RSA uses a private/public key pair. The fielded
embedded system only has the public key. Theft of the public key is of limited value since it
is not possible, with current technology, to derive the private key from the public key.
Encrypted partitions are also authenticated using the Galois Counter Mode (GCM) mode of
AES.
In the secure boot flow, partitions are first authenticated and then decrypted if necessary.
Authentication
Figure 5-32 shows RSA signing and verification of partitions. From a secure facility, the SDK
Bootgen tool signs partitions, using the private key. In the device, the ROM verifies the FSBL
and either the FSBL or U-Boot verifies the subsequent partitions, using the public key.
Primary and secondary private/public key pairs are used. The function of the primary
private/public key pair is to authenticate the secondary private/public key pair. The function
of the secondary key is to sign/verify partitions.
Partition Data
Partition Data RSA Signature
6+$ 56$
6+$ Public Key
9HULI\
RSA Signature
Verification of the FSBL is handled by the CSU ROM code. To verify the subsequent
partitions, the FSBL or U-Boot uses the XILSECURE library.
There is a debug mode for authentication called bootheader authentication. In this mode of
authentication, the CSU ROM code does not check the primary public key digests, the
session key ID or the key revocation bits stored in the device eFUSEs. Therefore, this mode
is not secure. However, it is useful for testing and debugging as it does not require
programming of eFUSEs. This tutorial uses this mode. However, fielded systems should not
use boot header authentication. The example BIF file for a fully secured system is included
at the end of this section.
Bootgen and FSBL software support AES encryption. Private keys are used in AES
encryption, and AES encryption is done by Bootgen using the key files. The key files can be
generated by Bootgen or OpenSSL. The use of the operational key limits the exposure of the
device key. The use of the operational key in key rolling is discussed in the next section. To
maintain Boot image confidentiality, Encrypted Boot images can be created using Bootgen.
Software examples to program keys to BBRAM and eFUSE are also available in Xilinx SDK.
One such example is discussed in Practical Methods in Secure Boot.
DPA Protections
Key rolling is used for DPA resistance. Key rolling and black key store can be used in the
same design. In key rolling, software and bitstream is broken up into multiple data blocks,
each encrypted with a unique AES key. The initial key is stored in BBRAM or eFUSE NVM.
Keys for successive data blocks are encrypted in the previous data block. After the initial
key, the key update register is used as the key source.
A 96 bit initialization vector is included in the NKY key file. The IV uses 96 bits to initialize
AES counters. When key rolling is used, a 128 bit IV is provided in the bootheader. The 32
least significant bits define the block size of data to decrypt using the current key. The block
sizes following the initial block defined in the IV are defined as attributes in the Bootgen
Image Format (BIF) file.
An efficient method of key rolling uses the operational key. With the operational key,
Bootgen creates an encrypted secure header with the user specified operational key and
the first block IV. The AES key in eFUSE or BBRAM is used only to decrypt the 384 bit secure
header with the 256 bit operational key. This limits the exposure of the device key to DPA
attacks.
There are two steps in using the PUF for black key storage. In the first, PUF registration
software is used to generate PUF helper data and the PUF KEK. The PUF registration data
allows the PUF to re-generate the identical key each time the PUF generates the KEK. For
more details on the use of PUF registration software, see PUF Registration - Boot Header
Mode. For more information on PUF Registration - eFUSE mode, see Programming BBRAM
and eFUSEs (XAPP1319) [Ref 13].
The helper data and encrypted user key must both be stored in eFUSEs if the PUF eFUSE
mode is used, and in the bootheader if the PUF Bootheader mode is used. The procedure
for the PUF bootheader mode is discussed in Using PUF in Bootheader Mode. For the
procedure to use PUF in eFUSE mode, see Programming BBRAM and eFUSEs (XAPP1319)
[Ref 13].
This tutorial uses PUF Bootheader Mode as it does not require programming of eFUSEs, and
is therefore useful for test and debug. However, the most common mode is PUF eFUSE
mode, as the PUB Bootheader mode requires a unique run of bootgen for each and every
device. The example BIF file for a fully secured system is included at the end of the Secure
Boot Sequence section demonstrates the PUF eFUSE mode.
This section starts by showing how to generate AES and RSA keys. Following key
generation, systems using the advanced AES and RSA methods are developed and tested.
Keys generated in this section are also included in the Design Files for This Tutorial, released
with this tutorial.
The methods used to develop AES functionality are provided in the following sections:
The Creating RSA Private/Public Key Pairs section provides the steps to authenticate all
partitions loaded at boot. This section also shows how to revoke keys.
A requirement in the development of a secure system is to add security attributes which are
used in image generation. SDK's Bootgen generates a Boot Image Format (BIF) file. The BIF
file is a text file. In its simplest form, the BIF is a list of partitions to be loaded at boot.
Security attributes are added to the BIF to specify cryptographic functionality. In most
cases, the Bootgen GUI (Create Boot Image wizard) is used to generate the BIF file. In some
cases, adding security attributes requires editing the Bootgen generated BIF file. In Create
Boot Image Wizard in Xilinx SDK, after the Security tab is selected, the Authentication and
Encryption tabs are used to specify security attributes.
After implementing AES and RSA cryptography in secure boot, a Boot test is done. The
system loads successfully and displays the FSBL messages on the terminal. These messages
indicate the cryptographic operations performed on each partition. Appendix A,
Debugging Problems with Secure Boot provides steps that are required to use, if the secure
boot test fails.
Key
Generation
Device
Provisioning
Release
PMU PMU PMU
PMU ROM
CSU
FW
Config Mgr (XILFPGA, XILSECURE), Framework, Warm-Restart, etc.
RAM
Boot Image
Reset Creation
Hardware
CSU FSBL CSU Execution
CSU ROM (Auth+Enc) RAM
Load Auth+Enc PMU FW;Load Auth ATF; Load Auth+Enc Bitstream, Load Auth U-Boot;
FSBL
Needs to run out of OCM for Security Reasons
OCM
ATF Needs to run out of OCM for Security Reasons
APU
UBoot Authentication is done in external memory; Too large for internal
RPU RPU
Assumption: Executes out of a combination of int/ext memory
SW
Time
X20902-052418
Notes:
1. In a Secure boot sequence PMU image is loaded by FSBL. Using the BootROM/CSU to load the PMU firmware
introduces a security weakness as the key/IV combination is used twice. First to decrypt the FSBL and then again
to decrypt the PMU image. This is not allowed for the secure systems.
2. As of 2019.1, U-Boot does not perform a secure authenticated loading of Linux. So instead of U-Boot, FSBL loads
the Linux images to memory address and then uses U-Boot to jump to that memory address.
This tutorial demonstrates assembling the binaries that are created using Chapter 6, System
Design Examples in a boot image with all the security features enabled. This section also
shows how PL bitstream can be added as a part of secure boot flow. Follow Chapter 6,
System Design Examples till the section Modifying the Build Settings to create all the
necessary files and then switch back.
Enabling the security features in boot image is done in two different methods. During the
first method, the BIF file is manually created using a text editor and then using that BIF file
to have Bootgen create keys. This enables you to identify the sections of the BIF file that are
enabled which security features. The second method uses the Create Boot Image wizard in
SDK. It demonstrates the same set of security features. The second method reuses the keys
from the first method for convenience.
The creation of keys using bootgen commands requires the generation and modification of
the BIF files. The key generation section of this tutorial creates these bif files "by hand"
using a text editor. The next section, building your boot image demonstrates how to create
these BIF files using the SDKs Bootgen GUI (create Boot Image Wizard).
For this example, you will create the Primary and Secondary keys in the PEM format. The
keys are generated using Bootgen command-line options. Alternately, you can create the
keys using external tools like OpenSSL.
The following steps describe the process of creating the RSA Private/Public Key Pairs:
Note: The key_generation.bif file will be used to create both the asymmetric keys in these
steps and the symmetric keys in later steps.
the_ROM_image:
{
[pskfile]psk0.pem
[sskfile]ssk0.pem
[auth_params]spk_id = 0; ppk_select = 0
[fsbl_config]a53_x64
[bootloader]fsbl_a53.elf
[destination_cpu = pmu]pmu_fw.elf
[destination_device = pl]edt_zcu102_wrapper.bit
[destination_cpu = a53-0, exception_level = el-3, trustzone] bl31.elf
[destination_cpu = r5-0]tmr_psled_r5.elf
[destination_cpu = a53-0, exception_level = el-2]u-boot.elf
[load = 0x1000000, destination_cpu = a53-0]image.ub
}
8. Verify that the files psk0.pem and ssk0.pem are generated at the location specified
in the BIF file (c:\edt\secure_boot_sd\keys).
The following steps are required only for RSA Authentication with eFUSE mode, and can be
skipped for RSA authentication with bootheader mode. The 384 bits from sha3.txt can
be programmed to eFUSE for RSA Authentication with the eFUSE Mode. For more
information, see Programming BBRAM and eFUSEs (XAPP1319)[Ref 13].
The steps in this section to generate Secondary RSA Private/Public key pair required for Key
Revocation, which requires programming of eFUSE. For more information, see Programming
BBRAM and eFUSEs (XAPP1319) [Ref 13]. You can skip this section if you do not intend to
use Key Revocation.
Repeat steps from Creating RSA Private/Public Key Pairsand Generate SHA3 of Public Key in
RSA Private/Public Key Pair to generate the second RSA private/public key pair and
generate the SHA3 of the second PPK.
1. Perform the steps from the prior section but with replacing psk0.pem, ssk0.pem, and
ppk0_digest.txt with psk1.pem, ssk1.pem and ppk1_digest.pem respectively.
Save this file as key_generation_1.bif. That .bif file will look like:
the_ROM_image:
{
[pskfile]psk1.pem
[sskfile]ssk1.pem
[auth_params]spk_id = 1; ppk_select = 1
[fsbl_config]a53_x64
[bootloader]fsbl_a53.elf
[destination_cpu = pmu]pmu_fw.elf
[destination_device = pl]edt_zcu102_wrapper.bit
[destination_cpu = a53-0, exception_level = el-3, trustzone]bl31.elf
[destination_cpu = r5-0]tmr_psled_r5.elf
[destination_cpu = a53-0, exception_level = el-2]u-boot.elf
[load = 0x1000000, destination_cpu = a53-0]image.ub
}
2. Run the bootgen command to create the RSA private/public key pairs.
bootgen -p zu9eg -arch zynqmp -generate_keys auth pem -image key_generation_1.bif
4. Run the bootgen command to generate the hash of the primary RSA public key.
bootgen -p zcu9eg -arch zynqmp -efuseppkbits ppk1_digest.txt -image
key_generation_1.bif
5. Verify that the files ppk1.pem, spk1.pem, and ppk1_digest.txt are all generated at
the location specified (c:\edt\secure_boot\keys).
Boot header authentication is a mode of authentication that instructs the ROM to skip the
checks of the eFUSE hashes for the PPKs, the revocation status of the PPKs and the Session
IDs for the secondary keys. This mode is useful for testing and debugging as it does not
require programming of eFUSEs. This mode can be permanently disabled for a device by
programming the RSA_EN eFUSEs which forces RSA Authentication with the eFUSE checks.
Fielded systems should use the RSA_EN eFUSE to force the eFUSE checks and disable Boot
Header Authentication.
Add the bh_auth_enable attribute to the [fsbl_config] line so that the bif file appears as
following:
the_ROM_image:
{
[pskfile]psk0.pem
[sskfile]ssk0.pem
[auth_params]spk_id = 0; ppk_select = 0
[fsbl_config]a53_x64, bh_auth_enable
[bootloader, authentication = rsa]fsbl_a53.elf
[destination_cpu = pmu, authentication = rsa]pmu_fw.elf
[destination_device = pl, authentication = rsa]edt_zcu102_wrapper.bit
[destination_cpu = a53-0, exception_level = el-3, trustzone, authentication =
rsa]bl31.elf
[destination_cpu = r5-0, authentication = rsa]tmr_psled_r5.elf
[destination_cpu = a53-0, exception_level = el-2, authentication = rsa]u-boot.elf
[load = 0x1000000, destination_cpu = a53-0, authentication = rsa]image.ub
}
This section provides the steps to use an operational key and key rolling effective
countermeasures against the differential power analysis (DPA).
Use of an operational key limits the amount of information encrypted using the device key.
Enable use of the operational key by adding the opt_key attribute to the [fsbl_config] line of
the bif file. The key_generation.bif file should now look like as shown below:
the_ROM_image:
{
[pskfile]psk0.pem
[sskfile]ssk0.pem
[auth_params]spk_id = 0; ppk_select = 0
[keysrc_encryption]bbram_red_key
[fsbl_config]a53_x64, bh_auth_enable, opt_key
[bootloader, authentication = rsa, encryption = aes, aeskeyfile =
fsbl_a53.nky]fsbl_a53.elf
[destination_cpu = pmu, authentication = rsa, encryption = aes, aeskeyfile =
pmu_fw.nky]pmu_fw.elf
Use of key rolling limits the amount of information encrypted using any of the other keys.
Key-rolling is enabled on a partition-by-partition basis using the blocks attribute in the bif
file. The blocks attribute allows specifying the amount of information in bytes to encrypt
with each key. For example, blocks=4096,1024(3),512(*) would use the first key for 4096
bytes, the 2nd through 4th keys for 1024 bytes and all remaining keys for 512 bytes. In this
example, the block command will be used to limit the life of each key to 1728 bytes.
Enable use of the key rolling by adding the blocks attribute to each of the encrypted
partitions. The key_generation.bif file should now look like.
the_ROM_image:
{
[pskfile]psk0.pem
[sskfile]ssk0.pem
[auth_params]spk_id = 0; ppk_select = 0
[keysrc_encryption]bbram_red_key
[fsbl_config]a53_x64, bh_auth_enable, opt_key
[bootloader, authentication = rsa, encryption = aes, aeskeyfile = fsbl_a53.nky,
blocks = 1728(*)]fsbl_a53.elf
[destination_cpu = pmu, authentication = rsa, encryption = aes,aeskeyfile =
pmu_fw.nky, blocks = 1728(*)]pmu_fw.elf
[destination_device = pl, authentication = rsa, encryption = aes,aeskeyfile =
edt_zcu102_wrapper.nky, blocks = 1728(*)]edt_zcu102_wrapper.bit
[destination_cpu = a53-0, exception_level = el-3, trustzone, authentication =
rsa]bl31.elf
[destination_cpu = r5-0, authentication = rsa, encryption = aes, aeskeyfile =
tmr_psled_r5.nky, blocks = 1728(*)]tmr_psled_r5.elf
[destination_cpu = a53-0, exception_level = el-2, authentication = rsa]u-boot.elf
[load = 0x1000000, destination_cpu = a53-0, authentication = rsa]image.ub
}
Once all desired encryption features have been enabled, you can generate all key files by
running Bootgen. Some of the source files (for example, ELF) contain multiple sections.
These individual sections will be mapped to separate partitions, and each partition will have
a unique key file. In this case, the key file will be appended with a ".1.". For example, if the
pmu_fw.elf file contains multiple sections, both a pmu_fw.nky and a pmu_fw.1.nky
file will be generated.
1. Create all of the necessary NKY files by running the bootgen command that creates the
final BOOT.bin image.
2. Verify that the NKY files were generated. These file should include
edt_zcu102_wrapper.nky, fsbl_a53.nky, pmu_fw.nky, pmu_fw.1.nky,
pmu_fw.2.nky, tmr_psled_r5.nky, and tmr_psled_r5.1.nky.
At the end of the Secure Boot Sequence section, a different BIF file demonstrates using the
PUF in eFUSE mode. In PUF eFUSe mode, the PUF helper data and encrypted user's AES key
are stored in eFUSEs. In PUF eFUSE mode, a single boot image can be used across all
boards.
The PUF registration software is included in the XILSKEY library. The PUF registration
software operates in a Bootheader mode or eFUSE mode. The Bootheader mode allows
development without programming the OTP eFUSEs. The eFUSE mode is used in
production. This lab runs through PUF registration in Bootheader Mode only. For PUF
registration using eFUSE, see Programming BBRAM and eFUSEs (XAPP1319) [Ref 13].
The PUF registration software accepts a red (unencrypted) key as input, and produces
syndrome data (helper data), which also contains CHASH and AUX, and a black (encrypted)
key. When the PUF Bootheader mode is used, the output is put in the bootheader. When the
PUF eFUSE mode is used, the output is programmed into eFUSEs.
1. In SDK, right click tmr_psled_r5_bsp and click Board Support Package Settings.
2. Ensure that xilskey and the xilsecure libraries are enabled.
The key is to be entered in HEX format and should be Key 0 from the fsbl_a53.nky
file that you generated in Generating all of the AES keys. You can find a sample key
below:
#define XSK_PUF_AES_KEY
"68D58595279ED1481C674383583C1D98DA816202A57E7FE4F67859CB069CD510"
Note: Do not copy this key. Refer to the fsbl_a53.nky file for your key.
d. Set the XSK_PUF_BLACK_KEY_IV. The initialization vector IV is a 12 byte data of your
choice.
#define XSK_PUF_BLACK_KEY_IV "E1757A6E6DD1CC9F733BED31"
10. In Project Explorer, right click on the puf_registration project and select Build Project.
11. In SDK, select Xilinx > Create Boot Image.
12. Select Zynq MP in the Architecture dialog box.
13. In the Output BIF file path: dialog box, specify
C:\edt\secureboot_sd\puf_registration\puf_registration.bif
15. In the Boot Image Partitions pane, click Add. Add the partitions and set the destination
CPU of the puf_registration application to R5-0:
C:\edt\edt_zcu102\edt_zcu102.sdk\fsbl_a53\Debug\fsbl_a53.elf
C:\edt\edt_zcu102\edt_zcu102.sdk\puf_registration\Debug\puf_registration.elf
16. Click on Create Image to create the Boot Image for PUF registration
X-Ref Target - Figure 5-38
21. In the communication terminal menu bar, select File > Log. Enter
C:\edt\secureboot_sd\puf_registration\puf_registration.log in the
dialog box.
22. Power cycle the board.
23. After the puf_registration software has run, exit the communication terminal.
24. The puf_registration.log content is used in Using PUF in Bootheader Mode. Open
puf_registration.log in a text editor.
25. Save the PUF Syndrome data that starts after App PUF Syndrome data Start!!!; and ends
at PUF Syndrome data End!!!, non-inclusive, to a file named helperdata.txt.
26. Save the black key IV identified by App: Black Key IV - to a file named black_iv.txt.
27. Save the black key to a file named black_key.txt.
28. The files helperdata.txt, black_key.txt, and black_iv.txt can be saved in
C:\edt\secure_boot_sd\keys
The following steps describes the process to update the .bif file from the previous
sections to include using the PUF in Boot Header mode. This section will make use of the
Syndrome data and Black Key created during PUF registration process.
1. Enable use of the PUF by adding all of the fields and attributes indicated in bold to the
bif file (key_generation.bif) shown below.
the_ROM_image:
{
[pskfile]psk0.pem
[sskfile]ssk0.pem
[auth_params]spk_id = 0; ppk_select = 0
[keysrc_encryption]bh_blk_key
[bh_key_iv]black_iv.txt
[bh_keyfile]black_key.txt
[puf_file]helperdata.txt
[fsbl_config]a53_x64, bh_auth_enable, opt_key, puf4kmode,
shutter=0x0100005E,pufhd_bh
[bootloader, authentication = rsa, encryption = aes, aeskeyfile = fsbl_a53.nky,
blocks = 1728(*)]fsbl_a53.elf
[destination_cpu = pmu, authentication = rsa, encryption = aes, aeskeyfile =
pmu_fw.nky, blocks = 1728(*)]pmu_fw.elf
[destination_device = pl, authentication = rsa, encryption = aes, aeskeyfile =
edt_zcu102_wrapper.nky, blocks = 1728(*)]edt_zcu102_wrapper.bit
[destination_cpu = a53-0, exception_level = el-3, trustzone, authentication =
rsa]bl31.elf
[destination_cpu = r5-0, authentication = rsa, encryption = aes, aeskeyfile =
tmr_psled_r5.nky, blocks =1728(*)]tmr_psled_r5.elf
[destination_cpu = a53-0, exception_level = el-2, authentication = rsa]u-boot.elf
[load = 0x1000000, destination_cpu = a53-0, authentication = rsa]image.ub
}
2. The above .bif file can be used for creating a final boot image using an AES key
encrypted in the boot image header with the PUF KEK. This would be done using the
following bootgen command.
bootgen -p zcu9eg -arch zynqmp -image key_generation.bif -w -o BOOT.bin
Note: The above steps can also be executed with PUF in eFUSE mode. In this case you can repeat the
previous steps, using the PUF in eFUSE mode. This requires enabling the programming of eFUSEs
during PUF registration by setting the XSK_PUF_PROGRAM_EFUSE macro in the
xilskey_puf_registration.h file used to build the PUF registration application. Also, the BIF
would need to be modified to use the encryption key from eFUSE and removing the helper data and
black key files. PUF in eFUSE mode is not covered in this tutorial in order to avoid programming the
eFUSEs on development or tutorial systems.
[keysrc_encryption]efuse_blk_key
[bh_key_iv]black_iv.txt
2. Copy the below data from the prior example to this example.
cp ../keys/*nky .
cp ../keys/*pem .
cp ../keys/black_iv.txt .
cp ../keys/helperdata.txt .
cp ../keys/*.elf .
cp ../keys/edt_zcu102_wrapper.bit .
cp ../keys/image.ub .
cp ../keys/black_key.txt.
3. Click Programs > Xilinx Design Tools > SDK 2019.1 > Xilinx SDK 2019.1 to launch
SDK.
4. Click Xilinx Tools > Create Boot Image from the SDK menu bar to launch the Create
Boot Image wizard.
5. Select Zynq MP as the Architecture.
6. Enter the Output BIF file path as
c:\edt\secure_boot_sd\bootgen_files\design_bh_bkey_keyrolling.bif .
21. This BIF file is still missing several security features that are not supported by the Create
Boot Image wizard. These are features are per-partition nky files, key rolling and black
key store.
22. Add black key store by changing the keysrc_encryption and adding the other
additional items so that the BIF file looks like the following:
the_ROM_image:
{
[pskfile]psk0.pem
[sskfile]ssk0.pem
[auth_params]spk_id = 0; ppk_select = 0
[aeskeyfile]fsbl_a53.nky
[keysrc_encryption]bh_blk_key
[bh_key_iv]black_iv.txt
[bh_keyfile]black_key.txt
[puf_file]helperdata.txt
[fsbl_config]a53_x64, bh_auth_enable, opt_key, puf4kmode, shutter=0x0100005E,
pufhd_bh
[bootloader, encryption = aes, authentication = rsa]fsbl_a53.elf
[encryption = aes, authentication = rsa, destination_cpu = pmu]pmu_fw.elf
[encryption = aes, authentication = rsa, destination_device =
pl]edt_zcu102_wrapper.bit
[authentication = rsa, destination_cpu = a53-0, exception_level = el-3]bl31.elf
[encryption = aes, authentication = rsa, destination_cpu = r5-0]tmr_psled_r5.elf
[authentication = rsa, destination_cpu = a53-0, exception_level = el-2]u-boot.elf
[authentication = rsa, load = 0x2000000, destination_cpu = a53-0]image.ub
}
23. Specify unique AES key files for each encrypted partition by updating the BIF file to look
like the following:
the_ROM_image:
{
[pskfile]psk0.pem
[sskfile]ssk0.pem
[auth_params]spk_id = 0; ppk_select = 0
[keysrc_encryption]bh_blk_key
[bh_key_iv]black_iv.txt
[bh_keyfile]black_key.txt
[puf_file]helperdata.txt
[fsbl_config]a53_x64, bh_auth_enable, opt_key, puf4kmode, shutter=0x0100005E,
pufhd_bh
[bootloader, encryption = aes, aeskeyfile = fsbl_a53.nky, authentication =
rsa]fsbl_a53.elf
[encryption = aes, aeskeyfile = pmu_fw.nky, authentication = rsa, destination_cpu =
pmu]pmu_fw.elf
[encryption = aes, aeskeyfile = edt_zcu102_wrapper.nky, authentication = rsa,
destination_device = pl]edt_zcu102_wrapper.bit
[authentication = rsa, destination_cpu = a53-0, exception_level = el-3]bl31.elf
[encryption = aes, aeskeyfile = tmr_psled_r5.nky, authentication = rsa,
destination_cpu = r5-0]tmr_psled_r5.elf
[authentication = rsa, destination_cpu = a53-0, exception_level = el-2]u-boot.elf
[authentication = rsa, load = 0x2000000, destination_cpu = a53-0]image.ub
}
24. Enable key rolling by adding the block attributes to the encrypted partitions. The
updated BIF file should now look like the following:
the_ROM_image:
{
[pskfile]psk0.pem
[sskfile]ssk0.pem
[auth_params]spk_id = 0; ppk_select = 0
[keysrc_encryption]bh_blk_key
[bh_key_iv]black_iv.txt
[bh_keyfile]black_key.txt
[puf_file]helperdata.txt
[fsbl_config]a53_x64, bh_auth_enable, opt_key, puf4kmode, shutter=0x0100005e,
pufhd_bh
[bootloader, encryption = aes, aeskeyfile = fsbl_a53.nky, authentication = rsa,
blocks = 1728(*)]fsbl_a53.elf
[encryption = aes, aeskeyfile = pmu_fw.nky, authentication = rsa, destination_cpu =
pmu, blocks = 1728(*)]pmu_fw.elf
[encryption = aes, aeskeyfile = edt_zcu102_wrapper.nky, authentication = rsa,
destination_device = pl, blocks = 1728(*)]edt_zcu102_wrapper.bit
[authentication = rsa, destination_cpu = a53-0, exception_level = el-3]bl31.elf
[encryption = aes, aeskeyfile = tmr_psled_r5.nky, authentication = rsa,
destination_cpu = r5-0, blocks = 1728(*)]tmr_psled_r5.elf
[authentication = rsa, destination_cpu = a53-0, exception_level = el-2]u-boot.elf
[authentication = rsa, load = 0x2000000, destination_cpu = a53-0]image.ub
}
25. Generate the boot image by running the following command. Note that the
-encryption_dump flag has been added. This flag causes the log file aes_log.txt
to be created. The log file details all encryption operations that were used. This allows
you to see which keys and IVs were used on which sections of the boot image.
bootgen -p zcu9eg -arch zynqmp -image design_bh_bkey_keyrolling.bif -w -o BOOT.bin
-encryption_dump
1. Copy the BOOT.bin image and the ps_pl_linux_app.elf over to the SD card from
c:\edt\secure_boot_sd\bootgen_files.
2. Insert the SD card into the ZCU102.
3. Set SW6 of the ZCU102 for SD boot mode (1=ON; 2,3,4=OFF).
Login: root;
password: root
X-Ref Target - Figure 5-51
Note: Mount the SD card manually if you fail to find SD card contents in this location.
# mount /dev/mmcblk0p1 /media/
The following changes are made to the final generation.bif file reach the following
result:
• The Linux applications configure a set of PL LEDs to toggle using a PS Dip Switch, and
another set of PL LEDs to toggle using a PL Dip Switch (SW17).
• The Linux APU A-53 Core 0 hosts this Linux application, while the RPU R5-0 hosts
another bare-metal application.
• The R5-Core 0 application uses an AXI Timer IP in Programmable logic to toggle PS LED
(DS50). The application is configured to toggle the LED state every time the timer
counter expires, and the Timer in the PL is set to reset periodically after a
user-configurable time interval. The system is configured such that the APU Linux
Application and RPU Bare-metal Application run simultaneously.
Configuring Hardware
The first step in this design is to configure the PS and PL sections. This can be done in
Vivado IP integrator. You start with adding the required IPs from the Vivado IP catalog and
then connect the components to blocks in the PS subsystem.
1. If the Vivado Design Suite is already open, start from the block diagram (shown in
Figure 2-2) and jump to step 4.
2. Open the Vivado Project that you created:
C:/edt/edt_zcu102/edt_zcu102.xpr
3. In the Flow Navigator, under IP Integrator, click Open Block Design and select
edt_zcu102.bd.
X-Ref Target - Figure 6-1
4. Right click in the block diagram and select Add IP from the IP catalog.
3. Double-click the AXI Timer IP again to configure the IP, as shown in following figure.
X-Ref Target - Figure 6-3
4. Click OK.
5. Again, right-click in the block diagram and select Add IP.
6. Search for “AXI GPIO” and double-click the AXI GPIO IP to add it to the design.
7. Repeat step 5 and step 6 to add another instance of AXI GPIO IP.
8. Double-click axi_gpio_0 and select Push button 5bits from the GPIO Board Interface
drop-down list.
1. Double-click the Zynq UltraScale+ IP Block, and select a PL-PS interrupt as shown in
Figure 6-6 (Ignore and move to the next step, if this is selected by default).
X-Ref Target - Figure 6-6
2. In PS-PL Configuration, expand PS-PL Interfaces and expand the Master Interface.
3. Expand AXI HPM0 LPD and set the AXI HPM0 LPD Data Width drop-down to 128 bit, as
shown in Figure 6-7.
X-Ref Target - Figure 6-7
.
X-Ref Target - Figure 6-9
A message dialog box opens and states "Validation successful. There are no errors or
critical warnings in this design."
The Generate Output Products dialog box opens, as shown Figure 6-10.
X-Ref Target - Figure 6-10
Note: If you are running the Vivado Design Suite on a Linux host machine, you might see
additional options under Run Settings. In this case, continue with the default settings.
8. Click Generate.
9. When the Generate Output Products process completes, click OK.
10. In the Block Diagram Sources window, click the IP Sources tab. Here you can see the
output products that you just generated, as shown in the following figure.
While synthesis is running, a status bar displays in the upper right-hand window. This
status bar spools for various reasons throughout the design process. The status bar
signifies that a process is working in the background.
X-Ref Target - Figure 6-13
Again, notice that the status bar describes the process running in the background. When
implementation completes, the Implementation Completed dialog box opens.
When Bitstream Generation completes, the Bitstream Generation Completed dialog box
opens.
1. From the Vivado toolbar, select File > Export > Export Hardware.
The Export Hardware dialog box opens. Make sure that the Include bitstream check
box is checked (only when design has PL design and bitstream generated), and that the
Export to field is set to the default option of <Local to Project>.
2. Click OK.
At this point a warning, message appears to indicate that the Hardware Module has
already been exported.
The warning message is also to check if SDK can update the project in sync with the new
HDF.
5. Click Yes.
Now the SDK project is updated in sync with the new HDF file. To verify this, look for the
GPIO and AXI_Timer drivers, which were added in the BSP packages in the existing project.
Configuring Software
This use case has a bare-metal application running on an R5 core and a Linux Application
running on APU Linux Target. Most of the software blocks will remain the same as
mentioned in Chapter 3. The software for this design example requires additional drivers for
components added in the PL Logic. For this reason, you will need to generate a new
Bare-metal BSP in SDK using the Hardware files generated for this design. Linux also
requires the Linux BSP to be reconfigured in sync with the new hardware design file (HDF).
Before you configure the software, first look at the application design scheme. The system
has a bare-metal application on RPU, which starts with toggling the PS LEDs for a user
configurable period. The LEDs are set to toggle in synchronization with PL AXI Timer
running in the PL block. The application sets the AXI Timer in the generate mode and
generates an interrupt every time the Timer count expires. The application is designed to
toggle the PS LED state after handling the Timer interrupt. The application runs in an
infinite while loop and sets the RPU in WFI mode after toggling the LEDs for the
user-configured time period. This LED toggling sequence can be repeated again by getting
the RPU out of WFI mode using an external interrupt. For this reason, the UART interrupt is
also configured and enabled in the same application. While this application runs on the
RPU, the Linux target also hosts another Linux application. The Linux application uses user
Input from PS or PL switches to toggle PL LEDs. This Linux application also runs in an infinite
while loop, waiting for user input to toggle PL LEDs. The next set of steps show how to
configure System software and build user applications for this design.
See the Example Project: Create Linux Images using PetaLinux in Chapter 3, and repeat
steps from step 2 to step 13 to update the device tree and build Linux images using
PetaLinux. Alternatively, you can also use the Linux image files shared with this tutorial. The
images for this section can be found in <design_files>/design.
Follow step 15 to verify the images. The next step is to create a Bare-metal Application
targeted for Arm Cortex-R5 based RPU.
For this design example, you must import the application source files available in the
Design Files ZIP file released with this tutorial. For information about locating these design
files, see the Design Files for This Tutorial in Appendix B.
2. Use the information in the table below to make your selections in the wizard.
3. Click Finish.
The New Project wizard closes and SDK creates the tmr_psled_r5 application project,
which you can view in the Project Explorer.
SDK automatically builds the application and displays the status in the console window.
3. In the linker script in Available Memory Regions, modify following attributes for
psu_r5_ddr_0_MEM_0 :
Size: 0x10000000
The following figure shows the linker script modification. The following figure is for
representation only. Actual memory regions may vary in case of isolation settings.
X-Ref Target - Figure 6-16
This modification in the linker script ensures that the RPU bare-metal application
resides above 0x70000000 base address in the DDR, and occupies no more than 256 MB
of size.
2. Use the information in the table below to make your selections in the wizard.
s
3. Click Finish.
The New Project wizard closes and SDK creates the ps_pl_linux_app application
project, which can be found in the Project Explorer.
SDK automatically builds the application and displays the status in the console window.
IMPORTANT: Ensure that you have set the correct exception levels for ATF (EL-3, Trustzone) and U-Boot
(EL-2) partitions. These settings can be ignored for other partitions.
Target Setup
1. Load the SD card into the ZCU102 board, in the J100 connector.
2. Connect the USB-UART on the Board to the Host machine.
3. Connect the Micro USB cable into the ZCU102 Board Micro USB port J83, and the other
end into an open USB port on the host Machine.
4. Configure the Board to Boot in SD-Boot mode by setting switch SW6 as shown in the
following figure.
X-Ref Target - Figure 6-20
8. Select the COM Port associated with the interface with the lowest number. In this case,
for UART-0, select the COM port with interface-0.
9. Similarly, for UART-1, select COM port with interface-1.
Remember that the R5 BSP has been configured to use UART-1, and so R5 application
messages will appear on the COM port with the UART-1 terminal.
You can see the initial Boot sequence messages on your Terminal Screen representing
UART-0.
You can see that the terminal screen configured for UART-1 also prints a message. This
is the print message from the R-5 bare-metal Application running on RPU, configured to
use UART-1 interface. This application is loaded by the FSBL onto RPU.
2. Now that this application is running, notice the PS LED being toggled by the application,
and follow the instructions in the application terminal.
X-Ref Target - Figure 6-21
After Linux is up on the ZCU102 system, log in to the Linux target with login: root and
password: root. The Linux target is now ready for running applications.
Note: Mount the SD card manually if you fail to find SD card contents in this location.
# mount /dev/mmcblk0p1 /media/
Copy the application to /tmp.
# cp /media/ps_pl_linux_app.elf /tmp
2. Run the application.
# /tmp/ps_pl_linux_app.elf
X-Ref Target - Figure 6-22
CAUTION! Do not click the Run Block Automation link. Clicking the link will reset the design as per
board preset and disable the design updates you made using in this section.
7. Click File > Save Block Design to save the block design. Alternatively, you can press
CTRL + S to save the block design.
8. Click Generate Bitstream, to re-synthesize the design and generate the Bitstream.
9. After the Bitstream is generated successfully, click File > Export > Export Hardware to
export the hardware design.
10. Select Include Bistream.
11. Click OK.
The next section describes steps to build Linux for your Hardware configuration and also
add additional software packages for GPU and the X Window System.
4. Save and exit the wizard without any additional configuration settings.
5. Clean the existing Bootloader image. This is to ensure that the bootloader is recreated
in sync with new hardware design.
$ petalinux-build -c bootloader -x distclean
1. Copy the entire application source directory of tricube to the Linux host machine in
the recipe-apps directory of the PetaLinux project.
<PetaLinux-Project>/project-spec/meta-user/recipes-apps/tricube
<plnx_project>/project-spec/meta-user/recipes-core/images/petali
nux-image-full.bbappend
With this addition, the file will look like below. Notice the new application in bold.
3. Refer to recipe tricube/tricube.bb for detailed instructions and libraries used for
building this application. The X Window System (X11) packages included while building
the above application is application dependent. Libraries included in tricube.bb
recipe are based on the packages that were used in the application.
These packages enable you to build and Run OpenGLES applications targeted for Mali
GPU in the Zynq UltraScale+ MPSoC device.
5. After enabling all the packages, save the config file and exit the rootfs configuration
settings.
6. Build the Linux images using the following command:
$ petalinux-build
Note: If the PetaLinux build fails, use the following commands to build again:
$ petalinux-build -x mrproper
$ petalinux-build
7. Verify that the image.ub Linux image file is generated in the images/linux directory.
8. Generate the Boot image for this design example as follows:
$ petalinux-package --boot --fsbl images/linux/zynqmp_fsbl.elf --pmufw
images/linux/pmufw.elf --atf images/linux/bl31.elf --fpga images/linux/system.bit
--u-boot images/linux/u-boot.elf
A BOOT.BIN Boot image is created. It is composed of the FSBL boot loader, the PL
bitstream, PMU firmware and ATF, and U-Boot. Alternatively, see the steps in Creating a
Boot Image to create this boot image.
IMPORTANT: This example uses the GPU packages based on X window system, which is the default
setting in PetaLinux 2019.1. To enable Frame Buffer fbdev based GPU Packages in PetaLinux 2019.1,
add the following line in <PetaLinux_project>/project-spec/meta-user/conf/petalinuxbsp.conf.
DISTRO_FEATURES_remove_zynqmp = " x11"
See example eglfbdev application (based on fdev) available in Design Files for This Tutorial. For more
information, see the Xilinx Answer 68821.
• BOOT.BIN
• image.ub
1. Load the SD card into the J100 connector of the ZCU102 board.
2. Connect the Micro USB cable into the ZCU102 Board Micro USB port J83, and the other
end into an open USB port on the host Machine.
Also, make sure that the JTAG cable is disconnected. If the cable is not disconnected, the
system might hang.
3. Connect a Display Port monitor to the ZCU102 Board. The display port cable from the
DP monitor can be connected to the display port connector on the ZCU102 board.
Note: These images were tested on a UHD@30 Hz and a FullHD@60 Hz Display Port capable
monitor.
4. Configure the Board to Boot in SD-Boot mode by setting switch SW6 as shown in the
following figure.
X-Ref Target - Figure 6-24
There are four USB-UART interfaces exposed by the ZCU102 Board. Select the COM port
associated with the interface with the lowest number. In this case, for UART-0, select the
COM port with interface-0.
At this point, you can see a rotating multi-colored cube and a rotating triangle on the
display port. Notice that the cube is also made of multi-colored triangles.
X-Ref Target - Figure 6-25
3. This location contains the CHASH and AUX values. If non-zero, PUF registration software
has been run on the device.
Xilinx Resources
For support resources such as Answers, Documentation, Downloads, and Forums, see Xilinx
Support.
Solution Centers
See the Xilinx Solution Centers for support on devices, software tools, and intellectual
property at all stages of the design cycle. Topics include design assistance, advisories, and
troubleshooting tips.
• From the Vivado IDE, select Help > Documentation and Tutorials.
• On Windows, select Start > All Programs > Xilinx Design Tools > DocNav >
DocNav.
• At the Linux command prompt, enter docnav.
Xilinx Design Hubs provide links to documentation organized by design tasks and other
topics, which you can use to learn key concepts and address frequently asked questions. To
access the Design Hubs:
• In the Xilinx Documentation Navigator, click the Design Hubs View tab.
• On the Xilinx website, see the Design Hubs page.
Note: For more information on Documentation Navigator, see the Documentation Navigator page
on the Xilinx website.
To view the contents of the ZIP file, download and extract the contents from the ZIP file to
C:\edt. The design files contain the HDF files, source code and prebuilt images for all the
sections.
Xilinx Resources
The following Xilinx Vivado Design Suite and Zynq® UltraScale+™ guides are referenced in
this document.
Support Resources
14. Xilinx Zynq UltraScale+ MPSoC Solution Center
15. The Software Zone:
https://www.xilinx.com/products/design-tools/software-zone/sdsoc.html#docsdownloa
d
Additional Resources
16. The Effect and Technique of System Coherence in Arm Multicore Technology by John
Goodacre, Senior Program Manager, Arm Processor Division
(http://www.mpsoc-forum.org/previous/2008/slides/8-6%20Goodacre.pdf)
17. Xilinx GitHub website: https://github.com/xilinx
18. The Linux Kernel Module Programming Guide:
http://tldp.org/LDP/lkmpg/2.6/html/index.html
Training Resources
Xilinx provides a variety of training courses and QuickTake videos to help you learn more
about the concepts presented in this document. Use these links to explore related videos: