{"id":29128,"date":"2022-04-11T10:09:49","date_gmt":"2022-04-11T17:09:49","guid":{"rendered":"https:\/\/digilent.com\/blog\/?p=29128"},"modified":"2023-02-07T17:30:50","modified_gmt":"2023-02-08T01:30:50","slug":"building-an-arch-linux-based-project-on-the-genesys-zu-5ev","status":"publish","type":"post","link":"https:\/\/digilent.com\/blog\/building-an-arch-linux-based-project-on-the-genesys-zu-5ev\/","title":{"rendered":"Building an Arch Linux-Based Project on the Genesys ZU-5EV"},"content":{"rendered":"<h2><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-29151\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/GenesysZU-top-RevA-1000.png\" alt=\"\" width=\"580\" height=\"375\" data-wp-pid=\"29151\" \/><\/h2>\n<h2>Step-by-Step Guide to Building an Arch Linux-Based Project<\/h2>\n<p>This paper will provide a step-by-step guide to build from ground up a Genesys ZU development board-based hardware and software project that is capable of running Arch Linux operating system (in theory any embedded ARM64 compiled Linux operating system can be used following this guide). All generated files are included and can be downloaded at the end of this guide. The development environment used to generate the example project was Vivado 2021.1, under Ubuntu Linux 20.4 LTS. Instructions on how to install Vivado under Linux and what licensing options are available can be found <a href=\"https:\/\/www.xilinx.com\/support\/documentation\/sw_manuals\/xilinx2020_2\/ug973-vivado-release-notes-install-license.pdf\">here<\/a>. \u00a0 of the hardware development can be done under Windows OS, however, the bootloader and Linux environment compilation requires a working Linux environment or the use of <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/wsl\/about\">Windows Subsystem for Linux<\/a>.<\/p>\n<p>All attachments can be found at the links below:<\/p>\n<ul>\n<li><a href=\"https:\/\/s3.console.aws.amazon.com\/s3\/object\/digilent?region=us-west-2&amp;prefix=resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/BOOT-BIN\/BOOT.BIN\"><span class=\"name object latest object-name\">BOOT.BIN<\/span><\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/BOOT-BIN\/FSBL_system.bif\">FSBL System.BIF<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/genesys_hw.xsa\">XSA<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/hw_project\/genesys_hw.zip\">HW Project<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/hw_project\/system.xdc\">System XDC<\/a><\/li>\n<li>Patches\n<ul>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/patch\/device-tree.patch\">Device Tree<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/patch\/fsbl.patch\">FSBL<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/patch\/kernel.patch\">Kernal<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/patch\/uboot.patch\">uboot<\/a><\/li>\n<\/ul>\n<\/li>\n<li>Pre-Generated Files\n<ul>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/pre-generated-files\/bl31.elf\">bl31.elf<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/pre-generated-files\/FSBL.elf\">FSBL.elf<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/pre-generated-files\/Image.ub\">image.ub<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/pre-generated-files\/PMUFirmware.elf\">PMUFirmware.elf<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/pre-generated-files\/u-boot.elf\">u-boot.elf<\/a><\/li>\n<li><a href=\"https:\/\/digilent.s3.us-west-2.amazonaws.com\/resources\/programmable-logic\/genesys+ZU+5+EV+tutorial\/Attachments\/pre-generated-files\/uramdisk.image.gz\">uramdisk.image.gz<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<figure id=\"attachment_29129\" aria-describedby=\"caption-attachment-29129\" style=\"width: 505px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29129\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-1-Design-Flow-505x600.png\" alt=\"\" width=\"505\" height=\"600\" data-wp-pid=\"29129\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-1-Design-Flow-505x600.png 505w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-1-Design-Flow.png 534w\" sizes=\"auto, (max-width: 505px) 100vw, 505px\" \/><figcaption id=\"caption-attachment-29129\" class=\"wp-caption-text\">Figure 1 &#8211; Design Flow<\/figcaption><\/figure>\n<p>The project has two major parts: the hardware platform generated in the Vivado environment and the software platform, partially (FSB, device-tree) generated by the Vivado tool or the Vitis IDE. Other software components, namely, the ARM Trusted Firmware, u-boot bootloader and the Linux Kernel needs to be compiled separately in a Linux environment using an ARM64 compiler (the Xilinx development environment contains the necessary compiler).<\/p>\n<h2>Compiling the Hardware<\/h2>\n<ol>\n<li>The first step is to create a new RTL project in Vivado. To use the Vivado executables and start the development environment from the terminal. The correct environment variables must be set by the settings64.sh script located in the Vivado installation folder. Every command during the implementation is executed in the terminal environment where the given source command was executed. Navigate to the installation directory &lt;path to Xilinx folder&gt;\/Vivado\/&lt;vivado version&gt;\/ enter the following command:<br \/>\n<blockquote><p>$ source settings64.sh<\/p><\/blockquote>\n<\/li>\n<li>Afterwards, the Vivado environment can be started with the command:<br \/>\n<blockquote><p>$ vivado<\/p><\/blockquote>\n<\/li>\n<li>After Vivado opens, select from the File menu -&gt; Project, then New\u2026 to create a new Vivado project. Select RTL Project, then Next. <img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-29130\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-2-New-project-generation-600x444.png\" alt=\"\" width=\"600\" height=\"444\" data-wp-pid=\"29130\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-2-New-project-generation-600x444.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-2-New-project-generation.png 1020w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/li>\n<li>At the configuration screen the correct board file must be selected in the Xilinx parts selector (Figure 3). At the time of writing this guide, Vivado 2021.1 and all the older Vivado versions do not contain the new Genesys ZU board specification files. The user has to download them from https:\/\/github.com\/Digilent\/vivado-boards, following the steps in Section 3 of the Installing Vivado, Xilinx SDK, and Digilent Board Files guide on the Digilent Wiki.If the files are correctly installed, the Genesys ZU boards will become selectable from the Xilinx parts selector window.<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-29131\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-3-Board-Setup-600x422.jpg\" alt=\"\" width=\"600\" height=\"422\" data-wp-pid=\"29131\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-3-Board-Setup-600x422.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-3-Board-Setup.jpg 983w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/li>\n<li>After the project is initialized, a new Block Design can be created.<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-29132\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-4-Creating-a-Hardware-Design-600x353.jpg\" alt=\"\" width=\"600\" height=\"353\" data-wp-pid=\"29132\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-4-Creating-a-Hardware-Design-600x353.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-4-Creating-a-Hardware-Design-1024x603.jpg 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-4-Creating-a-Hardware-Design-1536x905.jpg 1536w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-4-Creating-a-Hardware-Design.jpg 1674w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/li>\n<li>At least the Zynq UltraScale+ MPSoC core has to be added to the project. Select the Run Block Automation at the top green line to configure the ZynqMPSoC core with the Digilent preset that is included in the board specification files.\n<figure id=\"attachment_29133\" aria-describedby=\"caption-attachment-29133\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29133\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-5-Inserting-the-Zynq-Core-600x353.jpg\" alt=\"\" width=\"600\" height=\"353\" data-wp-pid=\"29133\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-5-Inserting-the-Zynq-Core-600x353.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-5-Inserting-the-Zynq-Core-1024x602.jpg 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-5-Inserting-the-Zynq-Core-1536x903.jpg 1536w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-5-Inserting-the-Zynq-Core.jpg 1673w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29133\" class=\"wp-caption-text\">Figure 5 &#8211; Inserting the Zynq Core<\/figcaption><\/figure>\n<figure id=\"attachment_29134\" aria-describedby=\"caption-attachment-29134\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29134\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-6-the-ZynqMP-core-configuration-600x390.png\" alt=\"\" width=\"600\" height=\"390\" data-wp-pid=\"29134\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-6-the-ZynqMP-core-configuration-600x390.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-6-the-ZynqMP-core-configuration-1024x665.png 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-6-the-ZynqMP-core-configuration.png 1354w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29134\" class=\"wp-caption-text\">Figure 6 &#8211; the ZynqMP core configuration<\/figcaption><\/figure><\/li>\n<li>When adding and configuring any additional modules, check the connections and the address allocation of the AXI Bus. The example project contains two AXI-GPIO modules connected to the four LEDs and the four switches on the board (if unused the AXI Slave HP0 should be disabled otherwise compilation errors can appear). Figure 7 shows the basic project with two GPIO modules connected, one to the switches and one to the LEDs on the board.<br \/>\n<a href=\"https:\/\/usermanual.wiki\/m\/e927687bc30c16b114c3153c220fceeab7ed9a40e9eedaed7d390fc260e4a1f3.pdf\">The emio_enet0_enet_tsu_timer_cnt<\/a> ports can be left unconnected. <img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-29135\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-7-Block-diagram-of-minimal-hardware-design-600x204.png\" alt=\"\" width=\"600\" height=\"204\" data-wp-pid=\"29135\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-7-Block-diagram-of-minimal-hardware-design-600x204.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-7-Block-diagram-of-minimal-hardware-design-1024x349.png 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-7-Block-diagram-of-minimal-hardware-design.png 1363w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/li>\n<li>The Display Port AUX signals can be connected by creating a new constraint file and adding appropriate ports (system.xdc, Figure 8).\n<figure id=\"attachment_29136\" aria-describedby=\"caption-attachment-29136\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29136\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-8-Creating-a-new-constraint-file-600x375.jpg\" alt=\"\" width=\"600\" height=\"375\" data-wp-pid=\"29136\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-8-Creating-a-new-constraint-file-600x375.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-8-Creating-a-new-constraint-file-1024x640.jpg 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-8-Creating-a-new-constraint-file-1536x960.jpg 1536w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-8-Creating-a-new-constraint-file.jpg 1680w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29136\" class=\"wp-caption-text\">Figure 8 &#8211; Creating a new constraint file<\/figcaption><\/figure>\n<figure id=\"attachment_29137\" aria-describedby=\"caption-attachment-29137\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29137\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-9-Contents-of-the-constraint-file-600x249.jpg\" alt=\"\" width=\"600\" height=\"249\" data-wp-pid=\"29137\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-9-Contents-of-the-constraint-file-600x249.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-9-Contents-of-the-constraint-file-1024x424.jpg 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-9-Contents-of-the-constraint-file.jpg 1426w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29137\" class=\"wp-caption-text\">Figure 9 &#8211; Contents of the constraint file<\/figcaption><\/figure><\/li>\n<li>After all user modules are connected and configured, the user must generate the HDL Wrapper for the block design presented in Figure 7. After this, the bitstream can be generated by clicking on the <strong>Generate Bitstream<\/strong> link from Flow Navigator panel. This will synthesize and implement the project.\n<figure id=\"attachment_29138\" aria-describedby=\"caption-attachment-29138\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29138\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-10-Creating-the-HDL-Wrapper-600x375.jpg\" alt=\"\" width=\"600\" height=\"375\" data-wp-pid=\"29138\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-10-Creating-the-HDL-Wrapper-600x375.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-10-Creating-the-HDL-Wrapper-1024x640.jpg 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-10-Creating-the-HDL-Wrapper-1536x960.jpg 1536w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-10-Creating-the-HDL-Wrapper.jpg 1680w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29138\" class=\"wp-caption-text\">Figure 10 &#8211; Creating the HDL Wrapper<\/figcaption><\/figure><\/li>\n<\/ol>\n<h2>Compiling the Software<\/h2>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li>We will generate and compile the necessary software components to run the Linux environment on top of the generated hardware components. The FSBL, PMU Firmware and the device-tree can be generated from Vivado tool or Vitis IDE, depending on the used development environment. The FSB will preconfigure the board, load the bitstream in the reconfigurable part of the chip and load the device-tree, boot loader and the kernel to memory. Afterwards, it executes the ARM Trusted Firmware. In Vivado 2021.1 the generate hardware project, can be exported to Vitis IDE (File-&gt;Export-&gt;Export Hardware). If the \u201cInclude bitstream\u201d option is selected, this will create the platform file with XSA extension that will include all configuration files and the bitstream.\n<figure id=\"attachment_29139\" aria-describedby=\"caption-attachment-29139\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29139\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-11-Exporting-the-Design-600x375.jpg\" alt=\"\" width=\"600\" height=\"375\" data-wp-pid=\"29139\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-11-Exporting-the-Design-600x375.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-11-Exporting-the-Design-1024x640.jpg 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-11-Exporting-the-Design-1536x960.jpg 1536w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-11-Exporting-the-Design.jpg 1680w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29139\" class=\"wp-caption-text\">Figure 11 &#8211; Exporting the Design to Vivado\/Vitis SDK<\/figcaption><\/figure><\/li>\n<li>Afterwards, the Vitis IDE can be started by selecting the Launch Vitis IDE from the Tools menu or by executing the following command from the terminal:<br \/>\n<blockquote><p>$ vitis<\/p><\/blockquote>\n<\/li>\n<li>In the Vitis IDE environment, after selecting the File-&gt;New-&gt;Application Project, the XSA file created in Vivado needs to be selected. Under the Create a new platform from hardware (XSA) tab, click on Browse and select the generated board file with the XSA extension.\n<ol>\n<li>Generating the FSBL and PMU firmware is possible through 2 methods:<br \/>\nThe first one, inside the hardware platform project, by ticking \u201cGenerate Boot Components&#8221;. The Digilent-provided FSBL is required and should be added to the Vitis workspace in the Xilinx-&gt;Software Repositories menu (Vitis -&gt; Window -&gt; Preferences -&gt; Xilinx -&gt; Software Repository).<br \/>\nDownload the FSBL source code from <a href=\"https:\/\/github.com\/Digilent\/embeddedsw\/tree\/genesys-zu-21.1\">https:\/\/github.com\/Digilent\/embeddedsw\/tree\/genesys-zu-21.1<\/a>.<br \/>\nAdd the path as a local software repository and Vitis will use the Genesys ZU-specific FSBL instead of the generic one.<\/li>\n<li>The second one, by Deselecting \u201cGenerate boot components\u201d (Figure 12) and using fsbl.patch file. We will be creating the FSBL manually. This method is used in this tutorial. <img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-29140\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-12-Creating-a-new-Vitis-application-project-600x484.png\" alt=\"\" width=\"600\" height=\"484\" data-wp-pid=\"29140\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-12-Creating-a-new-Vitis-application-project-600x484.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-12-Creating-a-new-Vitis-application-project.png 976w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/li>\n<\/ol>\n<\/li>\n<li>The next step is to create a new domain with the default values, on the Application Project Details window for the Application project name, type FSBL. The target processor is the psu_cortex53_0.\n<figure id=\"attachment_29143\" aria-describedby=\"caption-attachment-29143\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-29143 size-medium\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-13-Application-project-configuration-600x484.png\" alt=\"\" width=\"600\" height=\"484\" data-wp-pid=\"29143\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-13-Application-project-configuration-600x484.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-13-Application-project-configuration.png 976w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29143\" class=\"wp-caption-text\">Figure 13 &#8211; Application Project Configuration Step 1<\/figcaption><\/figure><\/li>\n<li>Create new domain and keep the default values. On the next window select the Zynq MP FSBL template.\n<figure id=\"attachment_29141\" aria-describedby=\"caption-attachment-29141\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-29141 size-medium\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-13-Application-project-configuration-Step-2-600x484.png\" alt=\"\" width=\"600\" height=\"484\" data-wp-pid=\"29141\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-13-Application-project-configuration-Step-2-600x484.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-13-Application-project-configuration-Step-2.png 976w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29141\" class=\"wp-caption-text\">Figure 14 &#8211; Application Project Configuration Step 2<\/figcaption><\/figure><\/li>\n<li>The FSBL must be modified to initialize the Wifi module on the board. The spi_gpio.h and spi_gpio.c files will be added to the project and the xfsbl_board.h and xfsbl_board.c files are also modified with the attached patch file. The ZynqMP FSBL is located in the on-chip memory (OCM) at 0xFFFC0000 \u2013 0xFFFE9FFF. After modification it might not fit. The xfsbl_config.h file can be modified to reduce the FSBL size, by removing unused modules. A more detailed description can be found on this <a href=\"https:\/\/xilinx-wiki.atlassian.net\/wiki\/spaces\/A\/pages\/18842019\/Zynq+UltraScale+FSBL\">link<\/a>. The modifications can be integrated by applying the FSBL.patch in the src directory of the FSBL project. Navigate to the Vitis workspace directory, afterwards FSBL, then src, and copy the FSBL.patch inside this directory and execute:<br \/>\n<blockquote><p>$ patch -p0 &lt; fsbl.patch<\/p><\/blockquote>\n<\/li>\n<li>After patching the source file the FSBL.elf image can be built.<\/li>\n<li>The <a href=\"https:\/\/www.xilinx.com\/publications\/events\/developer-forum\/2018-frankfurt\/soc-platform-management.pdf\">PMU Firmware<\/a> is responsible for some Power Management, Security, Functional Safety etc. functions that most users might not need to modify. However, in some cases, the execution of the FSBL might hang at \u201cProtection configuration applied Running\u201d dialogue, if the firmware is not present in the BIN file. The PMU can be generated by File-&gt;New-&gt;Application Project. Select the previously created platform. At the Application Project Details window, select the Show all processors in the hardware specification and create a new application on the psu_pmu_0 processor.\n<figure id=\"attachment_29146\" aria-describedby=\"caption-attachment-29146\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29146\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-16-PMU-Firmware-application-project-configuration-Step-1-600x484.png\" alt=\"\" width=\"600\" height=\"484\" data-wp-pid=\"29146\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-16-PMU-Firmware-application-project-configuration-Step-1-600x484.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-16-PMU-Firmware-application-project-configuration-Step-1.png 975w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29146\" class=\"wp-caption-text\">Figure 16 &#8211; PMU Firmware application project configuration Step 1<\/figcaption><\/figure>\n<figure id=\"attachment_29144\" aria-describedby=\"caption-attachment-29144\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29144\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-17-PMU-Firmware-application-project-configuration-Step-2-600x481.png\" alt=\"\" width=\"600\" height=\"481\" data-wp-pid=\"29144\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-17-PMU-Firmware-application-project-configuration-Step-2-600x481.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-17-PMU-Firmware-application-project-configuration-Step-2.png 977w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29144\" class=\"wp-caption-text\">Figure 17 &#8211; PMU Firmware application project configuration Step 2<\/figcaption><\/figure><\/li>\n<li>Afterwards, select the \u201cZynqMP PMU Firmware\u201d template to create the default PSU Firmware.<\/li>\n<li>To generate the device-tree automatically, the Xilinx Device\u2013Tree generator repository must be downloaded with the following commands and added to the project repositories. The following commands are given in Linux Terminal environment inside the user\u2019s home directory write access is needed on the directory to execute the following commands:<br \/>\n<blockquote><p>$ git clone <a href=\"https:\/\/github.com\/Xilinx\/device-tree-xlnx\"><u>https:\/\/github.com\/Xilinx\/device-tree-xlnx<\/u><\/a><\/p>\n<p>$ cd device-tree-xlnx\/<\/p>\n<p>$ git checkout \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0xlnx_rel_v2021.1<em> (use the version of the development environment)<\/em><\/p><\/blockquote>\n<\/li>\n<li>Afterwards, the device-tree can be generated from the Vitis environment. Add the repository to the Vitis workspace in the Xilinx-&gt;Software Repositories menu (Vitis -&gt; Window -&gt; Preferences -&gt; Xilinx -&gt; Software Repository). Generate the device-tree (Vitis -&gt; Xilinx -&gt; Generate Device Tree).\n<figure id=\"attachment_29145\" aria-describedby=\"caption-attachment-29145\" style=\"width: 553px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29145\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-18-Adding-device-tree-repository-553x600.png\" alt=\"\" width=\"553\" height=\"600\" data-wp-pid=\"29145\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-18-Adding-device-tree-repository-553x600.png 553w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-18-Adding-device-tree-repository.png 856w\" sizes=\"auto, (max-width: 553px) 100vw, 553px\" \/><figcaption id=\"caption-attachment-29145\" class=\"wp-caption-text\">Figure 18 &#8211; Adding device tree repository<\/figcaption><\/figure>\n<figure id=\"attachment_29147\" aria-describedby=\"caption-attachment-29147\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-29147\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-19-Device-tree-GUI-generation-600x301.png\" alt=\"\" width=\"600\" height=\"301\" data-wp-pid=\"29147\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-19-Device-tree-GUI-generation-600x301.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-19-Device-tree-GUI-generation.png 605w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29147\" class=\"wp-caption-text\">Figure 19 &#8211; Device tree GUI generation<\/figcaption><\/figure><\/li>\n<li>\u00a0The generated board files do not contain board specific blobs before compilation. The attached device-tree.patch must be applied to the folder where the files \u00a0\u00a0\u00a0\u00a0\u00a0were generated. Navigate to the folder given at the Generate Device Tree prompt, copy the attached device-tree.patch file to this directory and execute the command:<br \/>\n<blockquote><p>$ patch \u2013p0 &lt; device-tree.patch<\/p><\/blockquote>\n<p>This will include the board-specific configuration.<\/li>\n<li>The following commands will create the binary formatted device-tree used by u-boot and the Linux kernel. The dtc command is part of the Vivado environment the command must run from a terminal where the settinsg64.sh was sourced.<br \/>\n<blockquote><p>$ gcc -I . -E -nostdinc -undef -D__DTS__ -x assembler-with-cpp -o system.dts system-top.dts<br \/>\n$ dtc -W no-unit_address_vs_reg -I dts -O dtb -o genesys-zu.dtb system.dts<\/p><\/blockquote>\n<\/li>\n<li>The remaining modules are generated entirely from the Xilinx git repository under Linux. The <a href=\"https:\/\/developer.arm.com\/tools-and-software\/open-source-software\/firmware\/trusted-firmware\">ARM Trusted Firmware<\/a> has to be generated. The FSBL will start the firmware that will start the u-boot boot loader. Run the commands from a terminal where the settinsg64.sh was sourced. Navigate to a folder with write permissions and execute:<br \/>\n<blockquote><p>$ git clone https:\/\/github.com\/Xilinx\/arm-trusted-firmware<br \/>\n$ cd arm-trusted-firmware\/<br \/>\n$ git checkout xlnx_rebase_v2.4_2021.1<br \/>\n$ make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1<\/p><\/blockquote>\n<p>The generated binary bl31.elf file can be found at \/build\/zynqmp\/release\/bl31\/<\/li>\n<li>Next is the u-boot bootloader generation. First, clone the second stage bootloader and set the u-boot environment. Navigate to a folder with write permissions and execute:<br \/>\n<blockquote><p>$ git clone https:\/\/github.com\/Xilinx\/u-boot-xlnx<\/p>\n<p>$ cd u-boot-xlnx\/<\/p>\n<p>$ git checkout xilinx-v2021.1<\/p><\/blockquote>\n<\/li>\n<li>Before u-boot compilation, some device specific configuration must be done, by copying the previously generated device-tree blob into the project:<br \/>\n<blockquote><p>$ cp &lt;path to generated device-tree&gt;\/genesys-zu.dtb &lt;path to u-boot-xlnx&gt;\/arch\/arm\/dts\/<\/p><\/blockquote>\n<\/li>\n<li>Set the environmental variables. If the environment is set up correctly, the Xilinx provided compiler can be used.<br \/>\n<blockquote><p>$ export CROSS_COMPILE=aarch64-linux-gnu-<\/p>\n<p>$ export ARCH=aarch64<\/p><\/blockquote>\n<\/li>\n<li>Generate a base configuration file for default ZynqMP configuration. This will be modified by the attached patch file.<br \/>\n<blockquote><p>$ make xilinx_zynqmp_virt_defconfig<\/p><\/blockquote>\n<\/li>\n<li>Copy the provided uboot.patch file in the u-boot-xlnx directory and run the following command to configure u-boot:<br \/>\n<blockquote><p>$ patch -p0 &lt; uboot.patch<\/p><\/blockquote>\n<\/li>\n<li>Now compile u-boot with the <em>make<\/em> command.The u-boot.elf file can be found at the source directory u-boot-xlnx if the compilation was successful.<\/li>\n<li>The last component is the Linux Kernel. First, some additional packages have to be installed on the Ubuntu system with the following command:<br \/>\n<blockquote><p>$ sudo apt-get install libncurses-dev gawk flex bison openssl libssl-dev libelf-dev libudev-dev libpci-dev libiberty-dev autoconf<\/p><\/blockquote>\n<p>Afterwards, clone the Xilinx maintained kernel from their git repository. Run the commands from a terminal where Navigate to a folder with write permissions and execute:<\/p>\n<blockquote><p>$ git clone https:\/\/github.com\/Xilinx\/linux-xlnx<\/p>\n<p>$ cd linux-xlnx\/<\/p>\n<p>$ git checkout xilinx-v2021.1<\/p><\/blockquote>\n<p>Make a ZynqMP based default configuration<\/p>\n<blockquote><p>$ make ARCH=arm64 xilinx_zynqmp_defconfig<\/p><\/blockquote>\n<p>Copy the provided patch file to the linux-xlnx folder and apply it.<\/p>\n<blockquote><p>$ patch -p0 &lt; kernel.patch<\/p><\/blockquote>\n<p>Add any additional configuration or drivers by running the menuconfig command. When done, the kernel can be compiled.<\/p>\n<blockquote><p>$ make ARCH=arm64 menuconfig<\/p>\n<p>$ make ARCH=arm64<\/p><\/blockquote>\n<p>The compiled kernel image can be found at <em>&lt;path to linux-xlnx&gt;\/arch\/arm<\/em><em>64<\/em><em>\/boot. <\/em>The name of the binary kernel file is <em>Image,<\/em> without extension. If the graphical interface is used to generate the BOOT.BIN file, the kernel file \u00a0\u00a0\u00a0\u00a0\u00a0must have extension. It can be renamed <em>Image.ub<\/em>.<\/li>\n<li>All the necessary files are generated to run the Linux the kernel. The kernel can run a small user environment from a compressed image that is extracted to the memory. This ramdisk image contains the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Init\">init<\/a> script that will <a href=\"https:\/\/en.wikipedia.org\/wiki\/Chroot\">chroot<\/a> \u00a0\u00a0\u00a0\u00a0\u00a0into the Arch Linux environment. The image is \u00a0\u00a0\u00a0\u00a0\u00a0attached, and it contains a minimal <a href=\"https:\/\/en.wikipedia.org\/wiki\/BusyBox\">BusyBox<\/a> environment and the init script (uramdisk.image.gz).Afterwards, all files must be stitched together to generate the device boot image, the BOOT.BIN file. This is the file that the baked-in firmware will search for on the FAT32 formatted first partition of the SD card. The file can be generated from terminal, using the attached bif file.\u00a0\u00a0\u00a0\u00a0 \u00a0All the files in the bif file are invoked without a path. This means that all generated files \u00a0\u00a0\u00a0\u00a0\u00a0must be in the same folder as the bif file.\u00a0\u00a0\u00a0\u00a0 \u00a0Generate the boot image with the following command:<br \/>\n<blockquote><p>$ bootgen -arch zynqmp -image FSBL_system.bif -o BOOT.BIN \u2013w<\/p><\/blockquote>\n<p>The BOOT.BIN can also be generated from the graphical environment, as the user can import the provided bif file or create a new one.<\/p>\n<p>When creating a new bif file, the first file it has to contain is the FSBL bootloader and which processor it will run on, designated by the destination_cpu option.<\/p>\n<p>[bootloader, destination_cpu = a53-0]FSBL.elf<\/p>\n<p>The second position is the PMU firmware if it exists.<\/p>\n[pmufw_image]PMUFirmware.elf<\/p>\n<p>Then the user can specify with the destination_device=pl option, the bit file for the reconfigurable part of the FPGA and the FSBL will configure it.<\/p>\n[destination_device = pl]genesys-zu.bit<\/p>\n<p>The Zynq Ultrascale devices use the ARM Trusted Firmware secure software stack, where the Linux operating system is running. As the OS runs at ARM EL1\/0 level, it has limited access to system or security-critical registers and devices. All calls from Linux to those registers and devices are routed trough the ARM Trusted Firmware, which is running at EL3, this is the next file that the FSBL loads with the EL3 level set.<\/p>\n[destination_cpu = a53-0, execution_level = el-3, trustzone]bl31.elf<\/p>\n<p>The last file needed is the u-boot bootloader that will load the Linux operating system. This will run at trust level EL2.<\/p>\n[destination_cpu = a53-0, execution_level = el-2]u-boot.elf<\/p>\n<p>U-Boot has the capability to load the Linux kernel, the ramdisk and the device-tree from multiple external sources. In the given example project these files are stitched in the BOOT.bin file with a load option telling the FSBL to load the corresponding file to the given memory address. This way, U-Boot doesn\u2019t have to load any images just simply boots by directly issuing a matching booti command.<\/p>\n[load = 0x2a00000, destination_cpu = a53-0]genesis-zu.dtb<\/p>\n[load = 0x2000000, destination_cpu = a53-0]uramdisk.image.gz<\/p>\n[load = 0x3000000, destination_cpu = a53-0]Image.ub<\/p>\n<figure id=\"attachment_29149\" aria-describedby=\"caption-attachment-29149\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-29149 size-medium\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-21-Creating-the-Boot-Image-from-the-GUI-600x431.png\" alt=\"\" width=\"600\" height=\"431\" data-wp-pid=\"29149\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-21-Creating-the-Boot-Image-from-the-GUI-600x431.png 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-21-Creating-the-Boot-Image-from-the-GUI-1024x735.png 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/Figure-21-Creating-the-Boot-Image-from-the-GUI.png 1267w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><figcaption id=\"caption-attachment-29149\" class=\"wp-caption-text\">Figure 20 &#8211; Creating the Boot Image from the GUI<\/figcaption><\/figure>\n<p>When the BOOT.BIN is generated, it \u00a0\u00a0\u00a0\u00a0\u00a0must be copied on the FAT32 formatted first partition of an SD card, and the second partition \u00a0\u00a0\u00a0\u00a0\u00a0must be ext4 formatted, containing the extracted ARCH Linux files downloaded from this <a href=\"http:\/\/os.archlinuxarm.org\/os\/ArchLinuxARM-aarch64-latest.tar.gz\">link<\/a>. Extract the archive using the tar command to the second partition of the SD card.<\/p>\n<blockquote><p>$ tar -xvf archlinuxarm-aarch64-latest.tar.gz<\/p><\/blockquote>\n<p>The SD card can be formatted from any Linux Distribution using a GUI app like gparted or from terminal, using the <a href=\"https:\/\/xilinx-wiki.atlassian.net\/wiki\/spaces\/A\/pages\/18842385\/How+to+format+SD+card+for+SD+boot\">fdisk<\/a> command. If everything is applied correctly, the Arch Linux operating system will start, if the JP3 jumper is set to the SD card position. Connect the USB cable to the J8 port, open a serial terminal app like Putty, select the virtual COM port, set baud rate to 115200. If everything is set correctly, the Arch Linux will boot and a login terminal will appear.<\/p>\n<p>&nbsp;<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<div class='watch-action'><div class='watch-position align-left'><div class='action-like'><a class='lbg-style6 like-29128 jlk' data-task='like' data-post_id='29128' data-nonce='05046dc8ab' rel='nofollow'><img src='https:\/\/digilent.com\/blog\/wp-content\/plugins\/wti-like-post-pro\/images\/pixel.gif' title='Like' \/><span class='lc-29128 lc'>0<\/span><\/a><\/div><div class='action-unlike'><a class='unlbg-style6 unlike-29128 jlk' data-task='unlike' data-post_id='29128' data-nonce='05046dc8ab' rel='nofollow'><img src='https:\/\/digilent.com\/blog\/wp-content\/plugins\/wti-like-post-pro\/images\/pixel.gif' title='Unlike' \/><span class='unlc-29128 unlc'>0<\/span><\/a><\/div><\/div> <div class='status-29128 status align-left'>Be the 1st to vote.<\/div><\/div><div class='wti-clear'><\/div>","protected":false},"excerpt":{"rendered":"<p>Step-by-Step Guide to Building an Arch Linux-Based Project This paper will provide a step-by-step guide to build from ground up a Genesys ZU development board-based hardware and software project that &hellip; <\/p>\n","protected":false},"author":50,"featured_media":29151,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[4267,35,1563],"tags":[1662,453],"ppma_author":[4502],"class_list":["post-29128","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-fpga","category-guide","tag-fpga","tag-vivado"],"jetpack_featured_media_url":"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2022\/04\/GenesysZU-top-RevA-1000.png","authors":[{"term_id":4502,"user_id":50,"is_guest":0,"slug":"davidh","display_name":"David Horn","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/917c337136844f075c76fcf4a0c3b94aa8c225366009ebf63c08fcb9ce6d0e52?s=96&d=mm&r=g","1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":"","9":"","10":""}],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts\/29128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/users\/50"}],"replies":[{"embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/comments?post=29128"}],"version-history":[{"count":1,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts\/29128\/revisions"}],"predecessor-version":[{"id":29630,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts\/29128\/revisions\/29630"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/media\/29151"}],"wp:attachment":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/media?parent=29128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/categories?post=29128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/tags?post=29128"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=29128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}