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
This commit is contained in:
parent
56eaf4aa28
commit
9d403c9849
@ -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
|
||||
<https://github.com/freifunk-gluon/gluon/wiki/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 <https://github.com/freifunk-gluon/gluon/wiki/Device-Integration-checklist>`_.
|
||||
.. _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/<target>-<subtarget>`` (or just
|
||||
``target/<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/<target>/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/<target>/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 <https://github.com/freifunk-gluon/packages/tree/master/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=<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.
|
||||
|
Loading…
Reference in New Issue
Block a user