DESK-XZ7-L/pdf
History[edit | edit source]
DESK-XZ7-L History | |||
---|---|---|---|
Version | Issue Date | Notes | Refers to |
1.0.0-rc1 | Q1 2023 | DESK-XZ7-L-1.0.0 rc1 release | BORA SOM |
1.0.1 | Jan 2024 | DESK-XZ7-L-1.0.1 release | BORA SOM |
BORA Xpress SOM | |||
BORA Lite SOM | |||
1.1.0 | Jun 2024 | DESK-XZ7-L-1.1.0 release | BORA SOM |
BORA Xpress SOM | |||
BORA Lite SOM |
General Information[edit | edit source]
Release Notes[edit | edit source]
DAVE Embedded Systems adds to the latest Vivado/Petalinux BSP from Xilinx the customization required to support the SOC platform. For this reason most of the documentation provided by Xilinx remains valid for the DESK development kit.
However, some customization is required, in particular at bootloader and linux kernel levels.
The following table reports the DESK releases information.
DESK version | |
---|---|
Release number | 1.1.0 |
Release type | Minor |
Status | Released |
Release date | Jun 2024 |
Release notes | Ver 1.1.0 |
Product support | BORA / BORA Xpress / BORA Lite |
Drivers |
SPI NOR Flash (boot) SD |
Vivado version | 2021.2 |
Petalinux version | 2021.2 |
U-Boot version | U-boot Version v2021.01 |
Linux version | Linux Kernel rebase version 5.10 |
Build system | Yocto Gatesgarth (3.2.0) |
(*): ask Sales department for a dedicated Application Note
DESK 1.1.0[edit | edit source]
Release notes:
- fix bug for use all NAND size
- enable ETH1 in Linux for Bora and Borax platforms
Known Limitations[edit | edit source]
The following table reports the known limitations of this DESK release:
Issue | Description |
---|---|
microSD hotplug | microSD hotplug functionality not work correctly |
Downloadable binary images[edit | edit source]
All binary images for DESK-XZ7-L are hosted on DAVE Embedded System mirror server. There you can find a sub directory for each version of this development kit.
A summary of images with a brief description can be found into the table below:
Image | DESK-XZ-L version 1.0.1 | ||||
---|---|---|---|---|---|
Platform | BORA Evaluation Kit | BORA Xpress Evaluation Kit | BORA Lite Evaluation Kit | BORA Lite EVK with NAND support | BORA Lite Evaluation Kit |
Boot storage device | SD / NOR | SD / NOR | SD / NOR | SD (NAND storage support) | NAND |
bootscript | boot.scr | boot.scr | boot.scr | boot.scr | - |
boot.bin | BOOT.BIN | BOOT.BIN | BOOT.BIN | BOOT.BIN | BOOT.BIN |
Fit image | image.ub | image.ub | image.ub | image.ub | - |
SD card image | dave-image-devel.wic.bz2 | dave-image-devel.wic.bz2 | dave-image-devel.wic.bz2 | dave-image-devel.wic.bz2 | dave-image-devel.tar.gz |
DESK 1.0.1[edit | edit source]
Release notes:
- Major change to Xilinx BSP 2021.2
Known Limitations[edit | edit source]
The following table reports the known limitations of this DESK release:
Issue | Description |
---|---|
NAND | Zynq7000 NAND controller can access up to 512MB |
Downloadable binary images[edit | edit source]
All binary images for DESK-XZ7-L are hosted on DAVE Embedded System mirror server. There you can find a sub directory for each version of this development kit.
A summary of images with a brief description can be found into the table below:
Image | DESK-XZ-L version 1.0.1 | ||||
---|---|---|---|---|---|
Platform | BORA Evaluation Kit | BORA Xpress Evaluation Kit | BORA Lite Evaluation Kit | BORA Lite EVK with NAND support | BORA Lite Evaluation Kit |
Boot storage device | SD / NOR | SD / NOR | SD / NOR | SD (NAND storage support) | NAND |
bootscript | boot.scr | boot.scr | boot.scr | boot.scr | - |
boot.bin | BOOT.BIN | BOOT.BIN | BOOT.BIN | BOOT.BIN | BOOT.BIN |
Fit image | image.ub | image.ub | image.ub | image.ub | - |
SD card image | dave-image-devel.wic.bz2 | dave-image-devel.wic.bz2 | dave-image-devel.wic.bz2 | dave-image-devel.wic.bz2 | dave-image-devel.tar.gz |
Release types[edit | edit source]
DESK release type can be:
- Major, when substantial changes are applied to the BSP (eg: major kernel version upgrades) or to the development kit (eg: new features, build system updates, ..). This usually means that a new DVDK is created for the DESK release
- Maintenance, when minor updates and bug fixes are introduced. This usually means that the DVDK remains the same as provided with the previous major version, and only an update of the source tree repositories (and the tftp binaries) is required
As an example, DESK 1.1.0 is a maintenance release, so it provides the DVDK released with the 1.0.0 major release; customers can easily upgrade to the 1.1.0 release by updating the software components as described in Synchronizing git repositories.
Supported platforms[edit | edit source]
The following table reports the supported platforms in this DESK release:
Platform | Description |
---|---|
BORA Evaluation Kit | Evaluation kit using BORA SOM |
BORA Xpress Evaluation Kit | Evaluation kit using BORA Xpress SOM |
BORA Lite Evaluation Kit | Evaluation kit using BORA Lite SOM |
Build host[edit | edit source]
Before run petalinux-build, please perform the following command
ssh -T git@git.dave.eu
We assume that:
- Xilinx Vivado 2021.2 is installed into
/opt/Xilinx/2021.2
directory - Xilinx Petalinux 2021.2 is installed into
/opt/Xilinx/petalinux/2021.2
directory - Ubuntu
20.04
is used as build host
For more information about setup of host machine for build Petalinux, Vivado and Vitis, please see DESK-XZ7-L-AN-0001
ConfigID and UniqueID[edit | edit source]
ConfigID[edit | edit source]
ConfigID is a new feature of DAVE Embedded Systems products. Its main purpose is providing an automatic mechanism for the identification of the product model and configuration.
With ConfigID, we aim at:
- completing the hardware configuration information that the software can't normally auto-detect (i.e. RAM chip version,...), implementing a dedicated reliable detect procedure
- when required, overriding the auto-detected hardware configuration information
When implemented, this mechanism allows for:
- initializing in the proper way the hardware platform, based on the specific features and parameters of the product, using a common software base (eg: a typical case is the SDRAM controller parameters, which must be configured by U-Boot depending on the particular memory chip, which can be different for the various SOM models)
- getting the complete hardware configuration (combining ConfigID with the information collectable at runtime) of a product deployed on the field
In simple words, model identification means the capability of reading a numerical code, stored in an available device (SOC's OTP , I2C EEPROM, 1-wire memories, protected NOR flash, etc.)
There are two ConfigIDs:
- SOM ConfigID: which reflects the characteristics of the SOM (stored on the SOM itself)
- Carrier Board (CB) ConfigID: which reflects the characteristics of the carrier board that hosts the SOM (stored on the carrier board itself and read by the SOM at boot time)
UniqueID[edit | edit source]
An additional attribute is UniqueID, which is a read-only code which univocally identifies a single product and is used for traceability.
It is worth remembering that ConfigID and UniqueID are independent from product serial number. |
Customer's action[edit | edit source]
DAVE Embedded Systems recommends to be up-to-date with Official SOM's BSPs for taking advantages of ConfigID/UniqueId features: this is the only required action.
- ConfigID advantage: to allow U-Boot bootloader to be executed only with the correct configuration (if the U-Boot loaded is not the proper one, it may stop execution avoiding incorrect behaviour)
- UniqueID advantage: to trace univocally each individual SOMs and, in turn, all the on-the-field equipments
ConfigID values[edit | edit source]
ConfigID is a N-bit (typically N>8) signed integer, that can have the following values:
- < 0: error
- -1: not initialized
- = 0: ConfigID legacy
- for prototypes (ConfigID not yet defined) or for products manufactured before the introduction of the ConfigID feature
- > 0: valid ConfigID
- values are reported accordingly with the specific product table
Hardware implementations of the ConfigID[edit | edit source]
The following paragraphs briefly describe the available solutions for storing the ConfigID.
OTP on the SOC[edit | edit source]
Some SOCs provides programmable OTPs (eg. for security, MAC address, boot modes, etc). Usually, some of these are general purpose registers and can be managed by the user.
This is the ideal implementation, because:
- ConfigID is stored in the most important component of the SOM
- the component that hosts the ConfigID is NOT optional
- typically, a very selective lock can be forced. In general, for reliability and/or security reasons, OTP areas used to store ConfigIDs may be locked during the manufacturing process.
OTP 1-wire memory[edit | edit source]
This implementation requires a 1-wire memory chip.
I2C Eeprom[edit | edit source]
This implementation requires connecting an EEPROM to an I2C bus of the SOC. Moreover, routing a write protect pin to the SOM connector is required.
NOR Flash SPI[edit | edit source]
This implementation requires a NOR flash connected to the SPI bus of the SOC.
DAVE Embedded Systems' hardware implementation[edit | edit source]
DAVE's SOCs implement the ConfigID feature depending on hardware Capabilities of the SOCs. The following list shows the priority used for its implementation:
- OTPs
- example: AXEL family processor (i.MX6) implements ConfigID using processor's OTP
- AXEL uses GP1 eFuse register to store ConfigID
- NOR Flash SPI
- example: DIVA family processor (AM335x) implements ConfigID using NOR SPI (if present)
- DIVA and BORA use the first 32bytes OTP block on NOR SPI to store ConfigID (and its CRC32), UniqueID (and its CRC32)
- I2C Eeprom
- example: DIVA family processor (AM335x) or BORA Lite processor (ZYNQ) implements ConfigID using I2C Eeprom when NOR SPI is not present (module boots from NAND or SD)
- DIVA and BORA Lite use the first 32bytes on I2C EPROM to store ConfigID (and its CRC32), UniqueID (and its CRC32)
- 1-wire
- example: latest AXEL Lite, AXEL ULite and BORA/BORA Xpress/BORA Lite Evaluation Kits implement CB ConfigID using the onboard 1-wire device (DS2431)
Software implementation[edit | edit source]
U-Boot[edit | edit source]
u-boot integrates the software routines for reading and displaying the ConfigID: hereunder an example of SOM ConfigID at startup:
U-Boot 2013.04-00010-gcb05b30 (Jun 26 2015 - 12:49:26)-xelk-2.1.0 CPU: Freescale i.MX6Q rev1.5 at 792 MHz CPU: Temperature 47 C, limits (-40 C, 125 C), calibration data: 0xc0 Reset cause: POR Environment: SPI Flash I2C: ready DRAM: 2 GiB Now running in RAM - U-Boot at: 8ff35000 NAND: 512 MiB MMC: FSL_SDHC: 0, FSL_SDHC: 1 SF: Detected S25FL256S with page size 64 KiB, total 32 MiB In: serial Out: serial Err: serial Power: found PFUZE100 (devid=10, revid=21) SOM ConfigID#: 00000003 SOM UniqueID#: df646299:0b0579d4
For accessing these information on Linux procfs
, the device tree must be modified (using u-boot fdt command): for example:
DIVA# setenv fdtfixup 'fdt addr ${fdtaddr}; run fdtfixup_configid' DIVA# setenv fdtfixup_configid 'fdt set / som_configid ${som_configid#}; fdt set / som_uniqueid ${som_uniqueid#}; fdt set / cb_configid ${cb_configid#}; fdt set / cb_uniqueid ${cb_uniqueid#}'
Linux[edit | edit source]
It is possible to read the ConfigID/UniqueID via procfs
; for example:
root@axel-lite:~# cat /proc/device-tree/som/configid && echo 00000003 root@axel-lite:~# cat /proc/device-tree/som/uniqueid && echo df646299:0b0579d4 root@axel-lite:~#
Legacy device tree, has a sightly different procfs
structure:
root@axel-lite:~# cat /proc/device-tree/som_configid && echo 00000003 root@axel-lite:~# cat /proc/device-tree/som_uniqueid && echo df646299:0b0579d4 root@axel-lite:~#
A real case example of ConfigID benefit[edit | edit source]
The ConfigID benefit is clear when:
- there is a number of products deployed on the field
- the products deployed on the field needs a SW update
The ideal scenario is that all products are equal and there are no differences on the Bill Of Material (BOM):
In this case there are no problems to deploy a new SW update on the field: all products have the same HW configuration, then the same SW configuration.
Unfortunately, this is an ideal scenario. The reality is that:
- component obsolescence
- product shortage
- second source strategies
force to have an on-the-field different version of product (with same functionalities but with different HW configuration) which doesn't permit to realize what proposed in the ideal case.
The usage of the ConfigID technique, allows the running SW to identify the underlying HW configuration and automatically adapt the BSP (i.e. the driver layer) to properly use the HW subsystems: this, maintaining the overall product features identical to the final User point-of-view. |
With a scenario, like the one described above, if you would like to update the SW you need to implement a strategy for understanding what platform version is going to be updated. The Config ID is used exactly for this goal.
The ConfigID provides to the software update routine the information on which product version is so the update can be adapted to the exact product version.
In this way, you can distribute one single version of the software update which will automatically adapt itself to the currently running platform.
How to handle After Sales with Config ID[edit | edit source]
One of the mos common questions about Config ID is how to handle the Config ID issue. Below is described with an example how to handle it.
This product is returned from the field with a problem on the display:
After Sales Dept analizes the product and decide to substitute the display. The problem is that the existing display is not available - because of is End Of Life (EOL) - and it is required to move to a different display: in the product a different Config ID will be written because of the 2 displays requires a dedicated SW version and cannot be distinguished automatically during the startup. The final result is to have the similar product:
As indicated, the new display requires a different Config ID (from A to B) so it can be updated with an easy software routine before start the SW update. This Config ID update routine can be implemented in manufacturing facility typically using a dedicated USB pen drive which modify the saved ConfigID to the new one depending on the storage memory in use
ConfigID[edit | edit source]
This article describes how the ConfigID is implemented in the products supported by the DESK-XZ7-L Linux Kit.
Hardware implementation[edit | edit source]
BORA family uses the first 32bytes OTP block on NOR SPI to store ConfigID (and its CRC32), UniqueID (and its CRC32). For BORA Lite module configured for booting from NAND, the ConfigID is stored on internal I2C EPROM: see here for more information.
U-Boot integrates the software routines for reading and displaying the ConfigID. Hereunder an example of SOM ConfigID at startup:
... SOM ConfigID#: 00000002 SOM UniqueID#: fffffefc:fffffefc CB ConfigID#: 00000001 CB UniqueID#: a600000f:24188b2d ...
Generally speaking[edit | edit source]
- SOM ConfigID is used to identify the configuration of the basic features of the SOM
- CB ConfigID is used to identify the peripherals and the I/O interfaces.
Booting from NFS[edit | edit source]
This configuration is very helpful during software development (both for kernel and applications). The kernel image is downloaded via TFTP
while the root file system is remotely mounted via NFS
from the host. It is assumed that the development host:
- is connected with the target host board through an ethernet LAN
- exports the directory containing the root file system for the target through the NFS server
- runs a TFTP server
- has a proper subnet IP address
DESK-XZ7-L Virtual Machine is properly configured for the TFTP and NFS debug.
In any case, some variables have to be configured on the target and the VM itself has to be configured with respect to the network environment.
Host (Virtual Machine) configuration[edit | edit source]
The DESK-XZ7-L Virtual Machine has the tftp and nfs services already running. Optionally, their configuration has to be changed according to the network configuration to which the target is connected.
Check and properly configure the items describe in VirtualBox Network Configuration
Target configuration[edit | edit source]
The IP address for the server and target should be configured: as an example (for a network subnet 192.168.0.x
)
u-boot=> setenv serverip 192.168.10.100 u-boot=> setenv ipaddr 192.168.10.56 u-boot=> setenv gatewayip 192.168.10.254 u-boot=> setenv netmask 255.255.255.0 u-boot=> setenv netdev eth0
serverip
is the IP address of the host machine running the tftp/nfs serveripaddr
is the IP address of the targetgatewayip
is the gateway address of the targetnetmask
is the netmask address of the targetnetdev
is the name of the ethernet interface of the target
For using the DVDK Virtual Machine, a static IP address configuration has been selected, so the U-Boot variable ip_dyn
has to be set to no:
u-boot=> setenv ip_dyn no
Boot via NFS with PXE protocol[edit | edit source]
Booting via pxe
protocol is a very simple and efficient way to save a lot of time to update. In this case, the following artifacts will be downloaded from our mirror server or built with Petalinux:
zImage
, this file has to be installed in your host device directory for tftp server, configurated forpxe
, for example/tftpboot/bora/
system.dtb
, this file has to be installed in your host device directory for tftp server, configurated forpxe
, for example/tftpboot/bora/
rootfs.tar.gz
, this file has to be decompressed in your host device directory/home/dvdk/nfsroot
For more information about boot and configuration files see DESK-XZ7-L-AN-0003: using PXE protocol for boot
Boot via NFS with Petalinux[edit | edit source]
In the case of NFS Boot, the root file system is mounted through NFS
but the bootloader (FSBL, bitstream, U-Boot) and kernel can be downloaded using various methods, for example with JTAG, micro SD or tftp server.
To boot your target via NFS
, you need to update your configuration file with the following command:
petalinux-config
Here below there are properties that you have to update:
CONFIG_SUBSYSTEM_ROOTFS_NFS
SUBSYSTEM_NFSROOT_DIR
CONFIG_SUBSYSTEM_NFSSERVER_IP
CONFIG_SUBSYSTEM_TFTPBOOT_DIR
For more information about NFS Boot with Petalinux see Petalinux guide.
Development[edit | edit source]
Synchronizing the repository[edit | edit source]
In DESK-XZ7-L, the following source trees are clones of the correspondent DAVE Embedded Systems git repositories:
Component | GIT Remote |
---|---|
Vivado | git@git.dave.eu:desk-xz-l/vivado.git
|
Petalinux | git@git.dave.eu:desk-xz-l/petalinux.git
|
U-Boot | git@git.dave.eu:desk-xz-l/u-boot-xlnx.git
|
There are two main repositories to:
- track and reproduce hardware design with Vivado
- track and reproduce Petalinux/Yocto build
Additional repositories will be used to track other piece of software that requires customization (e.g. U-Boot bootloader, Linux kernel, sample application and so on)
Access to DAVE Embedded Systems' git repositories is granted to the development kit's owners only. Please refer to this page for detailed instructions on how to get access.
Instructions[edit | edit source]
The components listed in the table above can be kept in sync and up to date with DAVE Embedded Systems' repositories.
Once the git account has been enabled, the developer can:
- clone the repository with the
git clone <git_remote_repository> -b desk-xz7-l-1.1.0
command. In case of clone aboutPetalinux
use the--recursive
option - synchronize a source tree entering the repository directory and launching the
git fetch origin
command
Please note that git fetch doesn't merge the commits on the current branch. To do that, the developer should run the git merge
command or replace the fetch-merge process with a single git pull
command. Please note that the recommended method is the fetch-merge process. For further information on Git, please refer to the official Git Documentation
Vivado installation path, in this documentation, is the |
Creating and building the Vivado project[edit | edit source]
The Vivado repository allows to:
- track hardware/fpga related sources/configuration
- reproduce hardware design output (FPGA bitstream, XSA) using TCL scripts
Development kit TCL scripts supported are the following one:
Script | Boot |
---|---|
recreate_prj_bora.tcl
|
uSD and QSPI-NOR |
recreate_prj_bora_ETH1.tcl
|
uSD and QSPI-NOR with ETH1 support |
recreate_prj_borax_BASE.tcl
|
uSD and QSPI-NOR |
recreate_prj_borax_ETH1.tcl
|
uSD and QSPI-NOR with ETH1 support |
recreate_prj_boralite_BASE.tcl
|
uSD and QSPI-NOR |
recreate_prj_boralite_NAND.tcl
|
uSD and NAND |
As an example, to reproduce the build for the Bora platform, here below are the steps:
- clone the repository:
git clone git@git.dave.eu:desk-xz-l/vivado.git -b desk-xz7-l-1.1.0
cd vivado
or clone the Vivado repository when you clone Petalinux repository
git clone --recursive git@git.dave.eu:desk-xz-l/petalinux.git -b desk-xz7-l-1.1.0
cd petalinux/vivado
- (only once as first tools setup) copy Bora hardware definition into Vivado installation path:
cp -r boards/ <vivado directory installation>/Xilinx/2021.2/Vivado/2021.2/data/
- lunch Vivado Design Suite with the following commands and parameters:
source <vivado directory installation>/Xilinx/2021.2/Vivado/2021.2/settings64.sh
vivado -mode tcl -source scripts/recreate_prj_bora_BASE.tcl -notrace -tclargs "gen_bitstream"
- at the end of the bitstream build process, the script automatically exports the Xilinx Support Archive (XSA) hardware design
- the Vivado project
vivado/bora.xpr
is ready for customization through the Vivado GUI - the bitstream files are
vivado/bora.runs/impl_1/bora_wrapper.bit
vivado/bora.runs/impl_1/bora_wrapper.bin
- the hardware design file
vivado/bora.xsa
is ready for the import into Petalinux
- the Vivado project
CAN0 and UART0 routing example project[edit | edit source]
The following pictures show a simple PL design used to route PS' CAN0 and UART0 signals through EMIO.
Petalinux installation path, in this documentation, is the |
Creating and building the Petalinux project[edit | edit source]
Documentation reference[edit | edit source]
- PetaLinux Tools Documentation Reference guide UG1144
- PetaLinux Tools DocumentationCommand Line Reference Guide UG1157
Petalinux environment setup[edit | edit source]
To reproduce the Petalinux build:
- clone the repository
git clone --recursive git@git.dave.eu:desk-xz-l/petalinux.git -b desk-xz7-l-1.1.0
cd petalinux
- setup the Petalinux environment
source <petalinux installation path>/Xilinx/petalinux/2021.2/settings.sh
- initialize the configuration file
You can use the proper configuration file from the following table:
Config file | Boot |
---|---|
config_bora
|
uSD and QSPI-NOR |
config_bora_ETH1
|
uSD and QSPI-NOR with ETH1 support |
config_borax
|
uSD and QSPI-NOR |
config_borax_ETH1
|
uSD and QSPI-NOR with ETH1 support |
config_boralite
|
uSD and QSPI-NOR |
config_boralite_NAND
|
NAND |
config_boralite_nand_usd
|
uSD with NAND support |
In order to select a configuration file use the following command:
cp project-spec/configs/<configuration file> project-spec/configs/config
Update the hardware description[edit | edit source]
The hardware description comes from the Vivado project. The Vivado project is already cloned into the Petalinux project.
To build the Hardware description file, please look at this page: Creating and building the Vivado project
You can use the following command to update the hardware description:
petalinux-config --get-hw-description vivado/vivado/<path to .xsa>
When applying the hardware description, the standard menuconfig interface will pop up: just save the current configuration to proceed. If the menuconfig interface will not bring up, send the following command:
petalinux-config --get-hw-description vivado/vivado/<path to .xsa> --silentconfig
Run the Petalinux build[edit | edit source]
To build petalinux-image-minimal
use the following command:
petalinux-build
For building the dave-image-devel
target, use the following command:
petalinux-build -c dave-image-devel
For building only the Linux kernel, use the following command
petalinux-build -c kernel
For building only U-Boot use the following command:
petalinux-build -c u-boot
For generating the BOOT.BIN
artifact, run the following command:
petalinux-package --boot --u-boot --force
Note: BOOT.BIN
includes the files below. In this case, the system.bit
bitstream was generated with Vivado and imported in Petalinux with xsa
file.
fsbl.elf
system.bit
u-boot.elf
In case of boot from NAND for the BORA Lite SOM, be careful on using the following command:
petalinux-package --boot --u-boot --kernel --offset 0x1080000 --force
Note: BOOT.BIN
includes the files below. In this case, the bitstream system.bit
was generated with Vivado and imported in Petalinux with xsa
file.
fsbl.elf
system.bit
u-boot.elf
image.ub
The offset 0x1080000
for kernel is a default setting for NAND device installed on the SoM.
SD card image[edit | edit source]
To generate the SD card wic
image, execute the following command:
petalinux-package --wic --bootfiles "BOOT.BIN boot.scr image.ub"
If you want to use dave-image-devel
root file system, run the following command:
petalinux-package --wic --bootfiles "BOOT.BIN boot.scr image.ub" --rootfs-file build/tmp/deploy/images/zynq-generic/dave-image-devel-zynq-generic.tar.gz
How to create a bootable microSD card[edit | edit source]
The process is relatively straightforward: it consists of writing the WIC file of interest generated by Petalinux onto the SD card. There are multiple ways to do that.
The most common is to use the well-known BalenaEtcher tool (download BalenaEtcher). The following instruction explains how to use it on a Windows host. The procedure is similar when working with a Linux host.
- Download the desired binary image to flash (
*.wic
or*.wic.bz2
). In case you have a*.wic.bz2
, unzip the file in order to have a*.wic
file- Among the binaries made available in the mirror there are several
*.wic.bz2
files for the available releases. In particular, there is thedesk-xz7-l-1.0.1_bora_dave-image-devel.wic.bz2
file. This image is the one used to program the microSD card delivered along with the evaluation kit.
- Among the binaries made available in the mirror there are several
- Connect the microSD card to the PC Host
- Open BalenaEtcher tool
- Once the tool is open:
- Select the binary to flash by clicking on "Flash from file"
- Select the microSD to flash by clicking on "Select target"
- Flash the uSD by clicking o "Flash".
Hello World example[edit | edit source]
Here below is an example of C code displaying the classic Hello World! message on the target serial console.
This example shows how to use the arm cross-compiler using the environment configured for this purpose
Setting the cross-compiler[edit | edit source]
- start the Linux development VM and login into the system
- install the toolchain, for example for BORA SOM
dvdk@vagrant:~$ wget https://mirror.dave.eu/desk-xz-l/desk-xz7-l-1.0.1/desk-xz7-l-1.0.1_bora_sdk.sh --2024-01-26 11:57:04-- https://mirror.dave.eu/desk-xz-l/desk-xz7-l-1.0.1/desk-xz7-l-1.0.1_bora_sdk.sh Resolving mirror.dave.eu (mirror.dave.eu)... 84.46.251.143 Connecting to mirror.dave.eu (mirror.dave.eu)|84.46.251.143|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 998591008 (952M) [text/x-sh] Saving to: ‘desk-xz7-l-1.0.1_bora_sdk.sh’ desk-xz7-l-1.0.1_bora_sdk.sh 100%[====================================================================================================>] 952.33M 10.8MB/s in 1m 40s 2024-01-26 11:58:43 (9.57 MB/s) - ‘desk-xz7-l-1.0.1_bora_sdk.sh’ saved [998591008/998591008] dvdk@vagrant:~$ chmod 755 desk-xz7-l-1.0.1_bora_sdk.sh dvdk@vagrant:~$ ./desk-xz7-l-1.0.1_bora_sdk.sh PetaLinux SDK installer version 2021.2 ====================================== Enter target directory for SDK (default: /opt/petalinux/2021.2): You are about to install the SDK to "/opt/petalinux/2021.2". Proceed [Y/n]? y Extracting SDK.......................................................................................................................................................................................................................done Setting it up...done SDK has been successfully set up and is ready to be used. Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g. $ . /opt/petalinux/2021.2/environment-setup-cortexa9t2hf-neon-xilinx-linux-gnueabi
- open a terminal window and cd into your source code directory
dvdk@vagrant:~$ mkdir -p ~/myproject dvdk@vagrant:~$ cd ~/myproject/ dvdk@vagrant:~/myproject$ vi hello.c dvdk@vagrant:~/myproject$ cat hello.c #include <stdio.h> int main(){ printf("Hello, World!\n"); return 0; }
- configure the build environment
dvdk@vagrant:~/myproject$ source /opt/petalinux/2021.2/environment-setup-cortexa9t2hf-neon-xilinx-linux-gnueabi
- as you can see here below, the
$CC
environment variable has been properly configured for using the SDKsysroot
parameter:
dvdk@vagrant:~/myproject$ echo $CC arm-xilinx-linux-gnueabi-gcc -mthumb -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a9 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/petalinux/2021.2/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi
- invoke the cross-compiler for compiling your source code example: the object file obtained, is a proper ELF 32-bit for the target microprocessor
dvdk@vagrant:~/myproject$ $CC -O hello.c -o hello dvdk@vagrant:~/myproject$ file hello hello: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=cd0630d98370eb6b80423fb1b4b1e3411f2f4576, for GNU/Linux 3.2.0, with debug_info, not stripped
Running the example on the target[edit | edit source]
Now it is enough to copy the object file on target and execute it:
... ... root@bora:~# ./hello Hello, World! root@bora:~#
Deployment[edit | edit source]
Standalone boot[edit | edit source]
This document was written and tested with the software/hardware combination described in the history table above. However, it contains general concepts that can be adapted to any DAVE Embedded Systems' Linux platform.
The following programming examples are intended for laboratory usage or for preliminary deployment strategy. |
We'll explain how to program and configure a SOM
to boot in standalone mode, without the need for a system microSD card, with the following option:
- booting with Quad-SPI NOR
- in this configuration the primary boot images will be fetched from Quad-SPI NOR flash storage, while the root file system will be fetched from microSD
- booting with NAND
- in this configuration the primary boot images and rootfs will be fetched from NAND flash storage
Program the Quad-SPI NOR flash[edit | edit source]
This chapter is compatible with BORA, BORA Xpress and BORA Lite platforms, but below there is log for BORA Xpress SOM.
First of all, create a bootable microSD card as described here. Alternatively you can download binaries from mirror and install it on microSD or into tftpboot
directory in your host device.
Then, boot the board with the microSD card and stop the automatic boot process of U-Boot in order to access the console.
U-Boot 2021.01-desk-xz7-l-1.0.1 (Jan 12 2024 - 10:44:15 +0000) CPU: Zynq 7z030 Silicon: v3.1 Model: Bora DRAM: ECC disabled 1 GiB Flash: 0 Bytes NAND: 0 MiB MMC: mmc@e0100000: 0 Loading Environment from FAT... *** Warning - bad CRC, using default environment In: serial@e0001000 Out: serial@e0001000 Err: serial@e0001000 SF: Detected s25fl128s with page size 256 Bytes, erase size 64 KiB, total 16 MiB SF: Detected s25fl128s with page size 256 Bytes, erase size 64 KiB, total 16 MiB SOM ConfigID#: 00000004 SOM UniqueID#: 2a0e92c4:03193a4b CB ConfigID#: ffffffff CB UniqueID#: ffffffff:ffffffff SF: Detected s25fl128s with page size 256 Bytes, erase size 64 KiB, total 16 MiB Warning: MAC addr not found in SPI NOR at block 8 Net: ZYNQ GEM: e000b000, mdio bus e000b000, phyaddr 7, interface rgmii-id Warning: ethernet@e000b000 (eth0) using random MAC address - 72:2c:e1:44:08:28 eth0: ethernet@e000b000 Hit ENTER within 2 seconds to stop autoboot Zynq>
Programming Quad-SPI NOR flash from microSD[edit | edit source]
- Initialize and format Quad-SPI NOR flash memory
Zynq> sf probe SF: Detected s25fl128s with page size 256 Bytes, erase size 64 KiB, total 16 MiB Zynq> sf erase 0 0x1000000 SF: 16777216 bytes @ 0x0 Erased: OK
- Install
BOOT.BIN
on Quad-SPI NOR flash memory
Zynq> fatload mmc 0:1 $kernel_addr_r BOOT.BIN 7033004 bytes read in 406 ms (16.5 MiB/s) Zynq> sf write $kernel_addr_r 0x0 $filesize device 0 offset 0x0, size 0x6b50ac SF: 7033004 bytes @ 0x0 Written: OK
- Install
image.ub
on Quad-SPI NOR flash memory
Zynq> mw $kernel_addr_r 0x0 $filesize Zynq> fatload mmc 0:1 $kernel_addr_r image.ub 4868556 bytes read in 287 ms (16.2 MiB/s) Zynq> sf write $kernel_addr_r 0x700000 $filesize device 0 offset 0x700000, size 0x4a49cc SF: 4868556 bytes @ 0x700000 Written: OK
- Install
boot.scr
on Quad-SPI NOR flash memory
Zynq> mw $kernel_addr_r 0x0 $filesize Zynq> fatload mmc 0:1 $kernel_addr_r boot.scr 2709 bytes read in 14 ms (188.5 KiB/s) Zynq> sf write $kernel_addr_r 0xFC0000 $filesize device 0 offset 0xfc0000, size 0xa95 SF: 2709 bytes @ 0xfc0000 Written: OK
Programming Quad-SPI NOR flash from ethernet[edit | edit source]
- Initialize and format Quad-SPI NOR flash memory
Zynq> sf probe SF: Detected s25fl128s with page size 256 Bytes, erase size 64 KiB, total 16 MiB Zynq> sf erase 0 0x1000000 SF: 16777216 bytes @ 0x0 Erased: OK
- Properly define the ethernet configuration parameter:
Zynq> setenv ipaddr 192.168.0.89 Zynq> setenv serverip 192.168.0.99
- download via TFTP the
BOOT.BIN
binary image and writeBOOT.BIN
on Quad-SPI NOR flash memory
Zynq> tftpboot $kernel_addr_r desk-xz7-l/desk-xz7-l-1.0.1_borax_BOOT.BIN Using ethernet@e000b000 device TFTP from server 192.168.0.99; our IP address is 192.168.0.89 Filename 'desk-xz7-l/desk-xz7-l-1.0.1_borax_BOOT.BIN'. Load address: 0x2000000 Loading: #T ################################################################ ################################################################# ... ################################################################# ######### 444.3 KiB/s done Bytes transferred = 7033004 (6b50ac hex) Zynq> sf write $kernel_addr_r 0x0 $filesize device 0 offset 0x0, size 0x6b50ac SF: 7033004 bytes @ 0x0 Written: OK
- download via TFTP the
image.ub
binary image and writeimage.ub
on Quad-SPI NOR flash memory
Zynq> mw $kernel_addr_r 0x0 $filesize Zynq> tftpboot $kernel_addr_r desk-xz7-l/desk-xz7-l-1.0.1_borax_image.ub Using ethernet@e000b000 device TFTP from server 192.168.0.99; our IP address is 192.168.0.89 Filename 'desk-xz7-l/desk-xz7-l-1.0.1_borax_image.ub'. Load address: 0x2000000 Loading: #T ################################################################ ################################################################# ... ################################################################# ######################################### 394.5 KiB/s done Bytes transferred = 4868556 (4a49cc hex) Zynq> sf write $kernel_addr_r 0x700000 $filesize device 0 offset 0x700000, size 0x4a49cc SF: 4868556 bytes @ 0x700000 Written: OK
- download via TFTP the
boot.scr
binary image and writeboot.scr
on Quad-SPI NOR flash memory
Zynq> mw $kernel_addr_r 0x0 $filesize Zynq> tftpboot $kernel_addr_r desk-xz7-l/desk-xz7-l-1.0.1_borax_boot.scr Using ethernet@e000b000 device TFTP from server 192.168.0.99; our IP address is 192.168.0.89 Filename 'desk-xz7-l/desk-xz7-l-1.0.1_borax_boot.scr'. Load address: 0x2000000 Loading: #T 0 Bytes/s done Bytes transferred = 2709 (a95 hex) Zynq> sf write $kernel_addr_r 0xFC0000 $filesize device 0 offset 0xfc0000, size 0xa95 SF: 2709 bytes @ 0xfc0000 Written: OK
Once change boot mode and restarted, the complete boot log can be like this one:
U-Boot 2021.01-desk-xz7-l-1.0.1 (Jan 12 2024 - 10:44:15 +0000) CPU: Zynq 7z030 Silicon: v3.1 Model: Bora DRAM: ECC disabled 1 GiB Flash: 0 Bytes NAND: 0 MiB MMC: mmc@e0100000: 0 Loading Environment from SPIFlash... SF: Detected s25fl128s 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 SF: Detected s25fl128s with page size 256 Bytes, erase size 64 KiB, total 16 MiB SF: Detected s25fl128s with page size 256 Bytes, erase size 64 KiB, total 16 MiB SOM ConfigID#: 00000004 SOM UniqueID#: 2a0e92c4:03193a4b CB ConfigID#: ffffffff CB UniqueID#: ffffffff:ffffffff SF: Detected s25fl128s with page size 256 Bytes, erase size 64 KiB, total 16 MiB Warning: MAC addr not found in SPI NOR at block 8 Net: ZYNQ GEM: e000b000, mdio bus e000b000, phyaddr 7, interface rgmii-id Warning: ethernet@e000b000 (eth0) using random MAC address - 7a:68:29:db:0b:f6 eth0: ethernet@e000b000 Hit ENTER within 2 seconds to stop autoboot SF: Detected s25fl128s with page size 256 Bytes, erase size 64 KiB, total 16 MiB device 0 offset 0xfc0000, size 0x40000 SF: 262144 bytes @ 0xfc0000 Read: OK QSPI: Trying to boot script at 3000000 ## Executing script at 03000000 Trying to load boot images from qspi SF: Detected s25fl128s with page size 256 Bytes, erase size 64 KiB, total 16 MiB device 0 offset 0x700000, size 0x600000 SF: 6291456 bytes @ 0x700000 Read: OK ## Loading kernel from FIT Image at 10000000 ... Using 'conf-system-top.dtb' configuration Verifying Hash Integrity ... OK Trying 'kernel-1' kernel subimage Description: Linux kernel Type: Kernel Image Compression: uncompressed Data Start: 0x100000f8 Data Size: 4845944 Bytes = 4.6 MiB Architecture: ARM OS: Linux Load Address: 0x00200000 Entry Point: 0x00200000 Hash algo: sha256 Hash value: f5d0c9b9a689e4b0657468fb280f0c8fb60064196b7938a77a43b36a2743acca Verifying Hash Integrity ... sha256+ OK ## Loading fdt from FIT Image at 10000000 ... Using 'conf-system-top.dtb' configuration Verifying Hash Integrity ... OK Trying 'fdt-system-top.dtb' fdt subimage Description: Flattened Device Tree blob Type: Flat Device Tree Compression: uncompressed Data Start: 0x1049f37c Data Size: 20716 Bytes = 20.2 KiB Architecture: ARM Hash algo: sha256 Hash value: f93874aa1f1a0c6d52c423e12b25b4a2ae14a09b40a8068a49b4c8914be75e4c Verifying Hash Integrity ... sha256+ OK Booting using the fdt blob at 0x1049f37c Loading Kernel Image Loading Device Tree to 2fff7000, end 2ffff0eb ... OK Starting kernel ... [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 5.10.0-xilinx-v2021.2 (oe-user@oe-host) (arm-xilinx-linux-gnueabi-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35.1) #1 SMP PREEMPT Tue Oct 12 09:30:57 UTC 2021 [ 0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] OF: fdt: Machine model: Bora [ 0.000000] earlycon: cdns0 at MMIO 0xe0001000 (options '115200n8') [ 0.000000] printk: bootconsole [cdns0] enabled [ 0.000000] Memory policy: Data cache writealloc [ 0.000000] cma: Reserved 16 MiB at 0x3f000000 [ 0.000000] Zone ranges: [ 0.000000] Normal [mem 0x0000000000000000-0x000000002fffffff] [ 0.000000] HighMem [mem 0x0000000030000000-0x000000003fffffff] [ 0.000000] Movable zone start for each node [ 0.000000] Early memory node ranges [ 0.000000] node 0: [mem 0x0000000000000000-0x000000003fffffff] [ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff] [ 0.000000] percpu: Embedded 16 pages/cpu s32780 r8192 d24564 u65536 [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 260416 [ 0.000000] Kernel command line: console=ttyPS0,115200 earlycon root=/dev/mmcblk0p2 rw rootwait [ 0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes, linear) [ 0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes, linear) [ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off [ 0.000000] Memory: 1009768K/1048576K available (7168K kernel code, 279K rwdata, 1952K rodata, 1024K init, 162K bss, 22424K reserved, 16384K cma-reserved, 245760K highmem) [ 0.000000] rcu: Preemptible hierarchical RCU implementation. [ 0.000000] rcu: RCU event tracing is enabled. [ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2. [ 0.000000] Trampoline variant of Tasks RCU enabled. [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies. [ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2 [ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16 [ 0.000000] efuse mapped to (ptrval) [ 0.000000] slcr mapped to (ptrval) [ 0.000000] GIC physical location is 0xf8f01000 [ 0.000000] L2C: platform modifies aux control register: 0x72360000 -> 0x72760000 [ 0.000000] L2C: DT/platform modifies aux control register: 0x72360000 -> 0x72760000 [ 0.000000] L2C-310 erratum 769419 enabled [ 0.000000] L2C-310 enabling early BRESP for Cortex-A9 [ 0.000000] L2C-310 full line of zeros enabled for Cortex-A9 [ 0.000000] L2C-310 ID prefetch enabled, offset 1 lines [ 0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled [ 0.000000] L2C-310 cache controller enabled, 8 ways, 512 kB [ 0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x76760001 [ 0.000000] random: get_random_bytes called from start_kernel+0x2c0/0x4a0 with crng_init=0 [ 0.000000] zynq_clock_init: clkc starts at (ptrval) [ 0.000000] Zynq clock init [ 0.000011] sched_clock: 64 bits at 333MHz, resolution 3ns, wraps every 4398046511103ns [ 0.005723] clocksource: arm_global_timer: mask: 0xffffffffffffffff max_cycles: 0x4ce07af025, max_idle_ns: 440795209040 ns [ 0.016655] Switching to timer-based delay loop, resolution 3ns [ 0.023169] Console: colour dummy device 80x30 [ 0.026895] Calibrating delay loop (skipped), value calculated using timer frequency.. 666.66 BogoMIPS (lpj=3333333) [ 0.037305] pid_max: default: 32768 minimum: 301 [ 0.042082] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes, linear) [ 0.049081] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes, linear) [ 0.057754] CPU: Testing write buffer coherency: ok [ 0.061529] CPU0: Spectre v2: using BPIALL workaround [ 0.066749] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 [ 0.072812] Setting up static identity map for 0x100000 - 0x100060 [ 0.078378] rcu: Hierarchical SRCU implementation. [ 0.083352] smp: Bringing up secondary CPUs ... [ 0.088388] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001 [ 0.088399] CPU1: Spectre v2: using BPIALL workaround [ 0.098134] smp: Brought up 1 node, 2 CPUs [ 0.102036] SMP: Total of 2 processors activated (1333.33 BogoMIPS). [ 0.108358] CPU: All CPU(s) started in SVC mode. [ 0.113587] devtmpfs: initialized [ 0.121144] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4 [ 0.124128] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns [ 0.133462] futex hash table entries: 512 (order: 3, 32768 bytes, linear) [ 0.141395] pinctrl core: initialized pinctrl subsystem [ 0.146259] NET: Registered protocol family 16 [ 0.151964] DMA: preallocated 256 KiB pool for atomic coherent allocations [ 0.157733] thermal_sys: Registered thermal governor 'step_wise' [ 0.158046] cpuidle: using governor ladder [ 0.166503] cpuidle: using governor menu [ 0.182919] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers. [ 0.185265] hw-breakpoint: maximum watchpoint size is 4 bytes. [ 0.191178] zynq-ocm f800c000.ocmc: ZYNQ OCM pool: 256 KiB @ 0x(ptrval) [ 0.198318] e0000000.serial: ttyPS1 at MMIO 0xe0000000 (irq = 34, base_baud = 3125000) is a xuartps [ 0.207234] e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 35, base_baud = 3125000) is a xuartps [ 0.221091] printk: console [ttyPS0] enabled [ 0.221091] printk: console [ttyPS0] enabled [ 0.225396] printk: bootconsole [cdns0] disabled [ 0.225396] printk: bootconsole [cdns0] disabled [ 0.249776] vgaarb: loaded [ 0.252888] SCSI subsystem initialized [ 0.256896] usbcore: registered new interface driver usbfs [ 0.262468] usbcore: registered new interface driver hub [ 0.267875] usbcore: registered new device driver usb [ 0.273183] mc: Linux media interface: v0.10 [ 0.277485] videodev: Linux video capture interface: v2.00 [ 0.283046] pps_core: LinuxPPS API ver. 1 registered [ 0.288002] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 0.297158] PTP clock support registered [ 0.301145] EDAC MC: Ver: 3.0.0 [ 0.304805] FPGA manager framework [ 0.308536] Advanced Linux Sound Architecture Driver Initialized. [ 0.315660] clocksource: Switched to clocksource arm_global_timer [ 0.332917] NET: Registered protocol family 2 [ 0.337977] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 6144 bytes, linear) [ 0.346425] TCP established hash table entries: 8192 (order: 3, 32768 bytes, linear) [ 0.354267] TCP bind hash table entries: 8192 (order: 4, 65536 bytes, linear) [ 0.361542] TCP: Hash tables configured (established 8192 bind 8192) [ 0.368054] UDP hash table entries: 512 (order: 2, 16384 bytes, linear) [ 0.374750] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear) [ 0.382042] NET: Registered protocol family 1 [ 0.387083] RPC: Registered named UNIX socket transport module. [ 0.393034] RPC: Registered udp transport module. [ 0.397734] RPC: Registered tcp transport module. [ 0.402441] RPC: Registered tcp NFSv4.1 backchannel transport module. [ 0.408896] PCI: CLS 0 bytes, default 64 [ 0.413390] hw perfevents: no interrupt-affinity property for /pmu@f8891000, guessing. [ 0.421576] hw perfevents: enabled with armv7_cortex_a9 PMU driver, 7 counters available [ 0.431150] workingset: timestamp_bits=14 max_order=18 bucket_order=4 [ 0.438734] jffs2: version 2.2. (NAND) (SUMMARY) © 2001-2006 Red Hat, Inc. [ 0.446129] bounce: pool size: 64 pages [ 0.449974] io scheduler mq-deadline registered [ 0.454520] io scheduler kyber registered [ 0.458913] zynq-pinctrl 700.pinctrl: zynq pinctrl initialized [ 0.467704] dma-pl330 f8003000.dmac: Loaded driver for PL330 DMAC-241330 [ 0.474442] dma-pl330 f8003000.dmac: DBUFF-128x8bytes Num_Chans-8 Num_Peri-4 Num_Events-16 [ 0.494238] brd: module loaded [ 0.504037] loop: module loaded [ 0.511083] random: fast init done [ 0.614245] random: crng init done [ 0.623641] spi-nor spi0.0: trying to lock already unlocked area [ 0.629650] spi-nor spi0.0: s25fl128s1 (16384 Kbytes) [ 0.639922] libphy: Fixed MDIO Bus: probed [ 0.645716] CAN device driver interface [ 0.652273] libphy: MACB_mii_bus: probed [ 0.688524] macb e000b000.ethernet eth0: Cadence GEM rev 0x00020118 at 0xe000b000 irq 37 (7a:68:29:db:0b:f6) [ 0.698709] e1000e: Intel(R) PRO/1000 Network Driver [ 0.703668] e1000e: Copyright(c) 1999 - 2015 Intel Corporation. [ 0.710509] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 0.717037] ehci-pci: EHCI PCI platform driver [ 0.721607] usbcore: registered new interface driver usb-storage [ 0.728609] ULPI transceiver vendor/product ID 0x0424/0x0006 [ 0.734267] Found SMSC USB331x ULPI transceiver. [ 0.738913] ULPI integrity check: passed. [ 0.745040] i2c /dev entries driver [ 0.752088] rtc-ds3232 0-0068: registered as rtc0 [ 0.757162] rtc-ds3232 0-0068: setting system clock to 2018-03-09T17:29:17 UTC (1520616557) [ 0.765791] cdns-i2c e0004000.i2c: 400 kHz mmio e0004000 irq 31 [ 0.774272] cdns-wdt f8005000.watchdog: Xilinx Watchdog Timer with timeout 10s [ 0.781826] EDAC MC: ECC not enabled [ 0.785972] cpufreq: cpufreq_online: CPU0: Running at unlisted initial frequency: 666666 KHz, changing to: 666667 KHz [ 0.796932] Xilinx Zynq CpuIdle Driver started [ 0.800410] sdhci: Secure Digital Host Controller Interface driver [ 0.803503] sdhci: Copyright(c) Pierre Ossman [ 0.805718] sdhci-pltfm: SDHCI platform and OF driver helper [ 0.809266] ledtrig-cpu: registered to indicate activity on CPUs [ 0.812545] clocksource: ttc_clocksource: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 1075096770 ns [ 0.817251] timer #0 at dfb516c6, irq=50 [ 0.819556] usbcore: registered new interface driver usbhid [ 0.822381] usbhid: USB HID core driver [ 0.827302] fpga_manager fpga0: Xilinx Zynq FPGA Manager registered [ 0.831575] mmc0: SDHCI controller on e0100000.mmc [e0100000.mmc] using ADMA [ 0.831977] NET: Registered protocol family 10 [ 0.838558] Segment Routing with IPv6 [ 0.840631] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver [ 0.847540] NET: Registered protocol family 17 [ 0.852063] can: controller area network core [ 0.856576] NET: Registered protocol family 29 [ 0.861071] can: raw protocol [ 0.864050] can: broadcast manager protocol [ 0.868298] can: netlink gateway - max_hops=1 [ 0.873045] Registering SWP/SWPB emulation handler [ 0.880140] of-fpga-region fpga-full: FPGA Region probed [ 0.886112] of_cfs_init [ 0.888667] of_cfs_init: OK [ 0.891875] ALSA device list: [ 0.894839] No soundcards found. [ 0.898729] Waiting for root device /dev/mmcblk0p2... [ 1.052324] mmc0: new high speed SDHC card at address aaaa [ 1.055781] mmcblk0: mmc0:aaaa SA16G 14.8 GiB [ 1.060584] mmcblk0: p1 p2 [ 1.086701] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null) [ 1.090810] VFS: Mounted root (ext4 filesystem) on device 179:2. [ 1.094724] devtmpfs: mounted [ 1.099892] Freeing unused kernel memory: 1024K [ 1.136017] Run /sbin/init as init process INIT: version 2.97 booting [ 1.516983] FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck. Starting udev [ 1.712872] udevd[82]: starting version 3.2.9 [ 1.763498] udevd[83]: starting eudev-3.2.9 [ 2.244862] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null) INIT: Entering runlevel: 5 Configuring network interfaces... done. Starting system message bus: dbus. Starting haveged: haveged: command socket is listening at fd 3 haveged: haveged starting up Starting Dropbear SSH server: dropbear. Starting rpcbind daemon...done. starting statd: done Starting atd: OK Starting internet superserver: inetd. NFS daemon support not enabled in kernel Starting system log daemon...0 Mar 9 17:29:22 borax kernel: [ 0.000000] L2C: platform modifies aux control register: 0x72360000 -> 0x72760000 Mar 9 17:29:22 borax kernel: [ 0.000000] L2C: DT/platform modifies aux control register: 0x72360000 -> 0x72760000 Mar 9 17:29:22 borax kernel: [ 0.413390] hw perfevents: no interrupt-affinity property for /pmu@f8891000, guessing. Mar 9 17:29:22 borax kernel: [ 0.623641] spi-nor spi0.0: trying to lock already unlocked area Mar 9 17:29:22 borax kernel: [ 1.516983] FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck. Starting internet superserver: xinetd. Starting crond: OK Starting tcf-agent: OK PetaLinux 2021.2 borax ttyPS0 root@borax:~# uname -a Linux borax 5.10.0-xilinx-v2021.2 #1 SMP PREEMPT Tue Oct 12 09:30:57 UTC 2021 armv7l armv7l armv7l GNU/Linux root@borax:~# cat /etc/build ----------------------- Build Configuration: | ----------------------- DISTRO = petalinux DISTRO_VERSION = 2021.2 MACHINE = zynq-generic IMAGE_BASENAME = dave-image-devel ----------------------- Layer Revisions: | ----------------------- meta = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-poky = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-perl = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-python = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-filesystems = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-gnome = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-multimedia = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-networking = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-webserver = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-xfce = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-initramfs = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-oe = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-clang = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-chromium = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-qt5 = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-microblaze = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-xilinx-bsp = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-xilinx-pynq = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-xilinx-contrib = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-xilinx-standalone = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-xilinx-tools = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-petalinux = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-virtualization = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-openamp = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-jupyter = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-vitis-ai = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-python2 = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-som = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-security = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-tpm = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-user = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified meta-dave = HEAD:e944801f104f86191cd086d0cea8f3df88dda061 workspace = HEAD:829c44d28c8c46b51744c14a92107ec3c5790934 -- modified root@borax:~# cat /etc/os-release ID=petalinux NAME="PetaLinux" VERSION="2021.2 (gatesgarth)" VERSION_ID=2021.2 PRETTY_NAME="PetaLinux 2021.2 (gatesgarth)" BUILD_VERSION="desk-xz7-l-1.0.1" root@borax:~# shutdown -h now Broadcast message from root@borax (ttyPS0) (Fri Mar 9 17:29:35 2018): The system is going down for system halt NOW! INIT: Sending processes configured via /etc/inittab the TERM signal Stopping haveged: Stopping Dropbear SSH server: stopped /usr/sbin/dropbear (pid 217) dropbear. Stopping atd: OK Stopping system message bus: dbus. Stopping internet superserver: inetd. stopping mountd: done stopping nfsd: done Stopping system log daemon...0 Stopping tcf-agent: OK Stopping internet superserver: xinetd. stopping statd: done Stopping crond: OK Stopping rpcbind daemon... done. Deconfiguring network interfaces... done. Sending all processes the TERM signal... logout Sending all processes the KILL signal... Unmounting remote filesystems... Deactivating swap... Unmounting local filesystems... [ 24.097545] reboot: System halted
Program the NAND flash[edit | edit source]
This chapter is compatible with BORA Lite SOM.
First of all, create a bootable microSD card as described here with config_boralite_nand_usd
configuration file, and install wic
binary on microSD. Then create artifact to install on NAND flash with config_boralite_nand
configuration file, as described here, and save the BOOT.BIN
and dave-image-devel-zynq-generic.tar.gz
artifact into the first partition of microSD.
In this case BOOT.BIN
binary that came from to config_boralite_nand_usd
and config_boralite_nand
are different, so save it with different name. Alternatively you can download binaries from mirror and install on microSD.
Then, install the following files into the microSD first partition:
BOOT.BIN
. This binary come from toconfig_boralite_nand_usd
configuration file, and need to install on microSDboot.scr
. This binary come from toconfig_boralite_nand_usd
configuration file, and need to install on microSDimage.ub
. This binary come from toconfig_boralite_nand_usd
configuration file, and need to install on microSDdesk-xz7-l-1.0.1_boralite_nand_BOOT.BIN.EXTENDED
. This binary come from toconfig_boralite_nand
configuration file, and has to be installed on NAND flashdesk-xz7-l-1.1.0_boralite_NAND_dave-image-devel-zynq-generic.ubi
. This binary come from toconfig_boralite_nand
configuration file, and has to be installed on NAND flash
Programming NAND flash from microSD[edit | edit source]
- delete all partition on NAND flash memory
root@boralite:~# for i in $(seq 0 2); do sudo flash_erase /dev/mtd$i 0 0; done Erasing 128 Kibyte @ 15e0000 -- 100 % complete Erasing 128 Kibyte @ 20000 -- 100 % complete Erasing 128 Kibyte @ 3e920000 -- 99 % complete flash_erase: Skipping bad block at 3e940000 flash_erase: Skipping bad block at 3e960000 flash_erase: Skipping bad block at 3e980000 flash_erase: Skipping bad block at 3e9a0000 Erasing 128 Kibyte @ 3e9a0000 -- 100 % complete
- install
BOOT.BIN
on NAND flash memory
root@boralite:~# nandwrite -p /dev/mtd0 /boot/desk-xz7-l-1.1.0_boralite_NAND_BOOT.BIN.EXTENDED Writing data to block 0 at offset 0x0 Writing data to block 1 at offset 0x20000 Writing data to block 2 at offset 0x40000 ... Writing data to block 174 at offset 0x15c0000 Writing data to block 175 at offset 0x15e0000
- install
rootfs on NAND flash memory
root@boralite:~# ubiformat /dev/mtd2 -f /boot/desk-xz7-l-1.1.0_boralite_NAND_dave-image-devel-zynq-generic.ubi ubiformat: mtd2 (nand), size 1050411008 bytes (1001.7 MiB), 8014 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes libscan: scanning eraseblock 8013 -- 100 % complete ubiformat: 8010 eraseblocks are supposedly empty ubiformat: 4 bad eraseblocks found, numbers: 8010, 8011, 8012, 8013 ubiformat: flashing eraseblock 1894 -- 100 % complete ubiformat: formatting eraseblock 8013 -- 100 % complete
Once change boot mode and restarted, the complete boot log can be like this one:
U-Boot 2021.01-desk-xz7-l-1.0.1 (Jan 12 2024 - 10:44:15 +0000) CPU: Zynq 7z020 Silicon: v3.1 Model: Bora DRAM: ECC disabled 1 GiB Flash: 0 Bytes NAND: 1024 MiB MMC: mmc@e0100000: 0 Loading Environment from NAND... *** Warning - bad CRC, using default environment In: serial@e0001000 Out: serial@e0001000 Err: serial@e0001000 SOM ConfigID#: 77777777 SOM UniqueID#: 55555555:66666666 CB ConfigID#: ffffffff CB UniqueID#: ffffffff:ffffffff Net: ZYNQ GEM: e000b000, mdio bus e000b000, phyaddr 7, interface rgmii-id Warning: ethernet@e000b000 (eth0) using random MAC address - 3e:1a:de:54:41:09 eth0: ethernet@e000b000 Hit ENTER within 2 seconds to stop autoboot Device 0: nand0, sector size 128 KiB Page size 2048 b OOB size 64 b Erase size 131072 b subpagesize 512 b options 0x40004000 bbt options 0x00020000 NAND read: device 0 offset 0xfc0000, size 0x40000 262144 bytes read: OK NAND: Trying to boot script at 3000000 ## Executing script at 03000000 Trying to load boot images from nand Device 0: nand0, sector size 128 KiB Page size 2048 b OOB size 64 b Erase size 131072 b subpagesize 512 b options 0x40004000 bbt options 0x00020000 NAND read: device 0 offset 0x1080000, size 0x6400000 104857600 bytes read: OK ## Loading kernel from FIT Image at 10000000 ... Using 'conf-system-top.dtb' configuration Verifying Hash Integrity ... OK Trying 'kernel-1' kernel subimage Description: Linux kernel Type: Kernel Image Compression: uncompressed Data Start: 0x100000f8 Data Size: 5647032 Bytes = 5.4 MiB Architecture: ARM OS: Linux Load Address: 0x00200000 Entry Point: 0x00200000 Hash algo: sha256 Hash value: 8190a3d693bca4da06460265eb066437a89fc51cde33121353a61c7e5b3c00b3 Verifying Hash Integrity ... sha256+ OK ## Loading fdt from FIT Image at 10000000 ... Using 'conf-system-top.dtb' configuration Verifying Hash Integrity ... OK Trying 'fdt-system-top.dtb' fdt subimage Description: Flattened Device Tree blob Type: Flat Device Tree Compression: uncompressed Data Start: 0x10562cbc Data Size: 20625 Bytes = 20.1 KiB Architecture: ARM Hash algo: sha256 Hash value: dd4f01191b5971a192cb469fc4c43c7137a26ccc87277f9156f08f0b7b77116c Verifying Hash Integrity ... sha256+ OK Booting using the fdt blob at 0x10562cbc Loading Kernel Image Loading Device Tree to 2fff7000, end 2ffff090 ... OK Starting kernel ... [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 5.10.0-xilinx-v2021.2 (oe-user@oe-host) (arm-xilinx-linux-gnueabi-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35.1) #1 SMP PREEMPT Tue Oct 12 09:30:57 UTC 2021 [ 0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] OF: fdt: Machine model: Bora [ 0.000000] earlycon: cdns0 at MMIO 0xe0001000 (options '115200n8') [ 0.000000] printk: bootconsole [cdns0] enabled [ 0.000000] Memory policy: Data cache writealloc [ 0.000000] cma: Reserved 16 MiB at 0x3f000000 [ 0.000000] Zone ranges: [ 0.000000] Normal [mem 0x0000000000000000-0x000000002fffffff] [ 0.000000] HighMem [mem 0x0000000030000000-0x000000003fffffff] [ 0.000000] Movable zone start for each node [ 0.000000] Early memory node ranges [ 0.000000] node 0: [mem 0x0000000000000000-0x000000003fffffff] [ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff] [ 0.000000] percpu: Embedded 20 pages/cpu s49484 r8192 d24244 u81920 [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 260416 [ 0.000000] Kernel command line: console=ttyPS0,115200 earlycon noinitrd root=ubi0_0 rw rootfstype=ubifs ubi.mtd=2 [ 0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes, linear) [ 0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes, linear) [ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off [ 0.000000] Memory: 1007176K/1048576K available (9216K kernel code, 773K rwdata, 2352K rodata, 1024K init, 181K bss, 25016K reserved, 16384K cma-reserved, 245760K highmem) [ 0.000000] ftrace: allocating 34293 entries in 67 pages [ 0.000000] ftrace: allocated 67 pages with 3 groups [ 0.000000] rcu: Preemptible hierarchical RCU implementation. [ 0.000000] rcu: RCU event tracing is enabled. [ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2. [ 0.000000] Trampoline variant of Tasks RCU enabled. [ 0.000000] Rude variant of Tasks RCU enabled. [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies. [ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2 [ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16 [ 0.000000] efuse mapped to (ptrval) [ 0.000000] slcr mapped to (ptrval) [ 0.000000] GIC physical location is 0xf8f01000 [ 0.000000] L2C: platform modifies aux control register: 0x72360000 -> 0x72760000 [ 0.000000] L2C: DT/platform modifies aux control register: 0x72360000 -> 0x72760000 [ 0.000000] L2C-310 erratum 769419 enabled [ 0.000000] L2C-310 enabling early BRESP for Cortex-A9 [ 0.000000] L2C-310 full line of zeros enabled for Cortex-A9 [ 0.000000] L2C-310 ID prefetch enabled, offset 1 lines [ 0.000000] L2C-310 dynamic clock gating enabled, standby mode enabled [ 0.000000] L2C-310 cache controller enabled, 8 ways, 512 kB [ 0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x76760001 [ 0.000000] random: get_random_bytes called from start_kernel+0x308/0x4fc with crng_init=0 [ 0.000000] zynq_clock_init: clkc starts at (ptrval) [ 0.000000] Zynq clock init [ 0.000012] sched_clock: 64 bits at 333MHz, resolution 3ns, wraps every 4398046511103ns [ 0.005316] clocksource: arm_global_timer: mask: 0xffffffffffffffff max_cycles: 0x4ce07af025, max_idle_ns: 440795209040 ns [ 0.016249] Switching to timer-based delay loop, resolution 3ns [ 0.022905] Console: colour dummy device 80x30 [ 0.026491] Calibrating delay loop (skipped), value calculated using timer frequency.. 666.66 BogoMIPS (lpj=3333333) [ 0.036905] pid_max: default: 32768 minimum: 301 [ 0.041722] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes, linear) [ 0.048678] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes, linear) [ 0.057480] CPU: Testing write buffer coherency: ok [ 0.061121] CPU0: Spectre v2: using BPIALL workaround [ 0.066393] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 [ 0.072561] Setting up static identity map for 0x100000 - 0x100060 [ 0.077999] rcu: Hierarchical SRCU implementation. [ 0.083708] smp: Bringing up secondary CPUs ... [ 0.088167] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001 [ 0.088181] CPU1: Spectre v2: using BPIALL workaround [ 0.097757] smp: Brought up 1 node, 2 CPUs [ 0.101628] SMP: Total of 2 processors activated (1333.33 BogoMIPS). [ 0.107963] CPU: All CPU(s) started in SVC mode. [ 0.113327] devtmpfs: initialized [ 0.121410] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4 [ 0.124055] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns [ 0.133198] futex hash table entries: 512 (order: 3, 32768 bytes, linear) [ 0.141293] pinctrl core: initialized pinctrl subsystem [ 0.146374] NET: Registered protocol family 16 [ 0.151988] DMA: preallocated 256 KiB pool for atomic coherent allocations [ 0.157737] thermal_sys: Registered thermal governor 'step_wise' [ 0.158110] cpuidle: using governor ladder [ 0.166247] cpuidle: using governor menu [ 0.184578] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers. [ 0.186930] hw-breakpoint: maximum watchpoint size is 4 bytes. [ 0.192897] zynq-ocm f800c000.ocmc: ZYNQ OCM pool: 256 KiB @ 0x(ptrval) [ 0.200120] e0000000.serial: ttyPS1 at MMIO 0xe0000000 (irq = 34, base_baud = 3125000) is a xuartps [ 0.208992] e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 35, base_baud = 3125000) is a xuartps [ 0.222757] printk: console [ttyPS0] enabled [ 0.222757] printk: console [ttyPS0] enabled [ 0.227046] printk: bootconsole [cdns0] disabled [ 0.227046] printk: bootconsole [cdns0] disabled [ 0.254007] vgaarb: loaded [ 0.257202] SCSI subsystem initialized [ 0.261323] usbcore: registered new interface driver usbfs [ 0.266893] usbcore: registered new interface driver hub [ 0.272350] usbcore: registered new device driver usb [ 0.277673] mc: Linux media interface: v0.10 [ 0.282043] videodev: Linux video capture interface: v2.00 [ 0.287589] pps_core: LinuxPPS API ver. 1 registered [ 0.292584] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 0.301755] PTP clock support registered [ 0.305736] EDAC MC: Ver: 3.0.0 [ 0.309570] FPGA manager framework [ 0.313314] Advanced Linux Sound Architecture Driver Initialized. [ 0.320649] clocksource: Switched to clocksource arm_global_timer [ 0.623097] NET: Registered protocol family 2 [ 0.628269] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 6144 bytes, linear) [ 0.636714] TCP established hash table entries: 8192 (order: 3, 32768 bytes, linear) [ 0.644561] TCP bind hash table entries: 8192 (order: 4, 65536 bytes, linear) [ 0.651835] TCP: Hash tables configured (established 8192 bind 8192) [ 0.658407] UDP hash table entries: 512 (order: 2, 16384 bytes, linear) [ 0.665141] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear) [ 0.672513] NET: Registered protocol family 1 [ 0.677671] RPC: Registered named UNIX socket transport module. [ 0.683628] RPC: Registered udp transport module. [ 0.688345] RPC: Registered tcp transport module. [ 0.693043] RPC: Registered tcp NFSv4.1 backchannel transport module. [ 0.699507] PCI: CLS 0 bytes, default 64 [ 0.704113] hw perfevents: no interrupt-affinity property for /pmu@f8891000, guessing. [ 0.712358] hw perfevents: enabled with armv7_cortex_a9 PMU driver, 7 counters available [ 0.722399] workingset: timestamp_bits=14 max_order=18 bucket_order=4 [ 0.730304] jffs2: version 2.2. (NAND) (SUMMARY) © 2001-2006 Red Hat, Inc. [ 0.737774] bounce: pool size: 64 pages [ 0.741626] io scheduler mq-deadline registered [ 0.746179] io scheduler kyber registered [ 0.750754] zynq-pinctrl 700.pinctrl: zynq pinctrl initialized [ 0.760032] dma-pl330 f8003000.dmac: Loaded driver for PL330 DMAC-241330 [ 0.766787] dma-pl330 f8003000.dmac: DBUFF-128x8bytes Num_Chans-8 Num_Peri-4 Num_Events-16 [ 0.789262] brd: module loaded [ 0.804344] loop: module loaded [ 0.809631] libphy: Fixed MDIO Bus: probed [ 0.815731] CAN device driver interface [ 0.822634] libphy: MACB_mii_bus: probed [ 0.862391] macb e000b000.ethernet eth0: Cadence GEM rev 0x00020118 at 0xe000b000 irq 37 (3e:1a:de:54:41:09) [ 0.872618] e1000e: Intel(R) PRO/1000 Network Driver [ 0.877579] e1000e: Copyright(c) 1999 - 2015 Intel Corporation. [ 0.884505] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 0.891064] ehci-pci: EHCI PCI platform driver [ 0.895690] usbcore: registered new interface driver usb-storage [ 0.902828] ULPI transceiver vendor/product ID 0x0424/0x0006 [ 0.908490] Found SMSC USB331x ULPI transceiver. [ 0.913157] ULPI integrity check: passed. [ 0.919619] i2c /dev entries driver [ 0.927188] rtc-ds3232 0-0068: registered as rtc0 [ 0.932291] rtc-ds3232 0-0068: setting system clock to 2018-03-11T16:20:50 UTC (1520785250) [ 0.940932] cdns-i2c e0004000.i2c: 400 kHz mmio e0004000 irq 31 [ 0.948473] tmp421 0-004f: Could not read configuration register (-6) [ 0.955902] cdns-wdt f8005000.watchdog: Xilinx Watchdog Timer with timeout 10s [ 0.963560] EDAC MC: ECC not enabled [ 0.968031] cpufreq: cpufreq_online: CPU0: Running at unlisted initial frequency: 666666 KHz, changing to: 666667 KHz [ 0.979128] Xilinx Zynq CpuIdle Driver started [ 0.984239] sdhci: Secure Digital Host Controller Interface driver [ 0.990418] sdhci: Copyright(c) Pierre Ossman [ 0.994827] sdhci-pltfm: SDHCI platform and OF driver helper [ 1.001388] ledtrig-cpu: registered to indicate activity on CPUs [ 1.007781] clocksource: ttc_clocksource: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 537538477 ns [ 1.016949] timer #0 at (ptrval), irq=50 [ 1.021309] usbcore: registered new interface driver usbhid [ 1.026919] usbhid: USB HID core driver [ 1.030832] mmc0: SDHCI controller on e0100000.mmc [e0100000.mmc] using ADMA [ 1.031968] nand: device found, Manufacturer ID: 0xef, Chip ID: 0xd3 [ 1.044349] nand: Winbond W29N08GV [ 1.047826] nand: 1024 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64 [ 1.055618] nand: SDR timing mode 4 not acknowledged by the NAND chip [ 1.062632] Bad block table found at page 524224, version 0x01 [ 1.069325] Bad block table found at page 524160, version 0x01 [ 1.075922] 3 fixed-partitions partitions found on MTD device W29N08GV [ 1.082543] Creating 3 MTD partitions on "W29N08GV": [ 1.087580] 0x000000000000-0x000001600000 : "bootbin" [ 1.101849] 0x000001600000-0x000001640000 : "ubootenv" [ 1.111887] 0x000001640000-0x000040000000 : "rootfs" [ 1.131185] fpga_manager fpga0: Xilinx Zynq FPGA Manager registered [ 1.139624] NET: Registered protocol family 10 [ 1.145534] Segment Routing with IPv6 [ 1.149300] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver [ 1.156122] NET: Registered protocol family 17 [ 1.160584] can: controller area network core [ 1.165189] NET: Registered protocol family 29 [ 1.169729] can: raw protocol [ 1.172767] can: broadcast manager protocol [ 1.177048] can: netlink gateway - max_hops=1 [ 1.181957] Registering SWP/SWPB emulation handler [ 1.203441] of-fpga-region fpga-full: FPGA Region probed [ 1.209218] ubi0: attaching mtd2 [ 3.944731] ubi0: scanning is finished [ 3.984970] ubi0: volume 0 ("ubifs") re-sized from 1893 to 7850 LEBs [ 3.992391] ubi0: attached mtd2 (name "rootfs", size 1001 MiB) [ 3.998226] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes [ 4.005153] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512 [ 4.011919] ubi0: VID header offset: 512 (aligned 512), data offset: 2048 [ 4.018701] ubi0: good PEBs: 8010, bad PEBs: 4, corrupted PEBs: 0 [ 4.024820] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128 [ 4.032097] ubi0: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 303836513 [ 4.041168] ubi0: available PEBs: 0, total reserved PEBs: 8010, PEBs reserved for bad PEB handling: 156 [ 4.050589] ubi0: background thread "ubi_bgt0d" started, PID 54 [ 4.050796] of_cfs_init [ 4.059156] of_cfs_init: OK [ 4.062394] ALSA device list: [ 4.065363] No soundcards found. [ 4.070167] UBIFS (ubi0:0): Mounting in unauthenticated mode [ 4.076139] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 55 [ 4.175402] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "ubifs" [ 4.182766] UBIFS (ubi0:0): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes [ 4.192747] UBIFS (ubi0:0): FS size: 1011419136 bytes (964 MiB, 7839 LEBs), journal size 9033728 bytes (8 MiB, 71 LEBs) [ 4.203551] UBIFS (ubi0:0): reserved for root: 0 bytes (0 KiB) [ 4.209390] UBIFS (ubi0:0): media format: w4/r0 (latest is w5/r0), UUID 5FEDC81D-3977-4B81-B939-CAEF7CAEBED8, small LPT model [ 4.223631] VFS: Mounted root (ubifs filesystem) on device 0:15. [ 4.232185] devtmpfs: mounted [ 4.241085] Freeing unused kernel memory: 1024K [ 4.246055] Run /sbin/init as init process INIT: version 2.97 booting Starting udev [ 5.284603] udevd[81]: starting version 3.2.9 [ 5.318975] random: udevd: uninitialized urandom read (16 bytes read) [ 5.326069] random: udevd: uninitialized urandom read (16 bytes read) [ 5.341534] random: udevd: uninitialized urandom read (16 bytes read) [ 5.403685] udevd[82]: starting eudev-3.2.9 bootlogd: /dev/ttyPS0chown: cannot access '/var/log/wtmp': No such file or directory Failed to set owner -root- for -/var/log/wtmp-. Configuring packages on first boot.... (This may take several minutes. Please do not power off the machine.) Running postinst /etc/rpm-postinsts/100-sysvinit-inittab... update-rc.d: /etc/init.d/run-postinsts exists during rc.d purge (continuing) Removing any system startup links for run-postinsts ... /etc/rcS.d/S99run-postinsts INIT: Entering runlevel: 5 Configuring network interfaces... done. Starting system message bus: dbus. Starting haveged: haveged: command socket is listening at fd 3 haveged: haveged starting up Starting Dropbear SSH server: Waiting for kernel randomness to be initialised... haveged: haveged: ver: 1.9.13; arch: generic; vend: ; build: (gcc 10.2.0 CTV); collect: 128K haveged: haveged: cpu: (VC); data: 16K (D); inst: 16K (D); idx: 12/40; sz: 15006/57790 haveged: haveged: tot tests(BA8): A:1/1 B:1/1 continuous tests(B): last entropy estimate 7.99907 haveged: haveged: fills: 0, generated: 0 Generating 2048 bit rsa key, this may take a while... Public key portion is: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8WDRfMV0EWtxgmu0taCucHnUDLw11tQb1sD03U1aL+GgjpVU2Z7vgJU4YwgoJtKTXsTBNMpkKdLSENmK2Ms5Xbv5mT190+FCexkjmpSnWATjXe8gX/SVxTCLUBU3yZjtED5MbyK7M6iY+yEjS7purLqKxO8dfsShxeuzpqGHwIZ2veargJl99775G5CANcs62MP+VZ2XVBOja0wuVvRi7HNVupzufecNzNfU/EE2GGXKwWuuf2q+leXSsv3M8J6WX2qivZTCKnKDLBsh1i8GTR9lass1QfsBYECpT7RNPyHwP8OoSLeN1qr4hiqyHYrgGtWj/1EDJOhaHGhco7CXx root@boralite Fingerprint: sha1!! 84:cf:73:1a:fa:1d:bc:6e:13:ba:6f:0c:c7:32:51:8f:57:42:15:08 dropbear. Starting rpcbind daemon...done. starting statd: done Starting atd: OK Starting internet superserver: inetd. NFS daemon support not enabled in kernel Starting system log daemon...0 Mar 11 16:21:12 boralite kernel: [ 0.000000] L2C: platform modifies aux control register: 0x72360000 -> 0x72760000 Mar 11 16:21:12 boralite kernel: [ 0.000000] L2C: DT/platform modifies aux control register: 0x72360000 -> 0x72760000 Mar 11 16:21:12 boralite kernel: [ 0.704113] hw perfevents: no interrupt-affinity property for /pmu@f8891000, guessing. Mar 11 16:21:12 boralite kernel: [ 0.948473] tmp421 0-004f: Could not read configuration register (-6) Mar 11 16:21:12 boralite kernel: [ 1.055618] nand: SDR timing mode 4 not acknowledged by the NAND chip Mar 11 16:21:12 boralite kernel: [ 7.162906] urandom_read: 4 callbacks suppressed Starting internet superserver: xinetd. Starting crond: OK Starting tcf-agent: OK PetaLinux 2021.2 boralite ttyPS0 root@boralite:~# cat /etc/os-release ID=petalinux NAME="PetaLinux" VERSION="2021.2 (gatesgarth)" VERSION_ID=2021.2 PRETTY_NAME="PetaLinux 2021.2 (gatesgarth)" BUILD_VERSION="desk-xz7-l-1.1.0" root@boralite:~# cat /etc/build ----------------------- Build Configuration: | ----------------------- DISTRO = petalinux DISTRO_VERSION = 2021.2 MACHINE = zynq-generic IMAGE_BASENAME = dave-image-devel ----------------------- Layer Revisions: | ----------------------- meta = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-poky = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-perl = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-python = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-filesystems = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-gnome = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-multimedia = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-networking = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-webserver = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-xfce = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-initramfs = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-oe = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-clang = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-chromium = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-qt5 = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-microblaze = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-xilinx-bsp = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-xilinx-pynq = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-xilinx-contrib = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-xilinx-standalone = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-xilinx-tools = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-petalinux = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-virtualization = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-openamp = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-jupyter = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-vitis-ai = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-python2 = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-som = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-security = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-tpm = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-user = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified meta-dave = HEAD:e944801f104f86191cd086d0cea8f3df88dda061 workspace = HEAD:3b09904245b9f132fc8951d4d4ba9c3ee1b2b656 -- modified root@boralite:~# uname -a Linux boralite 5.10.0-xilinx-v2021.2 #1 SMP PREEMPT Tue Oct 12 09:30:57 UTC 2021 armv7l armv7l armv7l GNU/Linux root@boralite:~# shutdown -h now Broadcast message from root@boralite (ttyPS0) (Sun Mar 11 16:21:21 2018): The system is going down for system halt NOW! INIT: Sending processes configured via /etc/inittab the TERM signal root@boralite:~# Stopping haveged: Stopping Dropbear SSH server: stopped /usr/sbin/dropbear (pid 278) dropbear. Stopping atd: OK Stopping system message bus: dbus. Stopping internet superserver: inetd. stopping mountd: done stopping nfsd: done Stopping system log daemon...0 Stopping tcf-agent: OK Stopping internet superserver: xinetd. stopping statd: done Stopping crond: OK Stopping rpcbind daemon... done. Deconfiguring network interfaces... done. Sending all processes the TERM signal... logout Sending all processes the KILL signal... Unmounting remote filesystems... Deactivating swap... Unmounting local filesystems... [ 37.521365] reboot: System halted
How to configure the network interfaces[edit | edit source]
For deploying an Embedded System, one of the most important configuration is the Network Interface configuration.
Once the Embedded Device is finally configured for stand-alone bootstrap, the network interface should be configured for reaching the device remotely via network connections like ssh, telnet, ftp, http, etc.
This Application Note briefly describes how it is possible to simply configure the network interfaces on SystemV (aka SysV) or systemd
Resources[edit | edit source]
For further details on network configuration, please refer - for example - to:
Examples[edit | edit source]
The following configuration assumptions are used in the paragraphs shown below:
- IP address range of the LAN network 192.168.1.0 - 192.168.1.255
- IP address of the gateway 192.168.1.254
- IP address of the device 192.168.1.100
SysV[edit | edit source]
The configuration files for SysV can be found in pre-defined directorys as written here
Basically, for network configuration, it should be enough to properly configure the /etc/network/interfaces
file.
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)
Here below an example of configuration file:
Static IP address[edit | edit source]
The network interface is configured with a static IP address by creating the configuration entry in the /etc/network/interfaces file as the following:
auto eth0 iface eth0 inet static address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.254
Dynamic IP addres (DHCP)[edit | edit source]
The network interface is configured - using a proper DHCP server on the network - by creating the configuration entry in the /etc/network/interfaces file as the following:
allow-hotplug eth0 iface eth0 inet dhcp
When the Linux kernel detects the physical interface eth0, the iface causes ifup to use DHCP to configure the interface.
DNS[edit | edit source]
If the resolvconf
package is not installed, the DNS configuration can be done manually by editing the /etc/resolv.conf as the following:
nameserver 192.168.1.1
For example, it can be done on the command line echoing the string in this way:
root@axel-lite:~# echo "nameserver 192.168.1.1" > /etc/resolv.conf
loopback network interface[edit | edit source]
The following configuration entry in the /etc/network/interfaces file brings up the loopback network interface lo upon booting the system.
# The loopback interface auto lo iface lo inet loopback
This one always exists in the /etc/network/interfaces file.
systemd[edit | edit source]
The network configuration for systemd are basically found in the /etc/systemd/network/
directory.
The most simply way for configuring the network interface is to create/edit the file /etc/systemd/network/20-eth0.network as per the following paragraphs.
For more example and usage hints on systemd, please refer to our wiki page.
Static IP address[edit | edit source]
[Match] Name=eth0 # Prevent the interface loading if the kernel boots from nfs KernelCommandLine=!nfsroot [Network] Address=192.168.1.100 Gateway=192.168.1.254 DNS=192.168.1.1
Once modified, the networkd
service should be resarted:
systemctl restart systemd-networkd
Dynamic IP addres (DHCP)[edit | edit source]
The network interface is configured - using a proper DHCP server on the network - by using the DHCP key in the configuration file as the following:
[Match] Name=eth0 # Prevent the interface loading if the kernel boots from nfs KernelCommandLine=!nfsroot [Network] DHCP=yes
When systemd network starts, it tries to use a DHCP server present in the network to configure the interface.
DNS[edit | edit source]
The DNS key (in the configuration file) is used only if the systemd-resolved service is enabled and the /etc/resolv.conf has a symbolic link to /run/systemd/resolve/stub-resolv.conf
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
Once modified, the resolved
service should be resarted:
systemctl restart systemd-resolved
loopback network interface[edit | edit source]
systemd contains native implementations of various tasks that need to be executed as part of the boot process.
For example, it sets the hostname or configures the loopback network device.
Apply configuration changes[edit | edit source]
After editing the above files, changes are applied after reboot or by restarting systemd-networkd.service
:
root@imx6qdlxelk:~# systemctl restart systemd-networkd.service
Peripherals[edit | edit source]
Peripheral Console[edit | edit source]
The Zynq-7000 main UART device (UART1) is mapped to the ttyPS0
device.
Accessing the peripheral[edit | edit source]
Linux messages at boot time[edit | edit source]
... [ 0.000000] Kernel command line: console=ttyPS0,115200 earlycon root=/dev/mmcblk0p2 rw rootwait ... [ 0.207202] e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 35, base_baud = 3125000) is a xuartps [ 0.221089] printk: console [ttyPS0] enabled ...
Peripheral Ethernet[edit | edit source]
The ethernet interface 0 is made available through the gem0
interface, this interface should be initialized on the device tree.
Device tree configuration[edit | edit source]
Here below an example of device tree for ethernet interface 0 configuration used on standard DAVE's kit for the BORA, BORA Xpress and BORA Lite:
From bora.dtsi
:
&gem0 { status = "okay"; phy-mode = "rgmii-id"; phy-handle = <ðernet_phy>; ethernet_phy: ethernet-phy@7 { reg = <0x07>; device_type = "ethernet-phy"; mdio { #address-cells = <1>; #size-cells = <0>; phy0: phy@7 { rxc-skew-ps = <0x744>; txc-skew-ps = <0x744>; micrel,led-mode = <0x01>; compatible = "micrel,ksz9031"; device_type = "ethernet-phy"; reg = <0x07>; }; }; }; };
Accessing the peripheral[edit | edit source]
Linux messages at boot time[edit | edit source]
eth0
[ 0.588523] macb e000b000.ethernet eth0: Cadence GEM rev 0x00020118 at 0xe000b000 irq 37 (00:50:c2:1e:af:e0) ... [ 3.538025] macb e000b000.ethernet eth0: PHY [e000b000.ethernet-ffffffff:07] driver [Micrel KSZ9031 Gigabit PHY] (irq=POLL) [ 3.538044] macb e000b000.ethernet eth0: configuring for phy/rgmii-id link mode
Cable connection:
... ... [ 7.698004] macb e000b000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off [ 7.698035] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
Check the interface with ifconfig[edit | edit source]
root@bora:~# ifconfig eth0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.89 netmask 255.255.255.0 broadcast 0.0.0.0 inet6 fe80::250:c2ff:fe1e:afe0 prefixlen 64 scopeid 0x20<link> ether 00:50:c2:1e:af:e0 txqueuelen 1000 (Ethernet) RX packets 1141 bytes 62918 (61.4 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 45 bytes 4892 (4.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 37 base 0xb000
Test with iperf3[edit | edit source]
root@bora:~# iperf3 -t 5 -c 192.168.0.167 Connecting to host 192.168.0.167, port 5201 [ 5] local 192.168.0.89 port 33028 connected to 192.168.0.167 port 5201 [ ID] Interval Transfer Bitrate Retr Cwnd [ 5] 0.00-1.00 sec 63.0 MBytes 527 Mbits/sec 0 427 KBytes [ 5] 1.00-2.02 sec 88.3 MBytes 727 Mbits/sec 0 655 KBytes [ 5] 2.02-3.01 sec 87.0 MBytes 735 Mbits/sec 1 522 KBytes [ 5] 3.01-4.01 sec 80.5 MBytes 675 Mbits/sec 0 602 KBytes [ 5] 4.01-5.00 sec 76.9 MBytes 651 Mbits/sec 0 636 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate Retr [ 5] 0.00-5.00 sec 396 MBytes 663 Mbits/sec 1 sender [ 5] 0.00-5.58 sec 396 MBytes 595 Mbits/sec receiver iperf Done. root@bora:~#
Peripheral SD[edit | edit source]
The SD device, if present, will be associated by the Linux kernel to the mmcblk0
device:
Accessing the peripheral[edit | edit source]
Linux messages at boot time[edit | edit source]
[ 0.740571] mmc0: SDHCI controller on e0100000.mmc [e0100000.mmc] using ADMA ... [ 0.824174] mmc0: new high speed SDHC card at address aaaa [ 0.830415] mmcblk0: mmc0:aaaa SA16G 14.8 GiB [ 0.837970] mmcblk0: p1 p2
Additional information[edit | edit source]
Once detected, it can be mounted and accessed via usual Linux commands:
root@bora:~# mkdir -p /mnt/mmcblk0p1 root@bora:~# mkdir -p /mnt/mmcblk0p2 root@bora:~# mount /dev/mmcblk0p1 /mnt/mmcblk0p1 root@bora:~# mount /dev/mmcblk0p2 /mnt/mmcblk0p2 root@bora:~# ls /mnt/mmcblk0p1 BOOT.BIN System Volume Information boot.scr image.ub root@bora:~# ls /mnt/mmcblk0p2 bin boot dev etc home lib lost+found media mnt proc run sbin sys tmp usr var root@bora:~# dd if=/dev/zero of=test_file_100MB bs=1M count=100 100+0 records in 100+0 records out 104857600 bytes (105 MB, 100 MiB) copied, 1.50526 s, 69.7 MB/s root@bora:~# time cp test_file_100MB /mnt/mmcblk0p1 real 0m3.006s user 0m0.011s sys 0m1.853s root@bora:~#
Peripheral CAN[edit | edit source]
CAN is routed through the PL using the TCL scripts for the Vivado project example here below:
recreate_prj_bora_BASE.tcl
recreate_prj_boralite_BASE.tcl
recreate_prj_boralite_NAND.tcl
recreate_prj_borax_BASE.tcl
Accessing the peripheral[edit | edit source]
Linux messages at boot time[edit | edit source]
root@bora:~# dmesg | grep -i can [ 0.545770] CAN device driver interface [ 0.752012] can: controller area network core [ 0.761010] can: raw protocol [ 0.763989] can: broadcast manager protocol [ 0.768236] can: netlink gateway - max_hops=1
Enable the interface and check status[edit | edit source]
The following commands can be issued from the command line to enable the CAN interface on BORA:
root@bora:~# ip link set can0 type can bitrate 500000 root@bora:~# ifconfig can0 up
To test the CAN interface it is possible to use a PCAN-USB device connected to the DESK-XZ7-L-MVM. The following commands can be issued from the command line to enable the CAN interface on the MVM:
dvdk@vagrant:~# sudo ip link set can0 type can bitrate 500000 dvdk@vagrant:~# sudo ifconfig can0 up
Usage with can-utils[edit | edit source]
cansend[edit | edit source]
This is an example of using a BORA Evaluation Kit to send data connected to a PCAN-USB device (that receives the data).
- the following commands can be issued from the command line on BORA to send data to PCAN-USB
root@bora:~# cansend can0 -i 0x7ff 00 01 02 03 04 05 06 07 interface = can0, family = 29, type = 3, proto = 1 <0x7ff> [8] 00 01 02 03 04 05 06 07
- the following commands can be issued from the command line on MVM to receive data from BORA with PCAN-USB
dvdk@vagrant:~# candump can0 can0 7FF [8] 00 01 02 03 04 05 06 0
candump[edit | edit source]
This is an example of using a PCAN-USB device to send data to a connected BORA Evaluation Kit (that receives the data).
- the following commands can be issued from the command line on MVM to send data with PCAN-USB
dvdk@vagrant:~# cansend can0 7ff#0001020304050607 can0 7FF [8] 00 01 02 03 04 05 06 07
- the following commands can be issued from the command line on BORA to receive data from PCAN-USB
root@bora:~# candump can0 interface = can0, family = 29, type = 3, proto = 1 <0x7ff> [8] 00 01 02 03 04 05 06 07
Peripheral NOR[edit | edit source]
Device tree configuration[edit | edit source]
Here below an example of device tree for the Quad-SPI NOR flash configuration used on standard DAVE's kit for the BORA, BORA Xpress and BORA Lite:
From bora.dtsi
:
... ... &qspi { flash0: flash@0 { // we need to use 128Mbit (16MiB) device compatibile even if // the real hardware has a 256Mbit (32MiB) device because of // Zynq QSPI controller limits compatible = "spansion,s25fl128s1", "jedec,spi-nor"; #address-cells = <1>; #size-cells = <1>; reg = <0>; spi-tx-bus-width = <1>; spi-rx-bus-width = <4>; spi-max-frequency = <25000000>; }; }; ... ...
Accessing the peripheral[edit | edit source]
Linux messages at boot time[edit | edit source]
[ 0.509067] spi-nor spi0.0: found s25fl256s1, expected s25fl128s1 [ 0.515401] spi-nor spi0.0: s25fl256s1 (32768 Kbytes) [ 0.520482] 1 fixed-partitions partitions found on MTD device spi0.0 [ 0.526863] Creating 1 MTD partitions on "spi0.0": [ 0.531648] 0x000000000000-0x000002000000 : "boot"
Check the mtd partitions[edit | edit source]
root@bora:~# cat /proc/mtd dev: size erasesize name mtd0: 02000000 00010000 "boot"
Peripheral NAND[edit | edit source]
Device tree configuration[edit | edit source]
If user use |
Here below an example of device tree configuration used on standard DAVE's kit for the BORA Lite NAND flash:
From bora.dtsi
:
... ... &nand0{ partition@nand-bootbin { label = "bootbin"; reg = <0x00000000 0x01600000>; }; partition@nand-ubootenv { label = "ubootenv"; reg = <0x01600000 0x00040000>; }; partition@nand-rootfs { label = "rootfs"; reg = <0x01640000 0x0>; }; }; ... ...
Accessing the peripheral[edit | edit source]
Linux messages at boot time (boot from SD with NAND flash support)[edit | edit source]
[ 0.709510] nand: device found, Manufacturer ID: 0xef, Chip ID: 0xd3 [ 0.712698] nand: Winbond W29N08GV [ 0.714412] nand: 1024 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64 ... [ 0.741479] 3 fixed-partitions partitions found on MTD device W29N08GV [ 0.748115] Creating 3 MTD partitions on "W29N08GV": [ 0.753138] 0x000000000000-0x000001600000 : "bootbin" [ 0.760908] 0x000001600000-0x000001640000 : "ubootenv" [ 0.776202] 0x000001640000-0x000040000000 : "rootfs"
Check the mtd partitions[edit | edit source]
root@boralite:~# cat /proc/mtd dev: size erasesize name mtd0: 01600000 00020000 "bootbin" mtd1: 00040000 00020000 "ubootenv" mtd2: 3e9c0000 00020000 "rootfs"
Linux messages at boot time (boot from NAND flash)[edit | edit source]
[ 0.705403] nand: device found, Manufacturer ID: 0xef, Chip ID: 0xd3 [ 0.708607] nand: Winbond W29N08GV [ 0.710317] nand: 1024 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64 ... [ 1.076003] 3 fixed-partitions partitions found on MTD device W29N08GV [ 1.082625] Creating 3 MTD partitions on "W29N08GV": [ 1.087662] 0x000000000000-0x000001600000 : "bootbin" [ 1.101780] 0x000001600000-0x000001640000 : "ubootenv" [ 1.111817] 0x000001640000-0x000040000000 : "rootfs" ... [ 1.209392] ubi0: attaching mtd2 [ 3.943763] ubi0: scanning is finished [ 3.970955] ubi0: attached mtd2 (name "rootfs", size 1001 MiB) [ 3.976801] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes [ 3.983713] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512 [ 3.990409] ubi0: VID header offset: 512 (aligned 512), data offset: 2048 [ 3.997277] ubi0: good PEBs: 8010, bad PEBs: 4, corrupted PEBs: 0 [ 4.003395] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128 [ 4.010637] ubi0: max/mean erase counter: 1/0, WL threshold: 4096, image sequence number: 1501637841 [ 4.019766] ubi0: available PEBs: 0, total reserved PEBs: 8010, PEBs reserved for bad PEB handling: 156 [ 4.029253] ubi0: background thread "ubi_bgt0d" started, PID 54 [ 4.048733] UBIFS (ubi0:0): Mounting in unauthenticated mode [ 4.054771] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 55 [ 4.098540] UBIFS (ubi0:0): recovery needed [ 4.252929] UBIFS (ubi0:0): recovery completed [ 4.257516] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "ubifs" [ 4.264862] UBIFS (ubi0:0): LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes [ 4.274857] UBIFS (ubi0:0): FS size: 1011419136 bytes (964 MiB, 7839 LEBs), journal size 9033728 bytes (8 MiB, 71 LEBs) [ 4.285664] UBIFS (ubi0:0): reserved for root: 0 bytes (0 KiB) [ 4.291525] UBIFS (ubi0:0): media format: w4/r0 (latest is w5/r0), UUID 18F323BA-5A9C-422A-912C-2C06647F3EDF, small LPT model ...
Check the mtd partitions[edit | edit source]
root@boralite:~# cat /proc/mtd dev: size erasesize name mtd0: 01600000 00020000 "bootbin" mtd1: 00040000 00020000 "ubootenv" mtd2: 3e9c0000 00020000 "rootfs"
Peripheral UART[edit | edit source]
The Zynq-7000 second UART device (UART0) is routed through the PL and it is mapped to the ttyPS1
device. This feature is available in the Vivado project example using the TCL scripts here below:
recreate_prj_bora_BASE.tcl
recreate_prj_bora_ETH1.tcl
recreate_prj_boralite_BASE.tcl
recreate_prj_boralite_ETH1.tcl
recreate_prj_boralite_NAND.tcl
recreate_prj_borax_BASE.tcl
recreate_prj_borax_ETH1.tcl
Accessing the peripheral[edit | edit source]
Linux messages at boot time[edit | edit source]
... [ 0.198315] e0000000.serial: ttyPS1 at MMIO 0xe0000000 (irq = 34, base_baud = 3125000) is a xuartps [ 0.207202] e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 35, base_baud = 3125000) is a xuartps ...
Usage with stty[edit | edit source]
N.B. UART mapping respect to ttyPSX
is the following one:
UART0 (RS232) <-> ttyPS1 UART1 (Serial Port) <-> ttyPS0
root@bora:~# stty -F /dev/ttyPS1 115200 -echo root@bora:~# cat /dev/ttyPS1 & [1] 297 root@bora:~# echo "Test loopback" > /dev/ttyPS1 root@bora:~# Test loopback
Helloworld from UART0[edit | edit source]
On target we need to loopback pin 6
and 7
of PMOD A
.
Here below an example on C code for initializing and using UART0 through FPGA:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <termios.h> int set_interface_attribs (int fd, int speed, int parity) { struct termios tty; memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { printf("error %d from tcgetattr", errno); return -1; } cfsetospeed (&tty, speed); cfsetispeed (&tty, speed); tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars // disable IGNBRK for mismatched speed tests; otherwise receive break // as \000 chars tty.c_iflag &= ~IGNBRK; // disable break processing tty.c_lflag = 0; // no signaling chars, no echo, // no canonical processing tty.c_oflag = 0; // no remapping, no delays tty.c_cc[VMIN] = 0; // read doesn't block tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, // enable reading tty.c_cflag &= ~(PARENB | PARODD); // shut off parity tty.c_cflag |= parity; tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CRTSCTS; if (tcsetattr (fd, TCSANOW, &tty) != 0) { printf("error %d from tcsetattr", errno); return -1; } return 0; } int main() { int fd; char *portname = "/dev/ttyPS1"; char msg[] = "Hello World from BELK (FPGA PS0 UART)!\n\r"; fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); if (fd < 0) { printf("error %d opening %s: %s", errno, portname, strerror (errno)); exit(1); } printf("%s", msg); set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity) write(fd, msg, strlen(msg)); exit(0); }
For compile it, please use the following instruction:
dvdk@vagrant:~$ wget https://mirror.dave.eu/desk-xz-l/desk-xz7-l-1.0.1/desk-xz7-l-1.0.1_bora_sdk.sh --2024-01-26 11:57:04-- https://mirror.dave.eu/desk-xz-l/desk-xz7-l-1.0.1/desk-xz7-l-1.0.1_bora_sdk.sh Resolving mirror.dave.eu (mirror.dave.eu)... 84.46.251.143 Connecting to mirror.dave.eu (mirror.dave.eu)|84.46.251.143|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 998591008 (952M) [text/x-sh] Saving to: ‘desk-xz7-l-1.0.1_bora_sdk.sh’ desk-xz7-l-1.0.1_bora_sdk.sh 100%[====================================================================================================>] 952.33M 10.8MB/s in 1m 40s 2024-01-26 11:58:43 (9.57 MB/s) - ‘desk-xz7-l-1.0.1_bora_sdk.sh’ saved [998591008/998591008] dvdk@vagrant:~$ chmod 755 desk-xz7-l-1.0.1_bora_sdk.sh dvdk@vagrant:~$ ./desk-xz7-l-1.0.1_bora_sdk.sh PetaLinux SDK installer version 2021.2 ====================================== Enter target directory for SDK (default: /opt/petalinux/2021.2): You are about to install the SDK to "/opt/petalinux/2021.2". Proceed [Y/n]? y Extracting SDK.......................................................................................................................................................................................................................done Setting it up...done SDK has been successfully set up and is ready to be used. Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g. $ . /opt/petalinux/2021.2/environment-setup-cortexa9t2hf-neon-xilinx-linux-gnueabi dvdk@vagrant:~$ source /opt/petalinux/2021.2/environment-setup-cortexa9t2hf-neon-xilinx-linux-gnueabi dvdk@vagrant:~$ vi hello_UART0.c dvdk@vagrant:~$ $CC -O hello_UART0.c -o hello_UART0
Copy hello_UART0
on target and perform the following command:
root@bora:~# chmod u+x hello_UART0 root@bora:~# ./hello_UART0 Hello World from BELK (FPGA PS0 UART)!
Additional information[edit | edit source]
Serial ports can be used through the standard serial programming API.
For detailed information, please refer to the Serial Programming HOWTO at Serial-Programming-HOWTO
Peripheral USB OTG[edit | edit source]
Device tree configuration[edit | edit source]
Here below an example of device tree configuration used on standard DAVE's kit for the BORA, BORA Xpress and BORA Lite:
From bora.dtsi
:
... ... / { ... ... usb_phy0: phy0@e0002000{ compatible = "ulpi-phy"; #phy-cells = <0x00>; reg = <0xe0002000 0x1000>; view-port = <0x170>; drv-vbus; }; ... ... }; ... ... &usb0 { dr_mode = "otg"; usb-phy = <&usb_phy0>; }; ... ...
Accessing the peripheral[edit | edit source]
Linux messages in host mode[edit | edit source]
When a USB2.0 peripheral is inserted, in the following example a memory mass storage device, the kernel recognizes the device (i.e. class, vendor id, product id, etc.)
[ 456.139975] ci_hdrc ci_hdrc.0: EHCI Host Controller [ 456.140014] ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1 [ 456.165598] ci_hdrc ci_hdrc.0: USB 2.0 started, EHCI 1.00 [ 456.165904] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.10 [ 456.165921] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 456.165932] usb usb1: Product: EHCI Host Controller [ 456.165941] usb usb1: Manufacturer: Linux 5.10.0-xilinx-v2021.2 ehci_hcd [ 456.165951] usb usb1: SerialNumber: ci_hdrc.0 [ 456.166730] hub 1-0:1.0: USB hub found [ 456.166800] hub 1-0:1.0: 1 port detected [ 457.115612] usb 1-1: new high-speed USB device number 2 using ci_hdrc [ 457.316438] usb 1-1: New USB device found, idVendor=0781, idProduct=557d, bcdDevice= 1.00 [ 457.316454] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 457.316465] usb 1-1: Product: Cruzer Force [ 457.316474] usb 1-1: Manufacturer: SanDisk [ 457.316483] usb 1-1: SerialNumber: 03021401121621082422 [ 457.317184] usb-storage 1-1:1.0: USB Mass Storage device detected [ 457.318430] scsi host0: usb-storage 1-1:1.0 [ 458.336628] scsi 0:0:0:0: Direct-Access SanDisk Cruzer Force 1.00 PQ: 0 ANSI: 6 [ 458.338116] sd 0:0:0:0: Attached scsi generic sg0 type 0 [ 458.338359] sd 0:0:0:0: [sda] 60088320 512-byte logical blocks: (30.8 GB/28.7 GiB) [ 458.339341] sd 0:0:0:0: [sda] Write Protect is off [ 458.339358] sd 0:0:0:0: [sda] Mode Sense: 43 00 00 00 [ 458.340543] sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA [ 458.401467] sda: sda1 [ 458.409036] sd 0:0:0:0: [sda] Attached SCSI removable disk [ 458.416048] usb 1-1: Get one byte OTG status failed
Additional information[edit | edit source]
If the root file system configuration does not automatically mount the partition, it is possible to mount the device using the following command:
root@bora:~# mkdir -p /mnt/usb root@bora:~# mount /dev/sda1 /mnt/usb root@bora:~# ls -la /mnt/usb/ total 116 drwxr-xr-x 4 root root 65536 Jan 1 1970 . drwxr-xr-x 3 root root 4096 Mar 12 16:05 .. drwxr-xr-x 2 root root 16384 Feb 3 2023 System Volume Information drwxr-xr-x 3 root root 16384 Aug 1 2023 phytool -rwxr-xr-x 1 root root 13 Oct 6 2022 uboot_testfile.txt
Accessing the device[edit | edit source]
Usage with mass-storage[edit | edit source]
root@bora:~# dd if=/dev/zero of=/tmp/mass count=16 bs=1M 16+0 records in 16+0 records out 16777216 bytes (17 MB, 16 MiB) copied, 0.0903981 s, 186 MB/s root@bora:~# mkfs.ext4 /tmp/mass mke2fs 1.45.6 (20-Mar-2020) Discarding device blocks: done Creating filesystem with 16384 1k blocks and 4096 inodes Filesystem UUID: 3f0fa651-33af-4001-b6c0-8774cf2d2f56 Superblock backups stored on blocks: 8193 Allocating group tables: done Writing inode tables: done Creating journal (1024 blocks): done Writing superblocks and filesystem accounting information: done root@bora:~# mkdir -p /tmp/loop root@bora:~# mount /tmp/mass /tmp/loop Mar 12 16:08:24 bora kernel: [ 659.854210] ext4 filesystem being mounted at /var/volatile/tmp/loop supports timestamps until 2038 (0x7fffffff) root@bora:~# echo "Hello from desk-xz7-l" > /tmp/loop/usb.txt root@bora:~# umount /tmp/loop root@bora:~#
then insert the g_mass_storage
kernel module driver enabling an Windows PC to see it as a removable device
root@bora:~# modprobe --first-time g_mass_storage file=/tmp/mass iSerialNumber=USBOTGCHECK
Once the USB cable is connected to the PC, the kernel prints the following messages:
[ 34.208769] Mass Storage Function, version: 2009/09/11 [ 34.208790] LUN: removable file: (no medium) [ 34.208929] LUN: file: /var/volatile/tmp/mass [ 34.208940] Number of LUNs=1 [ 34.209181] g_mass_storage gadget: Mass Storage Gadget, version: 2009/09/11 [ 34.209194] g_mass_storage gadget: g_mass_storage ready
and the Windows PC activate the driver and the disk is available as a Drive Unit (with the usb.txt file available).
Peripheral Temperature sensors[edit | edit source]
BORA and BORA Xpress SOMs has a TMP421AIDCN temperature sensor onboard.
Accessing the peripheral[edit | edit source]
The temperature information can be accessed through the sysfs
interface:
read the PCB temperature[edit | edit source]
root@bora:~# cat /sys/devices/soc0/axi/e0004000.i2c/i2c-0/0-004f/hwmon/hwmon1/temp1_input
the returned value has to be divided by 1000 for a °C temperature
read the CPU temperature[edit | edit source]
root@bora:~# cat /sys/devices/soc0/axi/e0004000.i2c/i2c-0/0-004f/hwmon/hwmon1/temp2_input
the returned value has to be divided by 1000 for a °C temperature
internal SoC temperature[edit | edit source]
Moreover, the SoC has an internal temperature sensor device which can be read using the following shell script:
root@bora:~# cat temp.sh #!/bin/sh # Tcpu TEMP_RAW=`cat /sys/devices/soc0/axi/f8007100.adc//iio\:device1/in_temp0_raw` TEMP_OFFSET=`cat /sys/devices/soc0/axi/f8007100.adc//iio\:device1/in_temp0_offset` TEMP_SCALE=`cat /sys/devices/soc0/axi/f8007100.adc//iio\:device1/in_temp0_scale` TEMP=`awk "BEGIN {print (($TEMP_RAW+$TEMP_OFFSET)*$TEMP_SCALE)/1000}"` echo "Cpu Temp: ${TEMP}" root@bora:~# chmod u+x temp.sh root@bora:~# ./temp.sh Cpu Temp: 46.0172
Peripheral Power meter[edit | edit source]
BORA, BORA Xpress and BORA Lite EVBs has a INA226 device connected to the I2C bus. The following commands can be saved as a shell script (e.g. read_power_values.sh
) and run to collect the measurements data:
root@bora:~# cat read_power_values.sh #!/bin/sh path_dev=/sys/bus/iio/devices/iio\:device0/ IN_VOLT0_RAW=$(cat "$path_dev/in_voltage0_raw") IN_VOLT0_SCALE=$(cat "$path_dev/in_voltage0_scale") IN_VOLT1_RAW=$(cat "$path_dev/in_voltage1_raw") IN_VOLT1_SCALE=$(cat "$path_dev/in_voltage1_scale") IN_VOLT0=$(echo "$IN_VOLT0_RAW*$IN_VOLT0_SCALE" | bc) IN_VOLT1=$(echo "$IN_VOLT1_RAW*$IN_VOLT1_SCALE" | bc) VOLTAGE=`awk "BEGIN {print ($IN_VOLT1-$IN_VOLT0)/1000}"` IN_CURRENT3_RAW=`cat $path_dev/in_current3_raw` IN_CURRENT3_SCALE=`cat $path_dev/in_current3_scale` CURRENT=`awk "BEGIN {print ($IN_CURRENT3_RAW*$IN_CURRENT3_SCALE)/1000}"` IN_POWER2_RAW=`cat $path_dev/in_power2_raw` IN_POWER2_SCALE=`cat $path_dev/in_power2_scale` POWER=`awk "BEGIN {print ($IN_POWER2_RAW*$IN_POWER2_SCALE)/1000}"` echo "Voltage: ${VOLTAGE}, Current: ${CURRENT}, Power: ${POWER}"
root@bora:~# ./read_power_values.sh Voltage: 3.30573, Current: 0.72375, Power: 2.3875 root@bora:~#