From 9d403c98493f31ac0bfaf11781f1df469691a60a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 7 May 2022 18:27:45 +0200 Subject: [PATCH] docs: dev/hardware: update hardware support documentation (#2458) Replace most of the page to account for the changes that have happened in Gluon and OpenWrt in the last 4 years: - Switch from Shell-based target definition language to Lua - Removal of targets using legacy build code Closes #2360 --- docs/dev/hardware.rst | 289 ++++++++++++++++++++++++++---------------- 1 file changed, 183 insertions(+), 106 deletions(-) diff --git a/docs/dev/hardware.rst b/docs/dev/hardware.rst index 56f56cba..fb56d08f 100644 --- a/docs/dev/hardware.rst +++ b/docs/dev/hardware.rst @@ -1,5 +1,5 @@ -Adding support for new hardware -=============================== +Adding hardware support +======================= This page will give a short overview on how to add support for new hardware to Gluon. @@ -7,155 +7,232 @@ Hardware requirements --------------------- Having an ath9k, ath10k or mt76 based WLAN adapter is highly recommended, although other chipsets may also work. VAP (multiple SSID) support -is a requirement. - -.. _device-class-definition: +with simultaneous AP + Mesh Point (802.11s) operation is required. Device checklist ---------------- -Pull requests adding device support must have the device checklist -included in their description. The checklist assures core functionality -of Gluon is well supported on the device. +The description of pull requests adding device support must include the +`device integration checklist +`_. +The checklist ensures that core functionality of Gluon is well supported on the +device. -The checklist can be found in the `wiki `_. +.. _device-class-definition: Device classes -------------- -Gluon currently is aware of two device classes. Depending on the device class, different -features can be installed onto the device. +All supported hardware is categorized into "device classes". This allows to +adjust the feature set of Gluon to the different hardware's capabilities via +``site.mk`` without having to list individual devices. -The ``tiny`` device-class contains devices with the following limitations: +There are currently two devices classes defined: "standard" and "tiny". The +"tiny" class contains all devices that do not meet the following requirements: -* All devices with less than 64 MB of system memory -* All devices with less than 7 MB of usable firmware space -* Devices using a single ath10k radio and less than 128MB of system memory +- At least 7 MiB of usable firmware space +- At least 64 MiB of RAM (128MiB for devices with ath10k radio) -.. _hardware-adding-profiles: +Target configuration +-------------------- +Gluon's hardware support is based on OpenWrt's. For each supported target, +a configuration file exists at ``targets/-`` (or just +``target/`` for targets without subtargets) that contains all +Gluon-specific settings for the target. The generic configuration +``targets/generic`` contains settings that affect all targets. -Adding profiles ---------------- -The vast majority of devices with ath9k WLAN are based on the ath79 target of OpenWrt. -If the hardware you want to add support for is ath79, adding a new profile -is sufficient. +All targets must be listed in ``target/targets.mk``. -Profiles are defined in ``targets/*`` in a shell-based DSL (so common shell -command syntax like ``if`` can be used). +The target configuration language is based on Lua, so Lua's syntax for variables +and control structures can be used. -The ``device`` command is used to define an image build for a device. It takes -two or three parameters. +Device definitions +~~~~~~~~~~~~~~~~~~ +To configure a device to be built for Gluon, the ``device`` function is used. +In the simplest case, only two arguments are passed, for example: -The first parameter defines the Gluon profile name, which is used to refer to the -device and is part of the generated image name. The profile name must be same as -the output of the following command (on the target device), so the autoupdater -can work:: +.. code-block:: lua - lua -e 'print(require("platform_info").get_image_name())' + device('tp-link-tl-wdr3600-v1', 'tplink_tl-wdr3600-v1') -While porting Gluon to a new device, it might happen that the profile name is -unknown. Best practise is to generate an image first by using an arbitrary value -and then executing the lua command on the device and use its output from then on. +The first argument is the device name in Gluon, which is part of the output +image filename, and must correspond to the model string looked up by the +autoupdater. The second argument is the corresponding device profile name in +OpenWrt, as found in ``openwrt/target/linux//image/*``. -The second parameter defines the name of the image files generated by OpenWrt. Usually, -it is also the OpenWrt profile name; for devices that still use the old image build -code, a third parameter with the OpenWrt profile name can be passed. The profile names -can be found in the image Makefiles in ``openwrt/target/linux//image/Makefile``. +A table of additional settings can be passed as a third argument: -Examples:: +.. code-block:: lua - device tp-link-tl-wr1043n-nd-v1 tl-wr1043nd-v1 - device alfa-network-hornet-ub hornet-ub HORNETUB + device('ubiquiti-edgerouter-x', 'ubnt_edgerouter-x', { + factory = false, + packages = {'-hostapd-mini'}, + manifest_aliases = { + 'ubnt-erx', + }, + }) + +The supported additional settings are described in the following sections. Suffixes and extensions -''''''''''''''''''''''' +~~~~~~~~~~~~~~~~~~~~~~~ +For many targets, OpenWrt generates images with the suffixes +``-squashfs-factory.bin`` and ``-squashfs-sysupgrade.bin``. For devices with +different image names, is it possible to override the suffixes and extensions +using the settings ``factory``, ``factory_ext``, ``sysupgrade`` and +``sysupgrade_ext``, for example: -By default, image files are expected to have the extension ``.bin``. In addition, -the images generated by OpenWrt have a suffix before the extension that defaults to -``-squashfs-factory`` and ``-squashfs-sysupgrade``. +.. code-block:: lua -This can be changed using the ``factory`` and ``sysupgrade`` commands, either at -the top of the file to set the defaults for all images, or for a single image. There -are three forms with 0 to 2 arguments (all work with ``sysupgrade`` as well):: + { + factory = '-squashfs-combined', + factory_ext = '.img.gz', + sysupgrade = '-squashfs-combined', + sysupgrade_ext = '.img.gz', + } - factory SUFFIX .EXT - factory .EXT - factory +Only settings that differ from the defaults need to be passed. ``factory`` and +``sysupgrade`` can be set to ``false`` when no such images exist. -When only an extension is given, the default suffix is retained. When no arguments -are given, this signals that no factory (or sysupgrade) image exists. +For some device types, there are multiple factory images with different +extensions. ``factory_ext`` can be set to a table of strings to account for this +case: -Aliases -''''''' +.. code-block:: lua -Sometimes multiple models use the same OpenWrt images. In this case, the ``alias`` -command can be used to create symlinks and additional entries in the autoupdater -manifest for the alternative models. + { + factory_ext = {'.img.gz', '.vmdk', '.vdi'}, + } -Standalone images -''''''''''''''''' +TODO: Extra images -On targets without *per-device rootfs* support in OpenWrt, the commands described above -can't be used. Instead, ``factory_image`` and ``sysupgrade_image`` are used:: +Aliases and manifest aliases +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sometimes multiple devices exist that use the same OpenWrt images. To make it +easier to find these images, the ``aliases`` setting can be used to define +additional device names. Gluon will create symlinks for these names in the +image output directory. - factory_image PROFILE IMAGE .EXT - sysupgrade_image PROFILE IMAGE .EXT +.. code-block:: lua -Again, the profile name must match the value printed by the aforementioned Lua -command. The image name must match the part between the target name and the extension -as generated by OpenWrt and is to be omitted when no such part exists. + device('aruba-ap-303', 'aruba_ap-303', { + factory = false, + aliases = {'aruba-instant-on-ap11'}, + }) -Packages -'''''''' +The aliased name will also be added to the autoupdate manifest, allowing upgrade +images to be found under the different name on targets that perform model name +detection at runtime. -The ``packages`` command takes an arbitrary number of arguments. Each argument -defines an additional package to include in the images in addition to the default -package sets defined by OpenWrt. When a package name is prefixed by a minus sign, the -packages are excluded instead. +It is also possible to add alternative names to the autoupdater manifest without +creating a symlink by using ``manifest_aliases`` instead of ``aliases``, which +should be done when the alternative name does not refer to a separate device. +This is particularly useful to allow the autoupdater to work when the model name +changed between Gluon versions. -The ``packages`` command may be used at the top of a target definition to modify -the default package list for all images, or just for a single device (when the -target supports *per-default rootfs*). +Package lists +~~~~~~~~~~~~~ +Gluon generates lists of packages that are installed in all images based on a +default list and the features and packages specified in the site configuration. +In addition, OpenWrt defines additional per-device package lists. These lists +may be modified in Gluon's device definitions, for example to include additional +drivers and firmware, or to remove unneeded software. Packages to remove are +prefixed with a ``-`` character. -Configuration -''''''''''''' +For many ath10k-based devices, this is used to replace the "CT" variant of +ath10k with the mainline-based version: -The ``config`` command allows to add arbitrary target-specific OpenWrt configuration -to be emitted to ``.config``. +.. code-block:: lua -Notes -''''' + local ATH10K_PACKAGES_QCA9880 = { + 'kmod-ath10k', + '-kmod-ath10k-ct', + '-kmod-ath10k-ct-smallbuffers', + 'ath10k-firmware-qca988x', + '-ath10k-firmware-qca988x-ct', + } + device('openmesh-a40', 'openmesh_a40', { + packages = ATH10K_PACKAGES_QCA9880, + factory = false, + }) -On devices with multiple WLAN adapters, care must also be taken that the primary MAC address is -configured correctly. ``/lib/gluon/core/sysconfig/primary_mac`` should contain the MAC address which -can be found on a label on most hardware; if it does not, ``/lib/gluon/upgrade/010-primary-mac`` -in ``gluon-core`` might need a fix. (There have also been cases in which the address was incorrect -even on devices with only one WLAN adapter, in these cases a OpenWrt bug was the cause). +This example also shows how to define a local variable, allowing the package +list to be reused for multiple devices. +Device flags +~~~~~~~~~~~~ -Adding support for new hardware targets ---------------------------------------- +The settings ``class``, ``deprecated`` or ``broken`` should be set according to +the device support status. The default values are as follows: -Adding a new target is much more complex than adding a new profile. There are two basic steps -required for adding a new target: +.. code-block:: lua -Package adjustments -''''''''''''''''''' + { + class = 'standard', + deprecated = false, + broken = false, + } -One package that may need adjustments for new targets is ``libplatforminfo`` (to be found in -`packages/gluon/libs/libplatforminfo `_). -If the new platform works fine with the definitions found in ``default.c``, nothing needs to be done. Otherwise, -create a definition for the added target or subtarget, either by symlinking one of the files in the ``templates`` -directory, or adding a new source file. +- Device classes are described in :ref:`device-class-definition` +- Broken devices are untested or do not meet our requirements as given by the + device checklist +- Deprecated devices are slated for removal in a future Gluon version due to + hardware constraints -On many targets, Gluon's network setup scripts (mainly in the package ``gluon-core``) -won't run correctly without some adjustments, so better double check that everything is fine there (and the files -``primary_mac``, ``lan_ifname`` and ``wan_ifname`` in ``/lib/gluon/core/sysconfig/`` contain sensible values). +Global settings +~~~~~~~~~~~~~~~ +There is a number of directives that can be used outside of a ``device()`` +definition: -Build system support -'''''''''''''''''''' +- ``include('filename')``: Include another file with global settings +- ``config(key, value)``: Set a config symbol in OpenWrt's ``.config``. Value + may be a string, number, boolean, or nil. Booleans and nil are used for + tristate symbols, where nil sets the symbol to ``m``. +- ``try_config(key, value)``: Like ``config()``, but do not fail if setting + the symbol is not possible (usually because its dependencies are not met) +- ``packages { 'package1', '-package2', ... }``: Define a list of packages to + add or remove for all devices of a target. Package lists passed to multiple + calls of ``packages`` will be aggregated. +- ``defaults { key = value, ... }``: Set default values for any of the + additional settings that can be passed to ``device()``. -A definition for the new target must be created under ``targets``, and it must be added -to ``targets/targets.mk``. The ``GluonTarget`` macro takes one to two arguments: -the target name and the OpenWrt subtarget name. +Helper functions +~~~~~~~~~~~~~~~~ +The following helpers can be used in the target configuration: -After this, is should be sufficient to call ``make GLUON_TARGET=`` to build the images for the new target. +- ``env.KEY`` allows to access environment variables +- ``istrue(value)`` returns true if the passed string is a positive number + (often used with ``env``, for example ``if istrue(env.GLUON_DEBUG) then ...``) + +Hardware support in packages +---------------------------- +In addition to the target configuration files, some device-specific changes may +be required in packages. + +gluon-core +~~~~~~~~~~ +- ``/lib/gluon/upgrade/010-primary-mac``: Override primary MAC address selection + + Usually, the primary (label) MAC address is defined in OpenWrt's Device Trees. + For devices or targets where this is not the case, it is possible to specify + what interface to take the primary MAC address from in ``010-primary-mac``. + +- ``/lib/gluon/upgrade/020-interfaces``: Override LAN/WAN interface assignment + + On PoE-powered devices, the PoE input port should be "WAN". + +- ``/usr/lib/lua/gluon/platform.lua``: Contains a list of outdoor devices + +gluon-setup-mode +~~~~~~~~~~~~~~~~ +- ``/lib/gluon/upgrade/320-setup-ifname``: Contains a list of devices that use + the WAN port for the config mode + + On PoE-powered devices, the PoE input port should be used for the config + mode. This is handled correctly by default for outdoor devices listed in + ``platform.lua``. + +libplatforminfo +~~~~~~~~~~~~~~~ +When adding support for a new target to Gluon, it may be necessary to adjust +libplatforminfo to define how autoupdater image names are derived from the +model name.