boards: intel_adsp: unify and update docs

Unifies docs into one updated guide with stubs for each platform.

Signed-off-by: Lauren Murphy <lauren.murphy@intel.com>
This commit is contained in:
Lauren Murphy 2023-03-06 14:24:35 -08:00 committed by Carles Cufí
parent c36622daa5
commit fb9aefca1f
8 changed files with 872 additions and 856 deletions

View file

@ -7,4 +7,4 @@ XTENSA Boards
:maxdepth: 1
:glob:
**/*
**/index

View file

@ -0,0 +1,35 @@
.. _intel_adsp_ace15:
Intel ADSP ACE 1.5
##################
Overview
********
This board configuration is used to run Zephyr on the Intel ACE 1.5 Audio DSP.
This configuration is present, for example, on Intel Meteor Lake microprocessors.
Refer to :ref:`intel_adsp_generic` for more details on Intel ADSP ACE and CAVS.
System requirements
*******************
Xtensa Toolchain
----------------
If you choose to build with the Xtensa toolchain instead of the Zephyr SDK, set
the following environment variables specific to the board in addition to the
Xtensa toolchain environment variables listed in :ref:`intel_adsp_generic`.
.. code-block:: shell
export ZEPHYR_TOOLCHAIN_VARIANT=xt-clang
export TOOLCHAIN_VER=RI-2021.7-linux
export XTENSA_CORE=ace10_LX7HiFi4
For older versions of the toolchain, set the toolchain variant to ``xcc``.
Programming and Debugging
*************************
Refer to :ref:`intel_adsp_generic` for generic instructions on programming and
debugging applicable to all CAVS and ACE platforms.

View file

@ -1,156 +1,34 @@
.. _Up_Squared_Audio_DSP:
.. _intel_adsp_cavs15:
Up Squared Audio DSP
####################
Intel ADSP CAVS 1.5
###################
System Requirements
Overview
********
This board configuration is used to run Zephyr on the Intel CAVS 1.5 Audio DSP.
This configuration is present, for example, on Intel `Apollo Lake`_ microprocessors.
Refer to :ref:`intel_adsp_generic` for more details on Intel ADSP ACE and CAVS.
System requirements
*******************
Prerequisites
=============
Xtensa Toolchain
----------------
The Zephyr SDK 0.11 or higher is required.
If you choose to build with the Xtensa toolchain instead of the Zephyr SDK, set
the following environment variables specific to the board in addition to the
Xtensa toolchain environment variables listed in :ref:`intel_adsp_generic`.
Since firmware binary signing for Audio DSP is mandatory on Intel products
form Skylake onwards the signing tool and key are needed.
.. code-block:: shell
``up_squared`` board is running Linux with `SOF Diagnostic Driver`_ built and
loaded.
Signing tool
------------
rimage is Audio DSP firmware image creation and signing tool. The tool is used
by `Sound Open Firmware`_ to generate binary firmware signed images.
For the building instructions refer to `rimage Build Instructions`_.
Signing keys
------------
The key used is Intel Open Source Technology Center (OTC) community key.
It can be freely used by anyone and intended for firmware developers.
Please download and store private key from the location:
https://github.com/thesofproject/sof/blob/master/keys/otc_private_key.pem
For more information about keys refer to `rimage keys`_.
Setup up_squared board
----------------------
To setup Linux on ``up_squared`` board refer to
`Getting Started with Ubuntu Core on an UP Squared Board`_.
After installing Linux build and install `SOF Diagnostic Driver`_.
export TOOLCHAIN_VER=RG-2017.8-linux
export XTENSA_CORE=X4H3I16w2D48w3a_2017_8
Programming and Debugging
*************************
Build Zephyr application
========================
Refer to :ref:`intel_adsp_generic` for generic instructions on programming and
debugging applicable to all CAVS and ACE platforms.
Applications can be build in the usual way (see :ref:`build_an_application`
for more details). The only additional step required is signing. For example,
for building ``hello_world`` application following steps are needed.
#. Building Zephyr application ``hello_world``
.. zephyr-app-commands::
:zephyr-app: samples/hello_world
:board: intel_adsp_cavs15
:goals: build
#. Sign and create firmware image
.. code-block:: console
west sign -t rimage -- -k <path to otc_private_key.pem>
Loading image to Audio DSP
==========================
`SOF Diagnostic Driver`_ provide interface for firmware loading. Python tools
in the board support directory use the interface to load firmware to ``ADSP``.
Assume that the up_squared board's host name is ``cavs15`` (It also can be an
ip address), and the user account is ``user``. Then copy the python tool to the
``up_squared`` board from your build environment::
$ scp boards/xtensa/intel_adsp/tools/cavstool.py user@cavs15:
$ scp boards/xtensa/intel_adsp/tools/remote-fw-service.py user@cavs15:
Note that the ``/dev/hda`` device file created by the diagnostic driver must
be readable and writable by the process. So we simply by running the
loader script as root:
.. code-block:: console
cavs15$ sudo ./remote-fw-service.py
Cavstool_server.py is a daemon which accepts a firmware image from a remote host
and loads it into the ADSP. After successful firmware download, the daemon also
sends any log messages or output back to the client.
Running and Debugging
=====================
While the python script is running on ``up_squared`` board, you can start load
image and run the application by:
.. code-block:: console
west flash --remote-host cavs15
or
.. code-block:: console
west flash --remote-host 192.168.x.x --pty
Then you can see the log message immediately:
.. code-block:: console
Hello World! intel_adsp_cavs15
Integration Testing With Twister
================================
The ADSP hardware also has integration for testing using the twister
tool. The ``cavstool_client.py`` script can be used as the
``--device-serial-pty`` handler, and the west flash script should take
a path to the same key file used above.
.. code-block:: console
./scripts/twister --device-testing -p intel_adsp_cavs15 \
--device-serial-pty $ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,myboard.local,-l \
--west-flash "--remote-host=myboard.local"
And if you install the SOF software stack in rather than the default path,
you also can specify the location of the rimage tool, signing key and the
toml config, for example:
.. code-block:: console
./scripts/twister --device-testing -p intel_adsp_cavs15 \
--device-serial-pty $ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,myboard.local,-l \
--west-flash "--remote-host=myboard.local,\
--rimage-tool=/path/to/rimage_tool,\
--key=/path/to/otc_private_key.pem,\
--config-dir=/path/to/config_dir"
.. target-notes::
.. _Getting Started with Ubuntu Core on an UP Squared Board: https://software.intel.com/en-us/articles/getting-started-with-ubuntu-core-on-an-up-squared-board
.. _SOF Diagnostic Driver: https://github.com/thesofproject/sof-diagnostic-driver
.. _Sound Open Firmware: https://github.com/thesofproject/sof
.. _rimage Build Instructions: https://github.com/thesofproject/rimage#building
.. _rimage keys: https://github.com/thesofproject/sof/tree/master/rimage/keys
.. _Apollo Lake: https://www.intel.com/content/www/us/en/products/platforms/details/apollo-lake.html

View file

