= !ZedBoard and Microzed Board Support = [[TOC(Boards/Zynq - Zedboard , depth=4)]] The page details how to run RTEMS on a [http://microzed.org/product/zedboard ZedBoard] and [http://microzed.org/product/microzed Microzed] board. The !ZedBoard and Microzed boards are supported by [http://www.denx.de/wiki/U-Boot U-Boot] and [http://www.denx.de/wiki/U-Boot U-Boot] can boot RTEMS. Please refer to the U-Boot documentation and the internet for documentation and example on using U-Boot. This page captures some examples on using U-Boot with these boards however is not all that can be done with U-Boot and running RTEMS. = First Stage Boot Loaders = The U-Boot bootloader comes with an FSBL. If you want to create one for yourself you can use the {{{mkbootimage}}} tool as an open source replacement for Xilinx's {{{bootgen}}} tool. The tool is available in github here https://github.com/kiwichris/zynq-mkbootimage. = Boot Mode = RTEMS can be run on the !ZedBoard and the Microzed boards from a number of sources. You select the boot mode you need based on what you are wanting to do. For example, if you are developer writing an RTEMS application you may use JTAG, while production may boot from QSPI flash. A developer may also boot from QSPI or SD card and download RTEMS over the network using the RTEMS debugger. == JTAG Debugging == JTAG can used to reset and initialise the hardware, load software and debug applications. There are a range of JTAG debugging solutions with varying prices available that integrate with RTEMS. JTAG lets you debug low level software such as boot loaders, exception handlers as well as support hardware watch points to help find difficult run time bugs. === Lauterbach === The Lauterbach debugger with trace support works with the !ZedBoard and Microzed. The Lauterbach support a range of real-time trace options. === Flyswatter2 === The Flyswatter2 pod from Tincan Tools combines with OpenOCD to provide an effective JTAG debugging solutions. Trace is not supported. === PS7 Initialisation === The Xilinx tools generate a set of files based on the System Z configuration call `ps7_init`. The Xilinx SDK embeds the `ps7_init.c` file in the First Stage Boot Loader (FSBL) to configure the Zynq hardware. Xilinx also creates a TCL version called `ps7_init.tcl` and it is used by Xilinx's XDM software to initialise the hardware before loading code. The [wiki:Debugging/OpenOCD/Xilinx_Zynq#XilinxSDKPS7Initialisation PS7 Initialisation] page details how to do this. === Zedboard Jumpers === TDB === Microzed Jumpers === The jumpers to boot in JTAG mode are: ||= JP3 =||= JP2 =||= JP1 =|| || X || X || X || || X || X || X || || - || - || - || == QSPI Flash == TDB == SD Card == The SD card mode boots from a DOSFS MBR partition. The Zynq's ROM code searches for the file `BOOT.BIN` in the root directory of a DOSFS partition and loads it. The `BOOT.BIN` file conforms the FSBL format documented in the Zynq TRM. Be-careful updating the SD card on a host operating system that supports Long File Names (LNF). If you happen to rename a file that is a LFN format name to `BOOT.BIN` the directory entry in the root directory on the DOSFS may still be in the LFN format and the Zynq'c ROM code will not see it. === Microzed Jumpers === The jumpers to boot in QSPI flash mode are: ||= JP3 =||= JP2 =||= JP1 =|| || - || - || X || || X || X || X || || X || X || - || = U-Boot = The [http://www.denx.de/wiki/U-Boot U-Boot] boot loader supports the !ZedBoard and Microzed boards. I do not used the Xilinx version of U-Boot they provide on Github. I also do not use any binary builds available for download. == U-Boot License == U-Boot is license under GPL-2 which means you will need to make the source code for U-Boot available to users of your product. Please check the GPL-2 license to make sure you can use U-Boot and what you need to do to meet the license. == Building U-Boot == To build U-Boot for an ARM processor you need an ARM cross-compiler. The following list what you need to install for your host. ||= Host OS =||= Commands =|| || FreeBSD || {{{ $ pkg install arm-none-eabi-binutils arm-none-eabi-gcc }}} ''Please add the set up your host if not listed.'' Get the source code from the project's git repository: {{{ $ git clone git://git.denx.de/u-boot.git }}} My last working build is `b615267633996a9410a88b54a55965d8b021f6f8`. Change into the `u-boot`directory and run the following script `mk-zed`: {{{ $ cat ../mk-zed #! /bin/sh gmake CROSS_COMPILE=arm-none-eabi- distclean gmake CROSS_COMPILE=arm-none-eabi- zynq_zed_config gmake CROSS_COMPILE=arm-none-eabi- HOSTCC=cc }}} ''Note'': `gmake` is used because `make` on FreeBSD is a BSD compatible `make` and U-Boot requires the GNU `make`. The `HOSTCC` define is added to the U-Boot build command line because the FreeBSD's default compiler is `clang` and U-Boot defaults to `gcc`. The files built by U-Boot you need to use are: ||= File =||= Description =|| || `spl/boot.bin` || U-Boot's FSBL || || `arch/arm/dts/zynq-zed.dtb` || !ZedBoard device tree blob || || `arch/arm/dts/zynq-microzed.dtb` || Microzed board device tree blob || || `u-boot.img` || U-Boot executable loaded by the U-Boot FSBL || == U-Boot Environment == You need to create a suitable environment file that defines how U-Boot loads your RTEMS executable. U-Boot lets you [http://www.denx.de/wiki/view/DULG/UBootScripts script] commands. U-Boot has a large number of [http://www.denx.de/wiki/view/DULG/UBootCommandLineInterface commands] and you can script these to boot your RTEMS executable. You can use the U-Boot control to enter commands to figure what works. === Network Booting RTEMS === Create a U-Boot script file called `uEnv.txt` to boot RTEMS from the network using the DHCP and TFTP protocols. {{{ # cat sd/uEnv.txt bootfile=zed/rtems.img loadaddr=0x02000000 uenvcmd=echo Booting RTEMS from net; set autoload no; dhcp; set serverip 10.10.5.1; tftpboot zed/rtems.img; bootm; }}} '''Note:''' 1. The `bootfile` is the file name used by the TFTP protocol. The path is relative to the top level path the TFTP server is configured to serve file from. This path is available to the development host machines so the executable can be updated after a build. 1. The `loadaddr` is the address U-Boot loads the image before it is relocated to the address RTEMS is built with. This value needs to be valid RAM and it is best if it does not overlap with the image's final located address. 1. The subnet is `10.10.5.0/24` and it has a DHCP server. The `dhcp;` command tells U-Boot to get an IP address using the DHCP protocol and optionally download an executable using the TFTP protocol. I do not define a boot file in the DHCP server so it can vary for each board on networking that is net booting. 1. The TFTP server IP address is manually set to `10.10.5.1`. == SD Card Set Up == Create a MBR DOSFS partition on an SD card with enough space to hold the files needed. The card I have: {{{ # df -h /dev/da0s1 Filesystem Size Used Avail Capacity Mounted on /dev/da0s1 64M 1.3M 63M 2% /mnt/sd }}} Copy the files: {{{ # mount -t msdosfs /dev/da0s1 /mnt/sd # cp spl/boot.bin /mnt/sd/boot.bin # cp arch/arm/dts/zynq-microzed.dtb /mnt/sd/system.dtb # cp u-boot.img /mnt/sd/u-boot.img # cp uEnv.txt /mnt/sd/uEnv.txt # umount /mnt/sd }}} '''Note:'' the mount command is for FreeBSD. = RTEMS Application = The RTEMS executable is an ELF format file and U-Boot requires custom image format which means you need to convert the RTEMS ELF executable file to the custom image format. The following script is an example of how you perform this conversion: {{{ $ cat rtems-zynq-mkimg #! /bin/sh OBJCOPY_FOR_TARGET=arm-rtems4.12-objcopy OBJCOPY="$OBJCOPY_FOR_TARGET" EXE_NAME=$1 START_ADDR=0x00104000 ENTRY_ADDR=0x00104000 ${OBJCOPY} -R -S --strip-debug -O binary "$EXE_NAME" "$EXE_NAME.bin" || exit 1 cat "$EXE_NAME.bin" | gzip -9 >"$EXE_NAME.gz" mkimage \ -A arm -O rtems -T kernel -a $START_ADDR -e $ENTRY_ADDR -n "RTEMS" \ -d "$EXE_NAME.gz" "$EXE_NAME.img" }}} '''Note:''' 1. The `arm-rtems4.12-objcopy` is part of the RTEMS ARM binutils package built by the RSB. 1. The `START_ADDR` the base address the RTEMS executable is linked too. This is set in the RTEMS BSP code for the !ZedBoard and Microzed board. 1. The `ENTRY_ADDR` is the entry point to the RTEMS executable. This again is BSP specific. For the ZedBoard the entry point is the base address. 1. The RTEMS executable is stripped of any debugging information and converted to a binary image and then compressed. Stripping the executable or debugging information does not effect your ability to debug the application because debugging uses the ELF image which still contains the debugging information. 1. The host tool `mkimage` is built as part of U-Boot. You can find it under `toos/mkimage`. You need to copy it somewhere in your path or add a path so it can be executed. = RTEMS Libbsd Debugger Application = The RTEMS Libbsd package builds an RTEMS Debugger application. This test application lets you connect to the running RTEMS application using GDB. You can find the application in the `rtems-libbsd` build tree: {{{ $ ls -las build/arm-rtems4.12-xilinx_zynq_zedboard/debugger01.exe 19745 -rwxr-xr-x 1 chris user 20171796 Dec 23 14:39 build/arm-rtems4.12-xilinx_zynq_zedboard/debugger01.exe }}} Convert this executable to the U-Boot image format using the script above and copy to the TFTP server then boot the board: {{{ U-Boot SPL 2016.05-00598-gb2f1858-dirty (Jun 04 2016 - 15:32:53) mmc boot Trying to boot from MMC1 reading system.dtb reading uImage spl_load_image_fat: error reading image uImage, err - -1 reading u-boot.img reading u-boot.img U-Boot 2016.05-00598-gb2f1858-dirty (Aug 05 2016 - 08:30:10 +1000) Model: Zynq MicroZED Board Board: Xilinx Zynq DRAM: ECC disabled 1 GiB MMC: sdhci@e0100000: 0 SF: Detected S25FL128S_64K with page size 256 Bytes, erase size 64 KiB, total 16 MiB *** Warning - bad CRC, using default environment In: serial@e0001000 Out: serial@e0001000 Err: serial@e0001000 Model: Zynq MicroZED Board Board: Xilinx Zynq Net: ZYNQ GEM: e000b000, phyaddr 0, interface rgmii-id Warning: ethernet@e000b000 (eth0) using random MAC address - fa:69:35:9e:04:2f eth0: ethernet@e000b000 reading uEnv.txt 162 bytes read in 10 ms (15.6 KiB/s) Importing environment from mmc ... Checking if uenvcmd is set ... Running uenvcmd ... Booting RTEMS XxX from net ethernet@e000b000 Waiting for PHY auto negotiation to complete...... done BOOTP broadcast 1 BOOTP broadcast 2 DHCP client bound to address 10.10.5.247 (257 ms) Using ethernet@e000b000 device TFTP from server 10.10.5.1; our IP address is 10.10.5.247 Filename 'zed/rtems.img'. Load address: 0x2000000 Loading: ################################################################# ## 9 MiB/s done Bytes transferred = 976253 (ee57d hex) ## Booting kernel from Legacy Image at 02000000 ... Image Name: RTEMS Image Type: ARM RTEMS Kernel Image (gzip compressed) Data Size: 976189 Bytes = 953.3 KiB Load Address: 00104000 Entry Point: 00104000 Verifying Checksum ... OK Uncompressing Kernel Image ... OK ## Transferring control to RTEMS (at address 00104000) ... *** LIBBSD DEBUGGER 1 TEST *** RTEMS Shell on /dev/console. Use 'help' to list commands. [/] # nexus0: cgem0: on nexus0 miibus0: on cgem0 e1000phy0: PHY 0 on miibus0 e1000phy0: none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT-FDX, 1000baseT-FDX-master, auto cgem0: Ethernet address: fa:69:35:9e:04:2f zy7_slcr0: on nexus0 notice: cgem0: link state changed to DOWN add host 10.10.5.1: gateway cgem0 add net default: gateway 10.10.5.1 rtems-db: remote running rtems-db: tcp remote: listing on port: 1122 notice: cgem0: link state changed to UP }}} The U-Boot DHCP address may not be the RTEMS IP address. In my case I have a static IP configured in LibBSD: {{{ [/] # cat /etc/rc.conf cat /etc/rc.conf cat: /etc/rc.conf: No such file or directory [/] # ifconfig ifconfig cgem0: flags=8843 metric 0 mtu 1500 options=80008 ether fa:69:35:9e:04:2f inet 10.10.5.15 netmask 0xffffff00 broadcast 10.10.5.255 inet6 fe80::f869:35ff:fe9e:42f%cgem0 prefixlen 64 scopeid 0x1 nd6 options=21 media: Ethernet autoselect (1000baseT ) status: active lo0: flags=8049 metric 0 mtu 16384 options=600003 inet 127.0.0.1 netmask 0xffffff00 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 nd6 options=21 }}} The `ifconfig` command shows the IP address is `10.10.5.15`. We can use this to connect GDB. On the development host run GDB using: {{{ $ arm-rtems4.12-gdb -nx build/arm-rtems4.12-xilinx_zynq_zedboard/debugger01.exe GNU gdb (GDB) 7.12 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-freebsd10.3 --target=arm-rtems4.12". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from build/arm-rtems4.12-xilinx_zynq_zedboard/debugger01.exe...done. (gdb) target remote 10.10.5.15:1122 Remote debugging using 10.10.5.15:1122 _Thread_Priority_update (queue_context=0x2866c0) at /opt/work/chris/rtems/kernel/rtems.git/c/src/../../cpukit/score/src/threadchangepriority.c:344 344 n = queue_context->Priority.update_count; (gdb) info thread Id Target Id Frame * 1 Thread 1.167837697 (UI1 (0a010001), priority(c:254 r:254), stack(s: 32768 a:0x429448), state(DELAY SUSP Wisig)) _Thread_Priority_update (queue_context=0x2866c0) at /opt/work/chris/rtems/kernel/rtems.git/c/src/../../cpukit/score/src/threadchangepriority.c:344 2 Thread 1.167837698 (SHLL (0a010002), priority(c: 1 r: 1), stack(s: 32768 a:0x431c08), state(SUSP)) _Thread_Priority_update (queue_context=0x2866c0) at /opt/work/chris/rtems/kernel/rtems.git/c/src/../../cpukit/score/src/threadchangepriority.c:344 (gdb) kill Kill the program being debugged? (y or n) y (gdb) q }}} '''Note:''' 1. The GDB `-nx` option is being used to stop loading any `.gdbinit` files. This done when testing the GDB connection. For a real development environment you should create a suitable `.gdbinit` file. 2. The remote port on the RTEMS target is `1122`. You can configure this in the RTEMS application. 3. Killing the session using the `kill` command reboots the target. If you have updated the executable on the TFTP before running this command a new version of the application will be download.