diff --git a/doc/configuration.rst b/doc/configuration.rst index ea1e03b65..315dd43d0 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -2014,6 +2014,8 @@ Arguments: - login_timeout (int, default=60): timeout for password/login prompt detection - for other arguments, see `UBootDriver`_ +.. _UBootProviderInfo: + UBootProviderDriver ~~~~~~~~~~~~~~~~~~~ @@ -2057,6 +2059,11 @@ Variables: specified in the environment file - do-clean (str): If set to "1" this cleans the build before starting, otherwise it does an incremental build + - build-dir (str): If set, this is used as the build directory for U-Boot + - process-limit (int): Limits the number of buildman processes which can + be running jobs at once. Set this to 1 to avoid over-taxing your + CPU. Buildman does its own multithreading, so each process will use + all available CPUs anyway. Environment variables: - U_BOOT_BUILD_DIR (str): If present, this is used as the build directory for @@ -2108,6 +2115,8 @@ Tools: tools: buildman: "buildman.stable" +.. _UBootWriterInfo: + UBootWriterDriver ~~~~~~~~~~~~~~~~~ @@ -3865,6 +3874,8 @@ the "shell" state: This command would transition directly into a Linux shell and activate the `ShellDriver`_. +.. _UBootStrategyInfo: + UBootStrategy ~~~~~~~~~~~~~ A :any:`UBootStrategy` has five states: diff --git a/doc/usage.rst b/doc/usage.rst index fa1b4ef5e..b4308f5ac 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -899,3 +899,280 @@ like this: $ labgrid-client -p example allow sirius/john To remove the allow it is currently necessary to unlock and lock the place. + +U-Boot Integration +------------------ + +.. note:: + See status_ for current status and development branches. + +Most ARM boards (and some others) use U-Boot as their bootloader. Labgrid +provides various features to help with development and testing on these boards. +Together these features allow interactive use of Labgrid to build U-Boot from +source, write it to a board and boot it. Support is provided for U-Boot's pytest +and Gitlab setup. + +This section describes the various features which contribute to the overall +functionality. The names of contributed scripts (in *contrib/u-boot*) are shown +in brackets. + +Interactive use +~~~~~~~~~~~~~~~ + +Labgrid provides a 'console' command which can be used to connect to a board. +The :ref:`UBootStrategyInfo` driver provides a way to power cycle (or reset) +the board so that U-Boot starts. It also provides two useful states: + +- `start` which starts up U-Boot and lets it boot (*ub-int*) +- `uboot` which starts up U-Boot and stops it at the CLI prompt (*ub-cli*) + +Both of these are useful in development. + +Building U-Boot +~~~~~~~~~~~~~~~ + +Labgrid intentionally +`doesn't include `_ +build functionality as usually the software-under-test already comes with a +build system and it wants to test the artifacts as built by the "real" build +system. + +U-Boot is no exception and it provides the +`buildman `_ for this +purpose. + +Still, for interactive use some sort of build is needed. The +:ref:`UBootProviderInfo` provides an interface to buildman and a way of dealing +with board-specific binary blobs. The buildman tool works automatically provided +that you have set it up with suitable toolchains. See +`buildman `_ for more +information. + +Writing U-Boot +~~~~~~~~~~~~~~ + +Writing U-Boot to a board can be complicated, because each SoC uses its own +means of booting. The other problem is that special lab hardware is generally +needed to update the boot device, e.g. +`SD-wire `_. + +Fortunately Labgrid provides the means for manipulating the lab hardware. All +that is needed is a driver which understands where to write images, which files +to use and the sequence to use in each case. The :ref:`UBootWriterInfo` driver +handles this. It picks out the necessary files from a build directory and writes +them to the selected boot media, or sends them using the SoC-specific bootrom. +Combined with :ref:`UBootStrategyInfo` it provides automated updating of U-Boot +on suported SoCs regardless of the lab setup. + +Run labgrid tests +~~~~~~~~~~~~~~~~~ + +Labgrid provides integration with pytest. As part of the U-Boot integration, a +conftest.py file is provided which can build and smoke-test U-Boot on a board +(*ub-smoke*). + +Run U-Boot tests +~~~~~~~~~~~~~~~~~ + +It is also possible to run the U-Boot tests (*ub-pyt*). To do this you will need +to set up Labgrid integration with the +`U-Boot test hooks `_. +To do this, create the directory `u-boot-test-hooks/bin/$hostname` and add an +executable file called `common.labgrid` which sets the crossbar and environment +information: + +.. code-block:: bash + + export LG_CROSSBAR="ws://kea:20408/ws" + export LG_ENV="/path/to/env.cfg" + + flash_impl=none + reset_impl=none + console_impl=labgrid + release_impl=labgrid + +The last four lines tell the hooks to use labgrid. + +Then create another executable file (in the same directory) called 'conf.all', +containing: + +.. code-block:: bash + + . "${bin_dir}/${hostname}/common-labgrid" + +Bisecting +~~~~~~~~~ + +It is possible to use the *ub-pyt* or *ub-smoke* scripts with `git bisect run` +to bisect a problem on a particular board. However there is a slightly more +powerful script which supports applying a commit each time (*ub-bisect*). + +Setting up pytest +~~~~~~~~~~~~~~~~~ + +To set up the U-Boot pytest integration: + +#. Copy the `contrib/u-boot` directory to somewhere suitable and add it to your + path. For example: + +.. code-block:: bash + + cp -a contrib/u-boot ~/bin/u-boot + echo 'PATH="$PATH:~/bin/u-boot"' >> ~/.bashrc + +#. Edit the `lg-env` file to set the lab parameters according to your setup. +#. Start a new terminal, or login again, so the path updates. You can now use + the scripts as documented below. + +Gitlab Integration +~~~~~~~~~~~~~~~~~~ + +U-Boot uses `Gitlab `_ as the basis for its Continuous +Integration (CI) system (`U-Boot instance `_). +It is possible to set up your own lab which integrates with Gitlab, with your +own Git lab 'runner' which can control Labgrid. This allows pushing branches to +Gitlab and running tests on real hardware, similarly to how QEMU is used in +Gitlab. + +To set this up: + +#. Install `gitlab-runner` using these + `instructions `_. + +#. Register a + `new runner `_ + following the instructions using your custodian CI settings (i.e. do this at + `https://source.denx.de`). + + Select Linux and with tags set to `lab`. Click `Create runner` and use the + command line to register the runner. Use `-lab` (for example + `kea-lab`) as your host name and select `shell` as the executor: + + .. code-block:: console + + $ gitlab-runner register --url https://source.denx.de --token glrt-xxx + Enter the GitLab instance URL (for example, https://gitlab.com/): + [https://source.denx.de]: + Verifying runner... is valid runner=yyy + Enter a name for the runner. This is stored only in the local config.toml file: + []: -lab + Enter an executor: ssh, parallels, docker-windows, docker+machine, kubernetes, instance, custom, shell, virtualbox, docker, docker-autoscaler: + shell + Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! + +#. Edit the resulting `/etc/gitlab-runner/config.toml` file to allow more than + one job at a time by adding 'concurrent = x' where x is the number of jobs. + Here we use concurrent = 8 (this is just an example; don't replace your file + with this): + + .. code-block:: toml + + concurrent = 8 + check_interval = 0 + shutdown_timeout = 0 + + [session_server] + session_timeout = 1800 + + [[runners]] + name = "ellesmere-lab" + url = "https://source.denx.de" + id = 130 + token = "..." + token_obtained_at = 2024-05-15T20:41:29Z + token_expires_at = 0001-01-01T00:00:00Z + executor = "shell" + [runners.custom_build_dir] + +#. Gitlab will run tests as the 'gitlab-runner' user. Make sure your labgrid + installation is installed such that it is visible to that user. One way is: + + .. code-block:: bash + + sudo su - gitlab-runner + cd /path/to/labgrid + pip install . + +#. Add the following to U-Boot's `.gitlab-ci.yml`, adjusting the variables as + needed. For trying it out initially you might want to disable all the other + rules by changing `when: always` to `when: never`: + + .. code-block:: yaml + + .lab_template: &lab_dfn + stage: lab + tags: [ 'lab' ] + script: + # Environment: + # SRC - source tree + # ROOT - directory above that + # OUT - output directory for builds + - export SRC="$(pwd)" + - ROOT="$(dirname ${SRC})" + - export OUT="${ROOT}/out" + - export PATH=$PATH:~/bin + - export PATH=$PATH:/vid/software/devel/ubtest/u-boot-test-hooks/bin + + # Load it on the device + - ret=0 + - echo "board ${BOARD} id ${ID}" + - ${SRC}/test/py/test.py -B "${BOARD}" --id ${ID} --configure + --build-dir "${OUT}/current/${BOARD}" -k "not bootstd"|| ret=$? + - if [[ $ret -ne 0 ]]; then + exit $ret; + fi + + rpi3: + variables: + BOARD: rpi_3_32b ## This is a U-Boot board name + ID: rpi3 ## This is the corresponding role/target + <<: *lab_dfn + +#. Commit your changes and push to your custodian tree. This example shows the + driver model tree at a remote called 'dm': + + .. code-block:: bash + + $ git remote -v |grep dm + dm git@source.denx.de:u-boot/custodians/u-boot-dm.git (fetch) + dm git@source.denx.de:u-boot/custodians/u-boot-dm.git (push) + $ git push dm HEAD:try + +#. Navigate to the pipelines and you should see your tests running. You can + debug things from there, e.g. using the `ub-int` or `ub-pyt` scripts on an + individual board. An example may be visible + `here `_. + +Scripts +~~~~~~~ + +Various scripts are provided in the `contrib/` directory, specifically targeted +at U-Boot testing and development. + +.. include:: ../contrib/u-boot/index.rst + + +.. _status: + +U-Boot Integration Status +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Date: May '24 +Overall status: Ready for early testing + +Required pieces: + +- `Labgrid WIP PR `_ +- `U-Boot test hooks branch `_ +- `U-Boot branch `_ (needed for + U-Boot pytest integration) + +Testing has been very limited, basically a set of 21 boards, including sunxi, +rpi, RK3399, ODroid-C4, pine64, Orange Pi PC, various Chromebooks and Intel +Minnowboard Max. + +Some U-Boot pytests fails on some hardware: +- TPM tests fail on boards with a TPM +- test_log_format fails on several (perhaps all?) boards + +There are likely many other problems.