@ -1,307 +0,0 @@
.. _Intel_Adsp_Generic_Running_Guide:
Intel Adsp Generic Running Guide
################################
This documentation describes how to run the intel_adsp_cavs boards. Including:
- intel_adsp_cavs15
- intel_adsp_cavs18
- intel_adsp_cavs20
- intel_adsp_cavs25
Set up the environment
**********************
1. Copy following two tools to the $HOME directory of the target machine (DUT):
- soc/xtensa/intel_adsp/tools/cavstool.py
(The firmware loader)
- soc/xtensa/intel_adsp/tools/remote-fw-service.py
(The remote service provider)
You can use scp command to copy them to DUT, Ex.
.. code-block:: console
$scp boards/xtensa/intel_adsp/tools/cavstool.py user@myboard:~
$scp boards/xtensa/intel_adsp/tools/remote-fw-service.py user@myboard:~
2. In your build machine, install the rimage tool, the signed key and
the toml config file. Please refer to please refer:
https://github.com/thesofproject/rimage.
How Remote Service works
************************
The CAVS remote service runs on the target board and interacts with
west. Two services working on the server:
- Run Sevice
Run Service (or Request Service) works as a flasher. It will receive and
download the firmware to the intel_adsp_cavs boards then starts the Zephyr
Application. It starts at port 10000 by default.
- Log Service
Log Service redirect the remote target board's /dev/tty console. It will
output Zephyr's log message to user via network. It starts at port 9999
by default.
The --remote-host parameter specify the network address which Run Service
provided, and the --pty parameter specifies the network address of log
output service.
Build and run the tests
***********************
1. In the remote target machine, starting the service by:
.. code-block:: console
sudo ./remote-fw-service.py
2. Build the application. Take hello world as an example:
.. code-block:: console
west build -b intel_adsp_cavs15 samples/hello_world
3. Run the test by:
.. code-block:: console
west flash --remote-host {host}:{port} \
--pty {host}:{port}
Ex.
.. code-block:: console
west flash --remote-host 192.168.0.1 --pty
# with specifying the port
west flash --remote-host 192.168.0.1:12345 \
--pty 192.168.0.1:54321
Now you can see the outout log in your terminal.
If you don't want to use the default location of rimage tools, you can
also specify the rimage tool, config and key by:
.. code-block:: console
west flash --remote-host {host}:{port} \
--pty {host}:{port} \
--rimage-tool [path to the rimage tool] \
--config-dir [path to dir of .toml config file] \
--key [path to signing key]
The cavstool server will listen to the available network interfaces on
port 9999 and 10000 by default. In some case you might need to specify
it only listen on a dedicate IP address, or change the default ports
using, you can do it with following parameters:
.. code-block:: console
# with specifying the port
sudo ./remote-fw-service.py --log-port 54321 --req-port 12345
# can be simplified with
sudo ./remote-fw-service -p 54321 -r 12345
# with specifying a IP address
sudo ./remote-fw-service -s 192.168.0.2
# with specifying the IP address with a log port
sudo ./remote-fw-service -s 192.168.0.2:54321
# with specifying the IP, log and request port
sudo ./remote-fw-service -s 192.168.0.2:54321 -r 12345
# Also works in this way
sudo ./remote-fw-service -s 192.168.0.2 -p 54321 -r 12345
Run by twister
**************
For running by twister, the --remote-host parameter needs to be added into
the content of the --west-flash parameter. Assume the IP address of your CAVS
boarad is 192.168.1.2, the port of the Request Service is 12345, the port of
the Log Service is 54321, this is an example of the twister command:
.. code-block:: console
twister -p intel_adsp_cavs25 --device-testing \
--device-serial-pty="$ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.2:54321,-l" \
--west-flash="--remote-host=192.168.1.4:12345"
Like we run tests by west, if you don't want to use the default location of
SOF tools, you can also specify the rimage tool, config and key by:
.. code-block:: console
twister -p intel_adsp_cavs15 --device-testing \
--device-serial-pty="$ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.2:54321,-l" \
--west-flash="--remote-host=192.168.1.2:12345,\
--rimage-tool=$HOME/sof/rimage/rimage,\
--config-dir=$HOME/sof/rimage/config/,\
--key=$HOME/sof/keys/otc_private_key.pem" \
-T tests/kernel/semaphore/semaphore/ -vv
Note that there should be no space between the arguments in --west-flash,
it use comma to separate the parameters.
Run one or multiple boards
**************************
In the above example, there are many parameters need to be keying in when
running by twister. You can reduce it is by writing a hardware map file.
Ruuning twister with the hardware map file also support you running tests
on single/multiple ADSP boards parallelly.
Let see how to use a hardware map file by twister to run a single board,
this is the content of the hardware map file cavs.map:
.. code-block:: console
- connected: true
id: None
platform: intel_adsp_cavs25
product: None
runner: intel_adsp
serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.4,-l"
runner_params:
- --remote-host=192.168.1.4
If you need to specify the port using, you can write the hardware map file
like following example. Assume you have a log port of 54321 and a req port
12345:
.. code-block:: console
- connected: true
id: None
platform: intel_adsp_cavs25
product: None
runner: intel_adsp
serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.4,--log-port,54321,-l"
runner_params:
- --remote-host=192.168.1.4
- --tool-opt=--req-port
- --tool-opt=12345
And another simplified form of the port specifying is to use {host}:{port}
for the --remote-host of the runner params and -s of the serial-pty, Ex.
.. code-block:: console
- connected: true
id: None
platform: intel_adsp_cavs25
product: None
runner: intel_adsp
serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.4:54321,-l"
runner_params:
- --remote-host=192.168.1.4:12345
Then you can run twister with fewer parameters:
.. code-block:: console
twister --hardware-map ./cavs.map --device-testing -T samples/hello_world -vv
And below example of the hardware map file shows you how to run tests in
mulitple boards:
.. code-block:: console
- connected: true
id: None
platform: intel_adsp_cavs15
product: None
runner: intel_adsp
serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.2,-l"
runner_params:
- --remote-host=192.168.1.2
- connected: true
id: None
platform: intel_adsp_cavs18
product: None
runner: intel_adsp
serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.3,-l"
runner_params:
- --remote-host=192.168.1.3
- connected: true
id: None
platform: intel_adsp_cavs25
product: None
runner: intel_adsp
serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.4,-l"
runner_params:
- --remote-host=192.168.1.4
If you don't want to run certain platform in this file, just make
the "connected" field from "true" to "false", it will be skip.
Again, if you don't use the default location of the SOF tools, you
can remove the --rimage-tool, --config-dir and --key in the extra_params
field. For example:
.. code-block:: console
- connected: true
id: None
platform: intel_adsp_cavs25
product: None
runner: intel_adsp
serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.4,-l"
runner_params:
- --remote-host=192.168.1.4
- --rimage-tool=/home/user/sof/rimage/rimage
- --config-dir=/home/user/sof/rimage/config/
- --key=/home/user/sof/keys/otc_private_key_3k.pem
To run multiple boards does also work when specifying the ports.
Passing extra parameter to tools
********************************
wwe can pass parameters to run/require service by the --tool-opt
option. This is for possible extending in the future. For example:
.. code-block:: console
west flash --remote-host=192.168.0.1 --pty=192.168.0.1 \
--tool-opt=--arg='white space' --tool-opt=-r --tool-opt=12345
That means our optional parameters will be parsed as:
.. code-block:: console
['--arg=white space', '-r', '12345']
Then cavs request service tool can get them.

View file

@ -0,0 +1,34 @@
.. _intel_adsp_cavs18:
Intel ADSP CAVS 1.8
###################
Overview
********
This board configuration is used to run Zephyr on the Intel CAVS 1.8 Audio DSP.
This configuration is present, for example, on Intel `Whiskey Lake`_ microprocessors.
Refer to :ref:`intel_adsp_generic` for more details on Intel ADSP ACE and CAVS.
System requirements
*******************
Xtensa Toolchain
----------------
If you choose to build with the Xtensa toolchain instead of the Zephyr SDK, set
the following environment variables specific to the board in addition to the
Xtensa toolchain environment variables listed in :ref:`intel_adsp_generic`.
.. code-block:: shell
export TOOLCHAIN_VER=RG-2017.8-linux
export XTENSA_CORE=X6H3CNL_2017_8
Programming and Debugging
*************************
Refer to :ref:`intel_adsp_generic` for generic instructions on programming and
debugging applicable to all CAVS and ACE platforms.
.. _Whiskey Lake: https://www.intel.com/content/www/us/en/products/platforms/details/whiskey-lake.html

View file

@ -0,0 +1,417 @@
:orphan:
.. _zephyr-audio-dsp-development-on-chromebooks:
Zephyr Audio DSP Development on Chromebooks
###########################################
The Audio DSP on Intel Chromebooks is configured to use the SOF
"Community" key for firmware signing, and can therefore accept
arbitrary user-developed firmware like Zephyr applications (of which
SOF is one), including the Zephyr samples and test suite.
Initial TGL Chromebook Setup
****************************
(These instructions were written specifically to the Asus Flip CX5
device code named "delbin". But they should be reasonably applicable
to any recent Intel device.)
Power the device on and connect it to a wireless network. It will
likely want to download a firmware update (mine did). Let this finish
first, to ensure you have two working OS images.
Enable Developer Mode
=====================
Power the device off (menu in lower right, or hold the power button
on the side)
Hold Esc + Refresh (the arrow-in-a-circle "reload" key above "3") and
hit the power key to enter recovery mode. Note: the touchscreen and
pad don't work in recovery mode, use the arrow keys to navigate.
Select "Advanced Options", then "Enable Developer Mode" and confirm
that you really mean it. Select "Boot from Internal Storage" at the
bootloader screen. You will see this screen every time the machine
boots now, telling you that the boot is unverified.
Wait while the device does the required data wipe. My device takes
about 15 minutes to completely write the stateful partition. On
reboot, select "Boot from Internal Storage" again and set it up
(again) with Google account.
Make a Recovery Drive
=====================
You will at some point wreck your device and need a recovery stick.
Install the Chromebook Recovery Utility from the Google Web Store and
make one.
You can actually do this on any machine (and any OS) with Chrome
installed, but it's easiest on the Chromebook because it knows its
device ID (for example "DELBIN-XHVI D4B-H4D-G4G-Q9A-A9P" for the Asus
Tiger Lake board). Note that recovery, when it happens, will not
affect developer mode or firmware settings but it **will wipe out the
root filesystem and /usr/local customizations you have made**. So
plan on a strategy that can tolerate data loss on the device you're
messing with!
Make the root filesystem writable
=================================
For security, ChromeOS signs and cryptographically verifies (using
Linux's dm-verity feature) all access to the read-only root
filesystem. Mucking with the rootfs (for example, to install modules
for a custom kernel) requires that the dm-verity layer be turned off:
First open a terminal with Ctrl-Alt-T. Then at the "crosh> " prompt
issue the "shell" command to get a shell running as the "chronos"
user. Finally (in developer mode) a simple "sudo su -" will get you a
root prompt.
.. code-block:: console
crosh> shell
chronos@localhost / $ sudo su -
localhost ~ #
Now you need to turn of signature verification in the bootloader
(because obviously we'll be breaking whatever signature existed).
Note that signature verification is something done by the ROM
bootloader, not the OS, and this setting is a (developer-mode-only)
directive to that code:
.. code-block:: console
cros# crossystem dev_boot_signed_only=0
(*Note: for clarity, commands in this document entered at the ChromeOS
core shell will be prefixed with a hostname of cros.*)
Next you disable the validation step:
.. code-block:: console
cros# /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification
**THIS COMMAND WILL FAIL**, give you an error that you are changing
the setting for the entire running system, and suggest an alternative
"--partitions X" argument to use that modifies only the currently used
partition. Run that modified command, then reboot.
After rebooting, you will notice that your chromebook boots with the
raw storage device (e.g. /dev/nvme0n1p5) mounted as root and not the
"dm-0" verity device, and that the rootfs is read-write.
Note: What this command actually does is modify the command line of
the installed kernel image (it saves a backup in
/mnt/stateful_partition/cros_sign_backups) so that it specifies
"root=<guid>" and not "root=dm-0". It does seem to leave the other
verity configuration in place though, it just doesn't try to mount the
resulting (now-invalid!) partition.
Metanote: The astute will note that we're probably going to throw this
kernel out, and that we could probably have just edited the command
line of the new kernel instead of flashing and rebooting into this
modified one. But that's too many balls to juggle at once for me.
Enable ChromeOS SSH
===================
Once you are booted with a writable partition, you can turn on the
built-in ssh server with:
.. code-block:: console
cros# /usr/libexec/debugd/helpers/dev_features_ssh
By default neither the "chronos" user nor root accounts have
passwords, so unless you want to type a ssh key in by hand, you
probably want to set a password for the first login (before you run
ssh-copy-id, of course):
.. code-block:: console
cros# passwd
Now ssh into the chromebook and add your key to
``.ssh/authorized_keys`` as you do for any Linux system.
Install Crouton
***************
The Zephyr integration tools require a proper Linux environment and
won't run on ChromeOS's minimal distro. So we need to install a Linux
personality. **DO NOT** bother installing the "Linux Development
Environment" (Crostini) from the ChromeOS Developer settings. This
personality runs inside a VM, where our tools need access to the real
kernel running on the real hardware. Instead install Crouton
(https://github.com/dnschneid/crouton), which is a community
chroot-based personality that preserves access to the real hardware
sysfs and /dev filesystem. These instructions install the "cli-extra"
package list, there are X11-enabled ones available too if you prefer
to work on the device screen directly. See the project page, etc...
At a root shell, grab the installer and run it (note: /usr/local is
the only writable filesystem without noexec, you must place the binary
there for it to run!):
.. code-block:: console
cros# mkdir -p /usr/local/bin
cros# curl -L https://github.com/dnschneid/crouton/raw/master/installer/crouton \
> /usr/local/bin/crouton
cros# chmod 755 /usr/local/bin/crouton
cros# crouton -r focal -t cli-extra
Start the Crouton chroot environment:
.. code-block:: console
cros# startcli
Now you are typing commands into the Ubuntu environment. Enable
inbound ssh on Crouton, but on a port other than 22 (which is used for
the native ChromeOS ssh server). I'm using 222 here (which is easy to
remember, and not a registered port in /etc/services):
.. code-block:: console
crouton# apt install iptables openssh-server
crouton# echo "Port 222" >> /etc/ssh/sshd_config
crouton# mkdir /run/sshd
crouton# iptables -I INPUT -p tcp --dport 222 -j ACCEPT
crouton# /usr/sbin/sshd
(*As above: note that we have introduced a hostname of "crouton" to
refer to the separate Linux personality.*)
NOTE: the mkdir, iptables and sshd commands need to be run every time
the chroot is restarted. You can put them in /etc/rc.local for
convenience. Crouton doesn't run systemd (because it can't -- it
doesn't own the system!) so Ubuntu services like openssh-server don't
know how to start themselves.
Building and Installing a Custom Kernel
***************************************
On your build host, grab a copy of the ChromeOS kernel tree. The
shipping device is using a 5.4 kernel, but the 5.10 tree works for me
and seems to have been backporting upstream drivers such that its main
hardware is all quite recent (5-6 weeks behind mainline or so). We
place it in the home directory here for simplicity:
.. code-block:: console
dev$ cd $HOME
dev$ git clone https://chromium.googlesource.com/chromiumos/third_party/kernel
dev$ cd kernel
dev$ git checkout chromeos-5.10
(*Once again, we are typing into a different shell. We introduce the
hostname "dev" here to represent the development machine on which you
are building kernels and Zephyr apps. It is possible to do this on the
chromebook directly, but not advisable. Remember the discussion above
about requiring a drive wipe on system recovery!*)
Note: you probably have an existing Linux tree somewhere already. If
you do it's much faster to add this as a remote there and just fetch
the deltas -- ChromeOS tracks upstream closely.
Now you need a .config file. The Chromebook kernel ships with the
"configs" module built which exposes this in the running kernel. You
just have to load the module and read the file.
.. code-block:: console
dev$ cd /path/to/kernel
dev$ ssh root@cros modprobe configs
dev$ ssh root@cros zcat /proc/config.gz > .config
You will need to set some custom configuration variables differently
from ChromeOS defaults (you can edit .config directly, or use
menuconfig, etc...):
+ ``CONFIG_HUGETLBFS=y`` - The Zephyr loader tool requires this
+ ``CONFIG_EXTRA_FIRMWARE_DIR=n`` - This refers to a build directory
in Google's build environment that we will not have.
+ ``CONFIG_SECURITY_LOADPIN=n`` - Pins modules such that they will
only load from one filesystem. Annoying restriction for custom
kernels.
+ ``CONFIG_MODVERSIONS=n`` - Allow modules to be built and installed
from modified "dirty" build trees.
Now build your kernel just as you would any other:
.. code-block:: console
dev$ make olddefconfig # Or otherwise update .config
dev$ make bzImage modules # Probably want -j<whatever> for parallel build
The modules you can copy directly to the (now writable) rootfs on the
device. Note that this filesystem has very limited space (it's
intended to be read only), so the INSTALL_MOD_STRIP=1 is absolutely
required, and you may find you need to regularly prune modules from
older kernels to make space:
.. code-block:: console
dev$ make INSTALL_MOD_PATH=mods INSTALL_MOD_STRIP=1 modules_install
dev$ (cd mods/lib/modules; tar cf - .) | ssh root@cros '(cd /lib/modules; tar xfv -)'
Pack and Install ChromeOS Kernel Image
======================================
The kernel bzImage file itself needs to be signed and packaged into a
ChromeOS vboot package and written directly to the kernel partition.
Thankfully the tools to do this are shipped in Debian/Ubuntu
repositories already:
.. code-block:: console
$ sudo apt install vboot-utils vboot-kernel-utils
Find the current kernel partition on the device. You can get this by
comparing the "kernel_guid" command line parameter (passed by the
bootloader) with the partition table of the boot drive, for example:
.. code-block:: console
dev$ KPART=`ssh root@cros 'fdisk -l -o UUID,Device /dev/nvme0n1 | \
grep -i $(sed "s/.*kern_guid=//" /proc/cmdline \
| sed "s/ .*//") \
| sed "s/.* //"'`
dev$ echo $KPART
/dev/nvme0n1p4
Extract the command line from that image into a local file:
.. code-block:: console
dev$ ssh root@cros vbutil_kernel --verify /dev/$KPART | tail -1 > cmdline.txt
Now you can pack a new kernel image using the vboot tooling. Most of
these arguments are boilerplate and always the same. The keys are
there because the boot requires a valid signature, even though as
configured it won't use it. Note the cannot-actually-be-empty dummy
file passed as a "bootloader", which is a holdover from previous ROM
variants which needed an EFI stub.
.. code-block:: console
dev$ echo dummy > dummy.efi
dev$ vbutil_kernel --pack kernel.img --config cmdline.txt \
--vmlinuz arch/x86_64/boot/bzImage \
--keyblock /usr/share/vboot/devkeys/kernel.keyblock \
--signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \
--version 1 --bootloader dummy.efi --arch x86_64
You can verify this image if you like with "vbutil_kernel --verify".
Now just copy up the file and write it to the partition on the device:
.. code-block:: console
$ scp kernel.img root@cros:/tmp
$ ssh root@cros dd if=/tmp/kernel.img of=/dev/nvme0n1p4
Now reboot, and if all goes well you will find yourself running in
your new kernel.
Wifi Firmware Fixup
===================
On the Tiger Lake Chromebook, the /lib/firmware tree is a bit stale
relative to the current 5.10 kernel. The iwlwifi driver requests a
firmware file that doesn't exist, leading to a device with no network.
It's a simple problem, but a catastrophic drawback if uncorrected. It
seems to be sufficient just to link the older version to the new name.
(It would probably be better to copy the proper version from
/lib/firmware from a recent kernel.org checkout.):
.. code-block:: console
cros# cd /lib/firmware
cros# ln -s iwlwifi-QuZ-a0-hr-b0-62.ucode iwlwifi-QuZ-a0-hr-b0-64.ucode
Build and Run a Zephyr Application
**********************************
Finally, with your new kernel booted, you are ready to run Zephyr
code.
Build rimage Signing Tool
=========================
First download and build a copy of the Sound Open Firmware "rimage"
tool (these instructions put it in your home directory for clarity,
but anywhere is acceptable):
.. code-block:: console
dev$ cd $HOME
dev$ git clone https://github.com/thesofproject/rimage
dev$ cd rimage/
dev$ git submodule init
dev$ git submodule update
dev$ cmake .
dev$ make
Copy Integration Scripting to Chromebook
========================================
There is a python scripts needed on the device, to be run inside
the Crouton environment installed above. Copy them:
.. code-block:: console
dev$ scp boards/xtensa/intel_adsp_cavs15/tools/cavstool.py user@crouton:
Then start the service in the Crouton environment:
.. code-block:: console
crouton$ sudo ./cavstool.py user@crouton:
Build and Sign Zephyr App
=========================
Zephyr applications build conventionally for this platform, and are
signed with "west flash" with just a few extra arguments. Note that
the key in use for the Tiger Lake DSP is the "3k" key from SOF, not
the original that is used with older hardware. The output artifact is
a "zephyr.ri" file to be copied to the device.
.. code-block:: console
dev$ west build -b intel_adsp_cavs25 samples/hello_world
dev$ west sign --tool-data=~/rimage/config -t ~/rimage/rimage -- \
-k $ZEPHYR_BASE/../modules/audio/sof/keys/otc_private_key_3k.pem
Run it!
=======
The loader script takes the signed rimage file as its argument. Once
it reports success, the application begins running immediately and its
console output (in the SOF shared memory trace buffer) can be read by
the logging script.
.. code-block:: console
dev$ west flash --remote-host crouton
Hello World! intel_adsp_cavs25
Misc References
***************
Upstream documentation from which these instructions were drawn:
This page has the best reference for the boot process:
http://www.chromium.org/chromium-os/chromiumos-design-docs/disk-format
This is great too, with an eye toward booting things other than ChromeOS:
https://www.chromium.org/chromium-os/developer-information-for-chrome-os-devices/custom-firmware

View file

@ -1,415 +1,34 @@
.. _zephyr-audio-dsp-development-on-chromebooks:
.. _intel_adsp_cavs25:
Zephyr Audio DSP Development on Chromebooks
###########################################
Intel ADSP CAVS 2.5
###################
The Audio DSP on Intel Chromebooks is configured to use the SOF
"Community" key for firmware signing, and can therefore accept
arbitrary user-developed firmware like Zephyr applications (of which
SOF is one), including the Zephyr samples and test suite.
Overview
********
Initial TGL Chromebook Setup
****************************
This board configuration is used to run Zephyr on the Intel CAVS 2.5 Audio DSP.
This configuration is present, for example, on Intel `Tiger Lake`_ microprocessors.
Refer to :ref:`intel_adsp_generic` for more details on Intel ADSP ACE and CAVS.
(These instructions were written specifically to the Asus Flip CX5
device code named "delbin". But they should be reasonably applicable
to any recent Intel device.)
System requirements
*******************
Power the device on and connect it to a wireless network. It will
likely want to download a firmware update (mine did). Let this finish
first, to ensure you have two working OS images.
Xtensa Toolchain
----------------
Enable Developer Mode
=====================
If you choose to build with the Xtensa toolchain instead of the Zephyr SDK, set
the following environment variables specific to the board in addition to the
Xtensa toolchain environment variables listed in :ref:`intel_adsp_generic`.
Power the device off (menu in lower right, or hold the power button
on the side)
.. code-block:: shell
Hold Esc + Refresh (the arrow-in-a-circle "reload" key above "3") and
hit the power key to enter recovery mode. Note: the touchscreen and
pad don't work in recovery mode, use the arrow keys to navigate.
export TOOLCHAIN_VER=RG-2017.8-linux
export XTENSA_CORE=cavs2x_LX6HiFi3_2017_8
Select "Advanced Options", then "Enable Developer Mode" and confirm
that you really mean it. Select "Boot from Internal Storage" at the
bootloader screen. You will see this screen every time the machine
boots now, telling you that the boot is unverified.
Programming and Debugging
*************************
Wait while the device does the required data wipe. My device takes
about 15 minutes to completely write the stateful partition. On
reboot, select "Boot from Internal Storage" again and set it up
(again) with Google account.
Refer to :ref:`intel_adsp_generic` for generic instructions on programming and
debugging applicable to all CAVS and ACE platforms.
Make a Recovery Drive
=====================
You will at some point wreck your device and need a recovery stick.
Install the Chromebook Recovery Utility from the Google Web Store and
make one.
You can actually do this on any machine (and any OS) with Chrome
installed, but it's easiest on the Chromebook because it knows its
device ID (for example "DELBIN-XHVI D4B-H4D-G4G-Q9A-A9P" for the Asus
Tiger Lake board). Note that recovery, when it happens, will not
affect developer mode or firmware settings but it **will wipe out the
root filesystem and /usr/local customizations you have made**. So
plan on a strategy that can tolerate data loss on the device you're
messing with!
Make the root filesystem writable
=================================
For security, ChromeOS signs and cryptographically verifies (using
Linux's dm-verity feature) all access to the read-only root
filesystem. Mucking with the rootfs (for example, to install modules
for a custom kernel) requires that the dm-verity layer be turned off:
First open a terminal with Ctrl-Alt-T. Then at the "crosh> " prompt
issue the "shell" command to get a shell running as the "chronos"
user. Finally (in developer mode) a simple "sudo su -" will get you a
root prompt.
.. code-block:: console
crosh> shell
chronos@localhost / $ sudo su -
localhost ~ #
Now you need to turn of signature verification in the bootloader
(because obviously we'll be breaking whatever signature existed).
Note that signature verification is something done by the ROM
bootloader, not the OS, and this setting is a (developer-mode-only)
directive to that code:
.. code-block:: console
cros# crossystem dev_boot_signed_only=0
(*Note: for clarity, commands in this document entered at the ChromeOS
core shell will be prefixed with a hostname of cros.*)
Next you disable the validation step:
.. code-block:: console
cros# /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification
**THIS COMMAND WILL FAIL**, give you an error that you are changing
the setting for the entire running system, and suggest an alternative
"--partitions X" argument to use that modifies only the currently used
partition. Run that modified command, then reboot.
After rebooting, you will notice that your chromebook boots with the
raw storage device (e.g. /dev/nvme0n1p5) mounted as root and not the
"dm-0" verity device, and that the rootfs is read-write.
Note: What this command actually does is modify the command line of
the installed kernel image (it saves a backup in
/mnt/stateful_partition/cros_sign_backups) so that it specifies
"root=<guid>" and not "root=dm-0". It does seem to leave the other
verity configuration in place though, it just doesn't try to mount the
resulting (now-invalid!) partition.
Metanote: The astute will note that we're probably going to throw this
kernel out, and that we could probably have just edited the command
line of the new kernel instead of flashing and rebooting into this
modified one. But that's too many balls to juggle at once for me.
Enable ChromeOS SSH
===================
Once you are booted with a writable partition, you can turn on the
built-in ssh server with:
.. code-block:: console
cros# /usr/libexec/debugd/helpers/dev_features_ssh
By default neither the "chronos" user nor root accounts have
passwords, so unless you want to type a ssh key in by hand, you
probably want to set a password for the first login (before you run
ssh-copy-id, of course):
.. code-block:: console
cros# passwd
Now ssh into the chromebook and add your key to
``.ssh/authorized_keys`` as you do for any Linux system.
Install Crouton
***************
The Zephyr integration tools require a proper Linux environment and
won't run on ChromeOS's minimal distro. So we need to install a Linux
personality. **DO NOT** bother installing the "Linux Development
Environment" (Crostini) from the ChromeOS Developer settings. This
personality runs inside a VM, where our tools need access to the real
kernel running on the real hardware. Instead install Crouton
(https://github.com/dnschneid/crouton), which is a community
chroot-based personality that preserves access to the real hardware
sysfs and /dev filesystem. These instructions install the "cli-extra"
package list, there are X11-enabled ones available too if you prefer
to work on the device screen directly. See the project page, etc...
At a root shell, grab the installer and run it (note: /usr/local is
the only writable filesystem without noexec, you must place the binary
there for it to run!):
.. code-block:: console
cros# mkdir -p /usr/local/bin
cros# curl -L https://github.com/dnschneid/crouton/raw/master/installer/crouton \
> /usr/local/bin/crouton
cros# chmod 755 /usr/local/bin/crouton
cros# crouton -r focal -t cli-extra
Start the Crouton chroot environment:
.. code-block:: console
cros# startcli
Now you are typing commands into the Ubuntu environment. Enable
inbound ssh on Crouton, but on a port other than 22 (which is used for
the native ChromeOS ssh server). I'm using 222 here (which is easy to
remember, and not a registered port in /etc/services):
.. code-block:: console
crouton# apt install iptables openssh-server
crouton# echo "Port 222" >> /etc/ssh/sshd_config
crouton# mkdir /run/sshd
crouton# iptables -I INPUT -p tcp --dport 222 -j ACCEPT
crouton# /usr/sbin/sshd
(*As above: note that we have introduced a hostname of "crouton" to
refer to the separate Linux personality.*)
NOTE: the mkdir, iptables and sshd commands need to be run every time
the chroot is restarted. You can put them in /etc/rc.local for
convenience. Crouton doesn't run systemd (because it can't -- it
doesn't own the system!) so Ubuntu services like openssh-server don't
know how to start themselves.
Building and Installing a Custom Kernel
***************************************
On your build host, grab a copy of the ChromeOS kernel tree. The
shipping device is using a 5.4 kernel, but the 5.10 tree works for me
and seems to have been backporting upstream drivers such that its main
hardware is all quite recent (5-6 weeks behind mainline or so). We
place it in the home directory here for simplicity:
.. code-block:: console
dev$ cd $HOME
dev$ git clone https://chromium.googlesource.com/chromiumos/third_party/kernel
dev$ cd kernel
dev$ git checkout chromeos-5.10
(*Once again, we are typing into a different shell. We introduce the
hostname "dev" here to represent the development machine on which you
are building kernels and Zephyr apps. It is possible to do this on the
chromebook directly, but not advisable. Remember the discussion above
about requiring a drive wipe on system recovery!*)
Note: you probably have an existing Linux tree somewhere already. If
you do it's much faster to add this as a remote there and just fetch
the deltas -- ChromeOS tracks upstream closely.
Now you need a .config file. The Chromebook kernel ships with the
"configs" module built which exposes this in the running kernel. You
just have to load the module and read the file.
.. code-block:: console
dev$ cd /path/to/kernel
dev$ ssh root@cros modprobe configs
dev$ ssh root@cros zcat /proc/config.gz > .config
You will need to set some custom configuration variables differently
from ChromeOS defaults (you can edit .config directly, or use
menuconfig, etc...):
+ ``CONFIG_HUGETLBFS=y`` - The Zephyr loader tool requires this
+ ``CONFIG_EXTRA_FIRMWARE_DIR=n`` - This refers to a build directory
in Google's build environment that we will not have.
+ ``CONFIG_SECURITY_LOADPIN=n`` - Pins modules such that they will
only load from one filesystem. Annoying restriction for custom
kernels.
+ ``CONFIG_MODVERSIONS=n`` - Allow modules to be built and installed
from modified "dirty" build trees.
Now build your kernel just as you would any other:
.. code-block:: console
dev$ make olddefconfig # Or otherwise update .config
dev$ make bzImage modules # Probably want -j<whatever> for parallel build
The modules you can copy directly to the (now writable) rootfs on the
device. Note that this filesystem has very limited space (it's
intended to be read only), so the INSTALL_MOD_STRIP=1 is absolutely
required, and you may find you need to regularly prune modules from
older kernels to make space:
.. code-block:: console
dev$ make INSTALL_MOD_PATH=mods INSTALL_MOD_STRIP=1 modules_install
dev$ (cd mods/lib/modules; tar cf - .) | ssh root@cros '(cd /lib/modules; tar xfv -)'
Pack and Install ChromeOS Kernel Image
======================================
The kernel bzImage file itself needs to be signed and packaged into a
ChromeOS vboot package and written directly to the kernel partition.
Thankfully the tools to do this are shipped in Debian/Ubuntu
repositories already:
.. code-block:: console
$ sudo apt install vboot-utils vboot-kernel-utils
Find the current kernel partition on the device. You can get this by
comparing the "kernel_guid" command line parameter (passed by the
bootloader) with the partition table of the boot drive, for example:
.. code-block:: console
dev$ KPART=`ssh root@cros 'fdisk -l -o UUID,Device /dev/nvme0n1 | \
grep -i $(sed "s/.*kern_guid=//" /proc/cmdline \
| sed "s/ .*//") \
| sed "s/.* //"'`
dev$ echo $KPART
/dev/nvme0n1p4
Extract the command line from that image into a local file:
.. code-block:: console
dev$ ssh root@cros vbutil_kernel --verify /dev/$KPART | tail -1 > cmdline.txt
Now you can pack a new kernel image using the vboot tooling. Most of
these arguments are boilerplate and always the same. The keys are
there because the boot requires a valid signature, even though as
configured it won't use it. Note the cannot-actually-be-empty dummy
file passed as a "bootloader", which is a holdover from previous ROM
variants which needed an EFI stub.
.. code-block:: console
dev$ echo dummy > dummy.efi
dev$ vbutil_kernel --pack kernel.img --config cmdline.txt \
--vmlinuz arch/x86_64/boot/bzImage \
--keyblock /usr/share/vboot/devkeys/kernel.keyblock \
--signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \
--version 1 --bootloader dummy.efi --arch x86_64
You can verify this image if you like with "vbutil_kernel --verify".
Now just copy up the file and write it to the partition on the device:
.. code-block:: console
$ scp kernel.img root@cros:/tmp
$ ssh root@cros dd if=/tmp/kernel.img of=/dev/nvme0n1p4
Now reboot, and if all goes well you will find yourself running in
your new kernel.
Wifi Firmware Fixup
===================
On the Tiger Lake Chromebook, the /lib/firmware tree is a bit stale
relative to the current 5.10 kernel. The iwlwifi driver requests a
firmware file that doesn't exist, leading to a device with no network.
It's a simple problem, but a catastrophic drawback if uncorrected. It
seems to be sufficient just to link the older version to the new name.
(It would probably be better to copy the proper version from
/lib/firmware from a recent kernel.org checkout.):
.. code-block:: console
cros# cd /lib/firmware
cros# ln -s iwlwifi-QuZ-a0-hr-b0-62.ucode iwlwifi-QuZ-a0-hr-b0-64.ucode
Build and Run a Zephyr Application
**********************************
Finally, with your new kernel booted, you are ready to run Zephyr
code.
Build rimage Signing Tool
=========================
First download and build a copy of the Sound Open Firmware "rimage"
tool (these instructions put it in your home directory for clarity,
but anywhere is acceptable):
.. code-block:: console
dev$ cd $HOME
dev$ git clone https://github.com/thesofproject/rimage
dev$ cd rimage/
dev$ git submodule init
dev$ git submodule update
dev$ cmake .
dev$ make
Copy Integration Scripting to Chromebook
========================================
There is a python scripts needed on the device, to be run inside
the Crouton environment installed above. Copy them:
.. code-block:: console
dev$ scp boards/xtensa/intel_adsp_cavs15/tools/cavstool.py user@crouton:
Then start the service in the Crouton environment:
.. code-block:: console
crouton$ sudo ./cavstool.py user@crouton:
Build and Sign Zephyr App
=========================
Zephyr applications build conventionally for this platform, and are
signed with "west flash" with just a few extra arguments. Note that
the key in use for the Tiger Lake DSP is the "3k" key from SOF, not
the original that is used with older hardware. The output artifact is
a "zephyr.ri" file to be copied to the device.
.. code-block:: console
dev$ west build -b intel_adsp_cavs25 samples/hello_world
dev$ west sign --tool-data=~/rimage/config -t ~/rimage/rimage -- \
-k $ZEPHYR_BASE/../modules/audio/sof/keys/otc_private_key_3k.pem
Run it!
=======
The loader script takes the signed rimage file as its argument. Once
it reports success, the application begins running immediately and its
console output (in the SOF shared memory trace buffer) can be read by
the logging script.
.. code-block:: console
dev$ west flash --remote-host crouton
Hello World! intel_adsp_cavs25
Misc References
***************
Upstream documentation from which these instructions were drawn:
This page has the best reference for the boot process:
http://www.chromium.org/chromium-os/chromiumos-design-docs/disk-format
This is great too, with an eye toward booting things other than ChromeOS:
https://www.chromium.org/chromium-os/developer-information-for-chrome-os-devices/custom-firmware
.. _Tiger Lake: https://www.intel.com/content/www/us/en/products/platforms/details/tiger-lake-h.html

View file

@ -0,0 +1,340 @@
:orphan:
.. _intel_adsp_generic:
Intel ADSP CAVS and ACE
#######################
Intel's Audio and Digital Signal Processing (ADSP) hardware offerings
include the Converged Audio Video Sensing (CAVS) series and its successor,
the Audio and Context Engine (ACE). These Xtensa-based ADSPs can be integrated
into a variety of Intel products. The below table lists (some of) the Intel
microprocessor(s) that each version of the Intel ADSP is compatible with.
+----------+-----------------------------+
| ADSP | Microprocessor |
+==========+=============================+
| CAVS 1.5 | Apollo Lake |
+----------+-----------------------------+
| CAVS 1.8 | Whiskey Lake |
+----------+-----------------------------+
| CAVS 2.5 | Tiger Lake |
+----------+-----------------------------+
| ACE 1.5 | Meteor Lake |
+----------+-----------------------------+
Intel open-sources firmware for its ADSP hardware under the Sound Open Firmware
(`SOF`_) project. SOF can be built with either Zephyr or Cadence's proprietary
Xtensa OS (XTOS) and run on a variety of Intel and non-Intel platforms.
In general, the Intel `UP2`_ and `UP Xtreme`_ product lines are the publicly
available reference boards for Zephyr's Intel ADSP support. This guide uses the
`UP Xtreme i11-0001 series`_ (:ref:`intel_adsp_cavs25`) board as an example.
However, the instructions are generic and will work on other boards unless
otherwise stated. You will be referred to the documentation for your specific
board in these cases.
System requirements
*******************
Setting Up Target Board
-----------------------
You can only flash Zephyr to the ADSP by using Zephyr's Python tool in a Linux
host running on the board's main CPU. It is possible (and recommended) for users
to build the binary locally on their development machine and flash remotely,
but the board itself must be capable of running the Python script that receives
the binary sent over the network by West and flashes it. You should install a
version of Linux that supports or comes with the current version of Python that
Zephyr requires. Consider using Ubuntu 20.04, which comes with Python 3.8
installed.
Note that if you plan to use SOF on your board, you will need to build and
install the modified Linux SOF kernel instead of the default kernel. It is
recommended you follow the `SOF instructions`_ to build and run SOF on Zephyr.
UP2 and UP Xtreme users can refer to the `UP Community wiki`_ for help installing a
Linux operating system on their board.
Signing Tool
------------
As firmware binary signing is mandatory on Intel products from Skylake onwards,
you will also need to set up the SOF rimage signing tool and key.
.. code-block:: shell
cd zephyrproject/modules/audio/sof/
git clone https://github.com/thesofproject/rimage --recurse-submodules
cd rimage
Follow the instructions in the :file:`README.md` to build and install the tool
globally on your system. You should be able to invoke the binary from the
command line with the name "rimage". For example:
.. code-block:: shell
which rimage
/usr/local/bin/rimage
If you are unable to install it, you can also pass the path to the tool binary
as an argument to ``west flash``, though this is not recommended.
Xtensa Toolchain (Optional)
---------------------------
The Zephyr SDK provides GCC-based toolchains necessary to build Zephyr for
the CAVS and ACE boards. However, users seeking greater levels of optimization
may desire to build with the proprietary Xtensa toolchain distributed by
`Cadence`_ instead. The following instructions assume you have purchased and
installed the toolchain(s) and core(s) for your board following their
instructions.
First, make sure to set ``XTENSAD_LICENSE_FILE`` as instructed by Cadence.
Next, set the following environment variables:
.. code-block:: shell
export XTENSA_TOOLCHAIN_PATH=$HOME/xtensa/XtDevTools/install/tools
export XTENSA_BUILDS_DIR=$XTENSA_TOOLCHAIN_PATH/../builds
export ZEPHYR_TOOLCHAIN_VARIANT=xcc
export TOOLCHAIN_VER=RG-2017.8-linux
export XTENSA_CORE=cavs2x_LX6HiFi3_2017_8
The bottom three variables are specific to each version of CAVS / ACE; refer to
your board's documentation for their values.
Programming and Debugging
*************************
Building
--------
Build as usual.
.. zephyr-app-commands::
:zephyr-app: samples/hello_world
:board: intel_adsp_cavs25
:goals: build
Signing
-------
West automatically signs the binary as the first step of flashing, but if you
need to sign the binary yourself without flashing, you can invoke the west sign
command directly. Read the output of a ``west flash`` command to find the
``west sign`` invocation. You can copy and modify it for your own purposes.
As mentioned previously, if you're unable to install the rimage tool
globally, you can pass it the path to the tool binary as an argument to
``west flash`` if the flash target exists for your board. To see a list
of all arguments to the Intel ADSP runner, run the following after you have
built the binary. There are multiple arguments related to signing, including a
key argument.
.. code-block:: console
west flash --context
Remote Flashing to CAVS-based ADSP
----------------------------------
As mentioned previously, the recommended way to run and monitor the output of
Zephyr on CAVS boards is remotely. The Linux host on the main CPU may freeze up
and need to be restarted if a flash or runtime error occurs on the ADSP. From
this point onward, we will refer to the board as the "remote host" and your
development machine as the "local host".
Copy the below scripts to the CAVS board.
:zephyr_file:`soc/xtensa/intel_adsp/tools/remote-fw-service.py` will receive
the binary sent over the network by West and invoke
:zephyr_file:`soc/xtensa/intel_adsp/tools/cavstool.py` (referred to as the
"CAVS tool"), which performs the flash and captures the log. Start
:file:`remote-fw-service.py`.
.. code-block:: console
scp -r $ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool.py username@remotehostname
scp -r $ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/remote-fw-service.py username@remotehostname
ssh username@remotehostname
sudo ./remote-fw-service.py
:file:`remote-fw-service.py` uses ports 9999 and 10000 on the remote host to
communicate. It forwards logs collected by :file:`cavstool.py` on port 9999
(referred to as its "log port") and services requests on port 10000
(its "requests port"). When you run West or Twister on your local host,
it sends requests using the :zephyr_file:`soc/xtensa/intel_adsp/tools/cavstool_client.py`
script (referred to as "CAVS tool client"). It also uses ports 9999 and 10000 on
your local host, so be sure those ports are free.
Flashing with West is simple.
.. code-block:: console
west flash --remote-host remotehostname --pty remotehostname
Running tests with Twister is slightly more complicated.
.. code-block:: console
twister -p intel_adsp_cavs25 --device-testing --device-serial-pty="$ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,remotehostname,-l" --west-flash="--remote-host=remotehostname" -T samples/hello_world
If your network is set up such that the TCP connection from
:file:`cavstool_client.py` to :file:`remote-fw-service.py` is forwarded through
an intermediate host, you may need to tell :file:`cavstool_client.py` to connect
to different ports as well as a different hostname. You can do this by appending
the port numbers to the intermediate host name.
.. code-block:: console
west flash --remote-host intermediatehost:reqport --pty remotehostname:logport
twister -p intel_adsp_cavs25 --device-testing --device-serial-pty="$ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,remotehostname:logport,-l" --west-flash="--remote-host=remotehostname:reqport" -T samples/hello_world
You can also save this information to a hardware map file and pass that to
Twister.
.. code-block:: console
twister -p intel_adsp_cavs25 --hardware-map cavs.map --device-testing -T samples/hello_world
Here's a sample ``cavs.map``:
.. code-block:: console
- connected: true
id: None
platform: intel_adsp_cavs25
product: None
runner: intel_adsp
serial_pty: "/home/zephyrus/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,remotehostname:logport,-l"
runner_params:
- --remote-host=remotehostname:reqport
Any of the arguments you would pass to Twister or West, you can pass with the
hardware map. As mentioned previously, you can see the Intel ADSP runner
arguments by passing the ``--context`` flag while flashing with West.
Refer to :ref:`twister_script` for more information on hardware maps.
Local Flashing to CAVS-based ADSP
---------------------------------
You can also directly flash the signed binary with the CAVS tool on the board.
This may be useful for debugging.
.. code-block:: console
sudo ./cavstool.py zephyr.ri
You should see the following at the end of the log if you are successful:
.. code-block:: console
***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx *****
Hello World! intel_adsp_cavs25
Flashing to ACE-based ADSP
--------------------------
Flashing is not yet supported for platforms with ACE-based ADSP, as these
platforms are not yet publicly available.
Debugging
---------
As Zephyr doesn't (yet) support GDB for the Intel ADSP platforms, users are
recommended to take advantage of Zephyr's built-in :ref:`coredump` and
:ref:`logging_api` features.
Troubleshooting
***************
You can pass verbose flags directly to the Intel ADSP scripts:
.. code-block:: console
sudo ./remote-fw-service.py -v
sudo ./cavstool.py zephyr.ri -v
To see a list of their arguments:
.. code-block:: console
sudo ./remote-fw-service.py --help
sudo ./cavstool.py --help
If flashing fails at ``west sign`` with errors related to unparsed keys, try
reinstalling the latest version of the signing tool. For example:
.. code-block:: shell
error: 1 unparsed keys left in 'adsp'
error: 1 unparsed arrays left in 'adsp'
If you get an "Address already in use" error when starting
:file:`remote-fw-service.py` on the board, you may have another instance of the
script running. Kill it.
.. code-block:: console
$ sudo netstat -peanut | grep 9999
tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN 0 289788 14795/python3
$ sudo kill 14795
If West or Twister successfully sign and establish TCP connections
with :file:`remote-fw-service.py` but hang with no output afterwards,
there are two possibilities: either :file:`remote-fw-service.py` failed
to communicate, or :file:`cavstool.py` failed to flash. Log into
the remote host and check the output of :file:`remote-fw-service.py`.
If a message about "incorrect communication" appears, you mixed up the port
numbers for logging and requests in your command or hardware map. Switch them
and try again.
.. code-block:: shell
ERROR:remote-fw:incorrect monitor communication!
If a "load failed" message appears, that means the flash failed. Examine the
log of ``west flash`` and carefully check that the arguments to ``west sign``
are correct.
.. code-block:: console
WARNING:cavs-fw:Load failed? FW_STATUS = 0x81000012
INFO:cavs-fw:cAVS firmware load complete
--
Sometimes a flash failure or network miscommunication corrupts the state of
the ADSP or :file:`remote-fw-service.py`. If you are unable to identify a
cause of repeated failures, try restarting the scripts and / or power cycling
your board to reset the state.
Users - particularly, users of the Xtensa toolchain - should also consider
clearing their Zephyr cache, as caching issues can occur from time to time.
Delete the cache as well as any applicable build directories and start from
scratch. You can try using the "pristine" option of West first, if you like.
.. code-block:: console
rm -rf build twister-out*
rm -rf ~/.ccache ~/.cache/zephyr
Xtensa toolchain users can get more detailed logs from the license server by
exporting ``FLEXLM_DIAGNOSTICS=3``.
.. _SOF: https://thesofproject.github.io/latest/index.html
.. _Chromebooks: https://www.hp.com/us-en/shop/pdp/hp-chromebook-x360-14c-cc0047nr
.. _UP2: https://up-board.org/upsquared/specifications/
.. _UP Xtreme: https://up-board.org/up-xtreme/
.. _UP Xtreme i11-0001 series: https://up-shop.org/up-xtreme-i11-boards-0001-series.html
.. _SOF instructions: https://thesofproject.github.io/latest/getting_started/build-guide/build-with-zephyr.html
.. _UP Community wiki: https://github.com/up-board/up-community/wiki/Ubuntu
.. _Cadence: https://www.cadence.com/en_US/home/tools/ip/tensilica-ip.html