Compare commits

..
13 Commits
Author SHA1 Message Date
Joachim Wiberg 009b31d465 modemd: handle preferred-mode set without allowed-mode
Setting just preferred-mode in YANG (no allowed-mode leaf-list) built an
invalid mode string with an empty allowed:

  Mode 'allowed: ; preferred: 4g' is not supported

The empty allowed: can never match anything in the modem's supported-modes
list, so the user got a cryptic 'is not supported' even when their preferred
mode was, in principle, supported.

When only preferred-mode is configured, walk the modem's supported-modes list
for an entry that already has that preferred, and reuse its allowed set.  If
no supported entry has that preferred mode, fail with a message that lists
every combination the modem does support, easier to diagnose than the silent
'empty allowed' case.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:04 +02:00
Joachim Wiberg 36ef190c3d modemd: stop retrying mmcli --reset when the modem rejects it
Some cellular modems (notably Quectel EM05) don't expose a RESET capability
over MBIM/QMI.  Both 'mmcli --reset' and 'mmcli --factory-reset' return
Unsupported immediately, the AT command is never forwarded to the firmware,
and there's nothing modemd can do over the management bus to recover.  Until
now modemd's failed-state retry kept calling --reset every 30 s for the rest
of uptime, producing pure log noise:

    modemd: <error> [modem0] Resetting after being 30s in state failed
    modemd: <info>  [modem0] Resetting
    ModemManager: <wrn> [modem0] failed requesting modem reset: Unsupported
    ModemManager: <wrn> [modem0] failed requesting modem factory reset: Unsupported
    modemd: <error> [modem0] Unable to reset

... and the same five lines again 30 s later, indefinitely.

Mitigate this by caching the Unsupported state per modem per session.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:03 +02:00
Joachim Wiberg 600483c35b modem: route NMEA from cellular modems to gpsd
Cellular modems (Quectel EM05/EM06/EM12, Sierra EM7565, ...) expose
GPS data as NMEA on a dedicated USB serial interface.  Until now we
relied on ModemManager's --location-enable-gps-nmea, which makes MM
hold the NMEA port and parse the stream itself — useful for mmcli
but a dead end for the rest of the system.  The result was that
modem GPS was visible only via 'show modem' and could not act as an
NTP fallback time source on devices without dedicated GPS hardware.

This commit reroutes the NMEA stream into the existing
gpsd → chronyd pipeline so cellular modems behave just like any
other NMEA-over-USB GPS dongle.  No changes to gpsd, chronyd, or
the ietf-hardware:gps component — the user activates it the same
way as for a dedicated receiver, by adding a 'gps' hardware
component that references /dev/gpsN.

This is Phase 2 of the modem GPS / location integration plan
(.notes/modem-gps-plan.md).

udev (src/modemd/77-mm-modem-gps.rules):
  - For known vendor:product:interface tuples, set ID_MM_PORT_IGNORE
    so ModemManager keeps off the NMEA port, and add
    SYMLINK+="gps%n" so gpsd's existing udev hook picks up the
    device automatically.
  - Interface-number match uses ENV{ID_USB_INTERFACE_NUM} rather
    than ATTRS{bInterfaceNumber}: udev requires all ATTRS{} matches
    in a rule to share one parent, but idVendor/idProduct live on
    the USB device while bInterfaceNumber lives on the USB
    interface.  ENV{} matching has no parent constraint and udev
    already populates ID_USB_INTERFACE_NUM from bInterfaceNumber.
  - Initial entries: Quectel EM05 (2c7c:0125), EM06-E (2c7c:0306),
    EM12-G (2c7c:0512), Sierra Wireless EM7565 (1199:9091).
    Easy to extend.

modemd (modemd/__init__.py):
  - GPS_AT_COMMANDS table maps manufacturer -> (enable, disable) AT
    command pair.  prepare_location() issues the vendor AT command
    via 'mmcli --command=AT+QGPS=1' (or AT+CGPS=1 for Sierra)
    instead of --location-enable-gps-{nmea,raw}.  Vendor lookup is
    substring-based ('Quectel' matches both 'Quectel' and 'Quectel
    Incorporated') because ModemManager normalises differently
    across firmware revisions.  For unrecognised vendors the
    high-level MM path is still used as a fallback, so nothing
    regresses for hardware not yet in the table.
  - The AT path runs based on the udev/vendor table, not on MM's
    --location-status capabilities.  Setting ID_MM_PORT_IGNORE on
    the NMEA port removes 'gps' from MM's capability list even
    though the GPS hardware is still there, so a capability gate
    would mistakenly skip GPS for the very modems we're targeting.
  - _location_capabilities() filters MM-managed sources so a single
    unsupported flag (e.g. CDMA on an LTE-only modem) doesn't fail
    the whole batched call.  Sources the modem doesn't support are
    silently skipped; a warning is logged only if the user's YANG
    config explicitly lists one.
  - Subprocess fan-out collapsed: agps-msa, agps-msb, 3gpp and cdma
    flags share a single batched mmcli invocation.
    prepare_location() drops from 5 subprocess calls to 1 (unknown
    vendor) or 2 (known vendor, AT + batched MM).
  - Stringly-typed if/elif source dispatch replaced with a
    dict-driven table (LOCATION_MM_FLAGS).
  - Two helpers eliminate the ['mmcli', '-m', self.path, ...]
    boilerplate at ~30 ModemThread call sites:
      self._mmcli(*args, check=True)   # runcmd wrapper
      self._mmclij(*args)              # runcmdj wrapper

build (package/feature-modem/Config.in):
  - Select BR2_PACKAGE_MODEM_MANAGER_ATVIADBUS so ModemManager
    accepts raw AT commands over D-Bus without being started in
    --debug mode.  Required by the AT path above; without it
    'mmcli --command' is rejected with MM_CORE_ERROR_UNAUTHORIZED.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:03 +02:00
Joachim Wiberg 7b7baa0730 modem: expose location and last-change in operational state
Cellular modem location data (GPS coordinates, 3GPP cell info) was
previously CLI-only — 'show modem modem0' shelled out to modem-info
which queried mmcli on demand and rendered straight to terminal.
NETCONF/RESTCONF clients had no view into modem location, and there
was no way to tell how stale any modem-state field was.

This commit moves both into the YANG operational tree so they are
accessible through every northbound interface, not just the CLI.  It
is Phase 1 of the modem GPS / location integration plan; Phase 2 will
route the modem's NMEA TTY into the existing gpsd → chronyd pipeline
so cellular modems can also serve as an NTP fallback time source.

YANG (infix-hardware.yang, revision 2026-05-10):
  - modem-state/last-change (yang:date-and-time): freshness indicator
    for the modem-state subtree, bumped on each modemd poll cycle
  - modem-state/location-state container: source (gps|3gpp|...),
    latitude/longitude/altitude (decimal64 6/6/1 fraction-digits),
    cell-id/lac/tac/mcc/mnc, and its own last-change

Runtime path:
  - modemd's check_location() now writes
    /run/modemd/modemN/location/data.json with the full location data
    plus an RFC3339 last-change.  Atomic via tmp+rename.  Walks the
    mmcli output once instead of twice.
  - check() touches /run/modemd/modemN/state.json with a fresh
    last-change after each successful state poll.
  - yanger/infix_modem.py reads both files via HOST.read_json and
    folds them into the modem-state operational subtree.
  - cli_pretty show_modem_detail rewritten to consume the operational
    tree (same path as 'show modem' overview), with new 'Last Update'
    lines for both top-level state and location.
  - bin/show/modem() consolidated: both 'show modem' and
    'show modem REF' use get_json('/ietf-hardware:hardware') — no
    more direct modem-info subprocess call.

Cleanup along the way:
  - Removed the legacy /run/modemd/modemN/location/{up,down,disabled,
    failed} marker file writes — they had no readers anywhere in the
    tree.  In-memory self.location['state'] is kept purely as the
    edge-trigger for the 'Retrieved GPS location' log line.
  - Aligned now_rfc3339() output with yanger.common.YangDate (+00:00
    form, not Z) so consumers see one consistent yang:date-and-time
    format regardless of producer.
  - Fixed multi-modem SIM scoping in show_modem_detail: now derives
    sim<N> from modem<N> instead of picking the first SIM globally.

The bearer / hardware-revision / phone-number / supported-carrier
sections of 'show modem REF' are deliberately omitted for now —
those fields are not yet in the YANG tree.  Bearer details in
particular likely belong on the wwan interface
(ietf-interfaces:interfaces-state) rather than on the modem hardware
component, and can be addressed in a follow-up.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:02 +02:00
Joachim Wiberg f41898d325 modemd: add SIGHUP handler for config reload
On SIGHUP, modemd stops all ModemThreads, re-runs sim-setup, then
restarts the modem threads from fresh sysrepo config.  The pidfile is
touched with os.utime() once the reload is complete, satisfying Finit's
default pidfile-based notify so confd can signal a reload and wait for
it to finish before proceeding.

This allows operator and APN changes to take effect without a full
daemon restart.

Also extract start_modem_threads() to remove the duplicated thread
startup loop shared between initial startup and reload, and align
sighandler() to use isinstance(th, ModemThread) consistently with the
rest of the thread-management code.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:02 +02:00
Joachim Wiberg 1168c6c8e2 modemd: package Python scripts for compiled deployment
Python scripts without a .py extension are never cached as bytecode by
CPython — every invocation re-parses the source.  Packaging as a wheel
pre-compiles all modules to .pyc and installs thin import stubs as the
executables, matching the approach used by bin/show and statd.

Restructure the modemd Python scripts into a proper Python package
(src/modemd/modemd/): each script becomes a module with a main() entry
point.  pyproject.toml declares 11 entry points; the Buildroot
MODEMD_BUILD_PYTHON hook builds a wheel via PEP 517, then pyinstaller.py
installs compiled stubs to /usr/libexec/modemd/ and pre-compiled .pyc
modules to site-packages.

/sbin/modemd is now a symlink to the compiled stub.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:51:01 +02:00
Joachim Wiberg f78f161dbe modem: migrate from infix-modem to ietf-hardware/ietf-interfaces
The initial modem import used a standalone infix-modem YANG module with
an integer-indexed list under /infix-modem:modems carrying a bearer
config mixed in with hardware config.  Infix has adopted the ietf-hardware
model to allow for a clearer separation of concerns, this commit aims to
improve on that situation by refactoring the modem model to use the same
architectural pattern already used for WiFi radios, GPS receivers, and
USB ports:

Hardware:
    /ietf-hardware:hardware/component[class=infix-hardware:modem]
    /ietf-hardware:hardware/component[class=infix-hardware:sim]
Interface:
    /ietf-interfaces:interfaces/interface[type=infix-if-type:modem]

Configuration split:
  modem component — admin-state (enable/disable), radio access mode,
                    frequency bands, location services, probe-timeout
  sim component   — PIN, PUK, carrier profile
  wwan interface  — APN, IP type, roaming, route-preference, auth

This also enables the modem to appear in 'show hardware' alongside
other hardware components, and to be managed over NETCONF/RESTCONF
using the same ietf-hardware RPCs used for USB and WiFi.

YANG changes:
  - infix-modem.yang removed (1089 lines, standalone module)
  - infix-hardware.yang: new modem and sim containers, modem-state and
    sim-state operational state, typedefs for bands/modes/location,
    notification status-update; actions restart/reset/send-sms are
    augmented directly on the component list entry (not inside container
    modem) to work around sysrepo NP-container parent validation — when
    checking a nested action's parent, sysrepo restricts its operational
    data fetch to the container path, excluding the sibling 'class' leaf
    needed to evaluate the container's 'when' condition, so the container
    is never instantiated and the parent check fails
  - infix-if-modem.yang: new submodule (same pattern as wifi/wireguard)
    adds the wwan bearer container to ietf-interfaces
  - infix-if-type.yang: new modem identity for wwan interface type
  - confd version bumped to 1.9

confd:
  - if-modem.c: new file replaces the stub modem_gen() in modem.c;
    generates dagger init scripts with probe-timeout wait loop and
    unconditional dummy wwan creation so downstream IP config succeeds
    when a USB modem is slow to enumerate at boot
  - hardware.c: start/stop/enable/disable modemd (and modem-manager)
    in response to admin-state changes on the modem hardware component;
    use finit_enable/disable consistently
  - hardware_cand_infer_class(): auto-set class for modemN/simN names
  - modem.c: stripped to RPC/notification forwarding only; the old
    genconf() / enable() / disable() logic is gone — hardware.c owns
    the lifecycle now
  - interfaces.c: remove wwan from wait-interface timeout (the modem
    interface appearance is managed by modemd, not confd's init scripts)
  - migrate/1.9: script fully migrates /infix-modem:modems to the new
    split model; each modem[N] becomes a modemN hardware component and
    simN sim component; each bearer becomes a wwanN interface (bearers
    numbered globally across modems); APN, IP type, roaming, preferred-
    mode, bands, location, PIN/PUK/carrier are all carried over; plain-
    text bearer credentials are moved to a named keystore symmetric-key
    (base64-encoded) referenced from bearer/authentication/password;
    apn-type, firewall-enabled, dns-enabled and default-route are
    dropped (no equivalent in the new model)

modemd:
  - load_config() replaces the infix-modem sysrepocfg call; reads from
    ietf-hardware (modem/sim config), ietf-interfaces (bearer config),
    and ietf-keystore (credentials) — three standard modules instead of
    one proprietary one; modems absent from sysrepo config but present
    in system.json are still started (physical detection wins)
  - Default route written to /etc/net.d/<iface>.conf (picked up by
    netd/staticd/zebra) instead of a direct 'ip route add'; routes are
    now visible to FRR for redistribution and metric-based failover
  - Addresses tagged with proto wwan (rt_addrprotos entry 7) for
    precise flush on disconnect without touching other address sources
  - _derive_gateway() handles point-to-point bearers where modem
    reports gateway as "--"; derives peer from link-scope subnet route
  - SimThread exits cleanly on platforms without /dev/simctrl
  - sim-setup, modem-info, modem-udev, modem-rpc, modem-sms all ported
    to the ietf-hardware/ietf-interfaces namespace

statd:
  - infix_modem.py now emits modem-state and sim-state into ietf-hardware
    component entries (modem0, sim0, ...) instead of a separate tree;
    sim-state reports physical slot, lock state, and SIM operator name
  - ietf_hardware.py: hardware component names deduplicated by rename
    (cpu → cpu, cpu1, ...) to prevent LY_EVALID when hwmon and thermal
    sysfs both normalise to the same sensor name
  - show hardware: Cellular Modems and SIM Cards tables added; sensor
    table width now adapts to the widest section in the output
  - 00-probe: USB modem detection writes to system.json["modem"], same
    source as wifi-radios, feeding gen-hardware which emits the
    ietf-hardware component entries at factory config generation time

CLI:
  - 'show modem [ref]': without ref shows Cellular Modems and SIM Cards
    tables (same data subset as 'show hardware'); with ref shows a full
    per-modem dump (hardware info, status, cellular, SIM, bearers, GPS)
  - 'modem restart <ref>': disconnect and reconnect all bearers without
    a full hardware reset
  - 'modem reset <ref>': factory-reset the modem firmware
  - 'modem sms <ref> <number> <message>': send an SMS via the modem
    (uses the signalling plane; no active data bearer required)
  - MODEMS PTYPE provides tab-completion reading modem names from
    /run/system.json

doc:
  - Add initial User Guide for modems
  - Update ChangeLog with modem news
  - Use absolute URLs in ChangeLog.  Relative links only work for in-tree
    references, not in release notes

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:58 +02:00
Joachim Wiberg f0dfc6a8de test: skip defconfig backup files at find time, not mid-loop
defconfig.sh used $# (find result, incl. *~ / *.bak) for the TAP total
but then 'continue'd past backups without decrementing — so a stray
bpi_r4_*_defconfig~ in the tree made TAP see "1..23" followed by only 21
results, and the harness treated the missing 2 as failures.  Filter the
patterns at find instead; $# now matches what the loop iterates over

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:29 +02:00
Joachim Wiberg ffe5ed1e32 statd, show: fix several operational data reporting bugs
Three bugs found while testing modem support on hardware:

ietf_system.py: "interface": null written to DNS server entries when
  no interface is associated, causing LY_EVALID in the ietf-system
  schema validator.  Only include the key when the interface name is
  non-empty.

ietf_system.py: empty list inserts (user [], server [], options [],
  search []) overwrote configured data in the operational store instead
  of leaving it intact.  Guard each insert so operational data only
  shadows configured data when there is something to report.

show system: CPU temperature reported only the first sensor named
  exactly "cpu", "soc", or "core".  Platforms with multiple thermal
  zones (e.g. BPI-R4 exposes cpu and cpu1) always showed only one
  reading.  Collect all sensors whose name matches a CPU/SoC prefix
  and report the maximum.

statd.c: yanger parse errors logged without model name or libyang
  error string, making failures hard to diagnose.  Include both.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:29 +02:00
Joachim Wiberg 314b0b425f Add cellular modem support via modemd daemon
Integrates the modem management subsystem, donated by Avvero Pty Ltd,
adapted to work on any platform without proprietary hardware (simctrl,
modules.json, /sys/class/sim/).

Components:
- package/feature-modem: Buildroot feature package pulling in modemd,
  ModemManager, libmbim, libqmi, and USB serial/MBIM/QMI kernel drivers
- package/modemd: Buildroot package for the modemd daemon and helpers
- src/modemd: modem management daemon — detects modems via ModemManager,
  connects bearers, configures IP addresses, handles SMS and location
- src/confd/src/modem.c: confd plugin — enables/disables modemd and
  modem-manager via sysrepo, forwards RPCs (restart/reset/send-sms)
- src/confd/src/interfaces.{c,h}: IFT_MODEM type for wwan* interfaces;
  confd manages address/route assignment, modem daemon owns link state
- src/confd/yang/confd/infix-modem.yang: YANG model for modem config and
  operational state (bearers, APN, bands, modes, location, SMS)
- src/statd/python/yanger/infix_modem.py: operational state collector
- patches/modem-manager: upstream patches for udev install path,
  multiplexed interface naming, and MBIM port trust from udev hint
  (the last fixes Dell DW5811e / Sierra EM7455 on cold boot)
- patches/libqmi: ignore sysfs in download mode

Platform portability fixes for boards without simctrl hardware:
- modem-info: fall back to /run/modems.json when /run/modules.json is
  absent; discover wwan interfaces via sysfs scan; provide synthetic SIM
  entry when /sys/class/sim/ is not present; fix dbg() to respect flag
- modemd: make --set-allowed-modes=any best-effort (some modems only
  support one mode combination and reject any change); skip mode set
  when current mode already matches requested mode
- sim-setup: guard simctrl open, return None when modules.json absent
  to skip SIM slot switching entirely on non-simctrl hardware

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:28 +02:00
Joachim Wiberg 985b694e51 confd: fix debug mode regression
In the last major refactor of confd to a stand-alone daemon, new command
line options were added, one of which -v <LEVEL>.  Unfortunately opening
up for a few corner cases where the debug flag or the log_level was not
set properly.

This fixes that and also adds a CONFD_ARGS for /etc/default/confd, which
is customary for all daemons.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:28 +02:00
Joachim Wiberg 060e0ea284 board: some sim card help on the bpi-r4
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:28 +02:00
Joachim Wiberg 43bf6358a0 board: add USB2 component to bpi-r4 factory-config
The M.2 LTE slot uses the USB2 bus. Add it as an unlocked component so
the modem hardware is accessible and visible to users in the config.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-07 20:50:27 +02:00
512 changed files with 9291 additions and 53514 deletions
+1 -1
View File
@@ -272,7 +272,7 @@ other contributions that are not aligned to this Code of Conduct."*
[PEP-8]: https://peps.python.org/pep-0008/
[RDD]: https://tom.preston-werner.com/2010/08/23/readme-driven-development
[cbeams]: https://cbea.ms/git-commit/#seven-rules
[conduct]: CODE_OF_CONDUCT.md
[conduct]: CODE-OF-CONDUCT.md
[DCO]: https://developercertificate.org/
[closing]: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests
[gpg-verify]: https://docs.github.com/en/authentication/managing-commit-signature-verification
-15
View File
@@ -1,15 +0,0 @@
version: 2
updates:
- package-ecosystem: gomod
directory: /src/webui
schedule:
interval: weekly
# goyang is pinned to our kernelkit fork via a replace directive and
# stepped by hand when we add patches; leave it for Dependabot to ignore.
ignore:
- dependency-name: github.com/openconfig/goyang
- package-ecosystem: gomod
directory: /src/netbrowse
schedule:
interval: weekly
+8 -2
View File
@@ -78,7 +78,7 @@ jobs:
- name: Configure ${{ matrix.defconfig }}_defconfig
run: |
make ${{ matrix.defconfig }}_defconfig apply-mirror
make ${{ matrix.defconfig }}_defconfig
- name: Build ${{ matrix.defconfig }}_defconfig
run: |
@@ -113,6 +113,12 @@ jobs:
pattern: "artifact-*"
merge-multiple: true
- name: Create checksums ...
run: |
for file in *.tar.gz; do
sha256sum $file > $file.sha256
done
- uses: ncipollo/release-action@v1
with:
allowUpdates: true
@@ -122,7 +128,7 @@ jobs:
prerelease: true
tag: "latest-boot"
token: ${{ secrets.GITHUB_TOKEN }}
artifacts: "*.tar.gz"
artifacts: "*.tar.gz*"
- name: Summary
run: |
+11 -2
View File
@@ -173,7 +173,7 @@ jobs:
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export IX_ID="infix"
export INFIX_ID="infix"
for target in $TARGETS; do
export BINARIES_DIR=$PWD/output_${target}/images
@@ -223,6 +223,15 @@ jobs:
output/images/*-emmc.img*
retention-days: 30
- name: Create checksums
run: |
cd output/images/
for file in *-sdcard.img *-emmc.img; do
if [ -f "$file" ]; then
sha256sum "$file" > "$file.sha256"
fi
done
- name: Upload to release
uses: ncipollo/release-action@v1
with:
@@ -233,7 +242,7 @@ jobs:
prerelease: true
tag: "latest-boot"
token: ${{ secrets.GITHUB_TOKEN }}
artifacts: "output/images/*-sdcard.img,output/images/*-emmc.img"
artifacts: "output/images/*-sdcard.img*,output/images/*-emmc.img*"
- name: Generate summary
run: |
+1 -28
View File
@@ -45,16 +45,13 @@ jobs:
target: ${{ matrix.target }}
enabled: ${{ inputs.use_cache }}
# WebUI images bundle the mkdocs User's Guide via post-build.sh.
- uses: kernelkit/actions/setup-mkdocs@v1.2
- name: Configure & Build
env:
INFIX_RELEASE: ${{ steps.vars.outputs.ver }}
run: |
target=${{ matrix.target }}_defconfig
echo "Building $target ..."
make $target apply-mirror
make $target
make
- name: Generate SBOM from Build
@@ -70,25 +67,6 @@ jobs:
run: |
make test-spec
# rootfs.squashfs is still present here; it is stripped from the
# tarball below. mkimage pulls the rpi64 bootloader from the
# latest-boot release and uses the freshly built host genimage.
- name: Build Raspberry Pi image
if: matrix.target == 'aarch64'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
./utils/mkimage.sh -d -r output raspberrypi-rpi64
mkdir -p rpi-image
mv output/images/*-rpi64-sdcard.img rpi-image/
xz -T0 rpi-image/*-rpi64-sdcard.img
- uses: actions/upload-artifact@v7
if: matrix.target == 'aarch64'
with:
name: artifact-rpi64-image
path: rpi-image/*.img.xz
- name: Prepare Artifacts
run: |
cd output/
@@ -117,8 +95,3 @@ jobs:
with:
name: artifact-disk-image-${{ matrix.target }}
path: output/images/*.qcow2
- uses: actions/upload-artifact@v7
with:
name: artifact-pkg-${{ matrix.target }}
path: output/images/*.pkg
+1 -4
View File
@@ -124,12 +124,9 @@ jobs:
with:
target: ${{ env.TARGET }}
# WebUI images bundle the mkdocs User's Guide via post-build.sh.
- uses: kernelkit/actions/setup-mkdocs@v1.2
- name: Configure ${{ env.TARGET }}
run: |
make ${{ env.TARGET }}_defconfig apply-mirror
make ${{ env.TARGET }}_defconfig
- name: Cleanup stale containers and ports
run: |
-68
View File
@@ -1,68 +0,0 @@
name: Go Vulnerability Scan
on:
push:
branches:
- main
paths:
- 'src/webui/**'
- 'src/netbrowse/**'
- '.github/workflows/govulncheck.yml'
pull_request:
paths:
- 'src/webui/**'
- 'src/netbrowse/**'
- '.github/workflows/govulncheck.yml'
schedule:
- cron: '5 0 * * 6' # Saturday at 00:05 UTC, same as Coverity
workflow_dispatch:
jobs:
govulncheck:
if: ${{ github.repository_owner == 'kernelkit' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
module:
- src/webui
- src/netbrowse
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: stable
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Scan ${{ matrix.module }}
working-directory: ${{ matrix.module }}
run: |
# Full report, for the run summary. govulncheck exits non-zero
# whenever it finds anything, so don't let it fail the step here.
{
echo "## govulncheck: ${{ matrix.module }}"
echo '```'
govulncheck ./... || true
echo '```'
} | tee -a "$GITHUB_STEP_SUMMARY"
# Gate on vulnerabilities reachable from our code through a
# dependency. govulncheck's call-graph analysis is transitive,
# so indirect use counts too (we call a dep that calls the bad
# symbol). trace[0] is the vulnerable symbol; we key on the
# module it lives in. A chain that bottoms out in stdlib is
# fixed by bumping the Buildroot host Go, not this module's
# go.mod, so it's reported above but doesn't fail the build.
# Keep the json scan and jq unguarded so a tool failure fails the
# gate closed; only grep's no-match exit (all-clear) is tolerated.
govulncheck -format json ./... > scan.json || true
called=$(jq -r 'select(.finding.trace[0].function != null) |
.finding.trace[0].module' scan.json | sort -u)
vulns=$(printf '%s' "$called" | grep -vx stdlib || true)
if [ -n "$vulns" ]; then
echo "::error::Called vulnerabilities in dependencies: $(echo "$vulns" | paste -sd, -)"
exit 1
fi
+88
View File
@@ -0,0 +1,88 @@
name: Manny the Manager
on:
workflow_dispatch:
inputs:
checkout:
required: true
type: boolean
cleanup:
required: true
type: boolean
peek:
required: true
type: boolean
jobs:
inventory:
runs-on: ubuntu-latest
steps:
- name: Disk usage ...
run: |
cd
du -hs .[^.]*
- name: Disk inventory (1/2) ...
run: |
echo "df -h ========================================================================="
df -h
echo "mounts ========================================================================"
mount
- name: File inventory (1/2) ...
run: |
echo "Current directory: $(pwd)"
echo "Files in $HOME ================================================================"
ls $HOME
echo "Find $HOME ===================================================================="
find $HOME
- name: Container inventory ...
run: |
echo "Available container images: ==================================================="
docker images
echo "Available containers: ========================================================="
docker ps -a
checkout:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: kernelkit/actions/cache-restore@v1
with:
target: x86_64
dl-prefix: dl-netconf
- name: Disk inventory (2/2) ...
run: |
echo "df -h ========================================================================="
df -h
echo "mounts ========================================================================"
mount
- name: File inventory (2/2) ...
run: |
echo "Current directory: $(pwd)"
echo "Files in $HOME ================================================================"
ls $HOME
echo "Find $HOME ===================================================================="
find $HOME
peeky:
if: ${{ inputs.peek }}
runs-on: ubuntu-latest
steps:
- name: Peek & Poke ...
run: |
whoami
ls -l /mnt/
cat /mnt/DATALOSS_WARNING_README.txt
sudo mkdir /mnt/x-aarch64
sudo chown $(id -un):$(id -gn) /mnt/x-aarch64
ls -l /mnt/
cleanup:
if: ${{ inputs.cleanup }}
needs: [inventory, peeky]
runs-on: ubuntu-latest
steps:
- name: Cleaning up cruft ...
run: |
docker image prune -af
docker volume prune -f
docker container prune -f
+7 -1
View File
@@ -16,6 +16,12 @@ jobs:
pattern: "artifact-*"
merge-multiple: true
- name: Create checksums ...
run: |
for file in *.tar.gz; do
sha256sum $file > $file.sha256
done
- uses: ncipollo/release-action@v1
with:
allowUpdates: true
@@ -26,7 +32,7 @@ jobs:
prerelease: true
tag: "latest"
token: ${{ secrets.GITHUB_TOKEN }}
artifacts: "*.tar.gz"
artifacts: "*.tar.gz*"
- name: Summary
run: |
+12 -1
View File
@@ -83,6 +83,17 @@ jobs:
pattern: "artifact-*"
merge-multiple: true
- name: Create checksums ...
run: |
for file in *.tar.gz; do
sha256sum $file > $file.sha256
done
if ls *.qcow2 &>/dev/null; then
for file in *.qcow2; do
sha256sum "$file" > "$file.sha256"
done
fi
- name: Extract ChangeLog entry ...
run: |
cat doc/ChangeLog.md | ./utils/extract-changelog.sh > release.md
@@ -95,7 +106,7 @@ jobs:
makeLatest: ${{ steps.rel.outputs.latest }}
discussionCategory: ${{ steps.rel.outputs.cat }}
bodyFile: release.md
artifacts: "*.tar.gz,*.qcow2,*.pkg,*.img.xz"
artifacts: "*.tar.gz*,*.qcow2*"
- name: Summary
run: |
-12
View File
@@ -143,15 +143,3 @@ jobs:
with:
name: test-report
path: output/images/test-report.pdf
- name: Generate XPath Coverage Report for ${{ env.TARGET }}
if: always()
run: |
make test-dir="$(pwd)/$TEST_PATH" xpath-coverage-report
- name: Upload XPath Coverage Report as Artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: xpath-coverage-report
path: output/images/xpath-coverage-report.pdf
+12 -1
View File
@@ -27,6 +27,17 @@ jobs:
pattern: "artifact-*"
merge-multiple: true
- name: Create checksums
run: |
for file in *.tar.gz; do
sha256sum $file > $file.sha256
done
if ls *.qcow2 &>/dev/null; then
for file in *.qcow2; do
sha256sum "$file" > "$file.sha256"
done
fi
- uses: ncipollo/release-action@v1
with:
tag: latest
@@ -43,7 +54,7 @@ jobs:
**Commit:** ${{ github.sha }}
**Built:** ${{ github.run_id }}
artifacts: "*.tar.gz,*.qcow2"
artifacts: "*.tar.gz*,*.qcow2*"
- name: Summary
run: |
+22 -23
View File
@@ -2,7 +2,7 @@ source "$BR2_EXTERNAL_INFIX_PATH/board/Config.in"
menu "Branding"
config IX_VENDOR
config INFIX_VENDOR
string "Vendor name"
default "KernelKit"
help
@@ -15,7 +15,7 @@ config IX_VENDOR
Used for VENDOR_NAME in /etc/os-release and GNS3 appliance files.
config IX_VENDOR_HOME
config INFIX_VENDOR_HOME
string "Vendor URL"
help
The homepage of the OS vendor. The value should be in RFC3986
@@ -24,14 +24,14 @@ config IX_VENDOR_HOME
Optional, used for VENDOR_HOME in /etc/os-release
config IX_NAME
config INFIX_NAME
string "Operating system name"
default "Infix"
help
Mandatory. Used for identifying the OS as NAME in /etc/os-release
and product_name in GNS3 appliance files.
config IX_ID
config INFIX_ID
string "Operating system identifier"
default "infix"
help
@@ -43,9 +43,9 @@ config IX_ID
Mandatory. Used for identifying the OS as ID in /etc/os-release and
in the generated image name: ID-ARCH-VERSION.img
config IX_IMAGE_ID
config INFIX_IMAGE_ID
string "Operating system image name"
default "${IX_ID}-${BR2_ARCH}"
default "${INFIX_ID}-${BR2_ARCH}"
help
A lower-case string (no spaces or other characters outside of 09,
az, ".", "_" and "-"), for naming critical image files, directories
@@ -54,18 +54,18 @@ config IX_IMAGE_ID
Mandatory. When INFIX_RELEASE is set, this string is appended to
the IMAGE_ID with a '-' separator.
config IX_COMPATIBLE
config INFIX_COMPATIBLE
string "Operating system compatible string"
default "${IX_IMAGE_ID}"
default "${INFIX_IMAGE_ID}"
help
A lower-case string (no spaces or other characters outside of 09,
az, ".", "_" and "-"), used for image identification at upgrade.
E.g., the RAUC [system] compatible string.
Mandatory. Defaults to $IX_IMAGE_ID, which in turn is composed
of $IX_ID-$BR2_ARCH.
Mandatory. Defaults to $INFIX_IMAGE_ID, which in turn is composed
of $INFIX_ID-$BR2_ARCH.
config IX_TAGLINE
config INFIX_TAGLINE
string "Operating system tagline"
default "Infix OS — Immutable.Friendly.Secure"
help
@@ -74,25 +74,25 @@ config IX_TAGLINE
This is also show at boot when the system init process starts.
config IX_DESC
config INFIX_DESC
string "Operating system description"
help
Optional. Used for long description texts about the OS. E.g.,
the GNS3 appliance file description field. Saved in the file
/etc/os-release as IX_DESC.
/etc/os-release as INFIX_DESC.
config IX_HOME
config INFIX_HOME
string "Operating system URL"
help
Used for identifying the OS, e.g. as HOME_URL in /etc/os-release
config IX_DOC
config INFIX_DOC
string "Operating system docs"
help
Optional. Main documentation URL, will be shown in /etc/os-release
as DOCUMENTATION_URL.
config IX_SUPPORT
config INFIX_SUPPORT
string "Operating system support"
help
Main support page for the operating system, if there is any. This
@@ -102,23 +102,22 @@ config IX_SUPPORT
Optional. Shown, e.g., as SUPPORT_URL in /etc/os-release or
maintainer_email in .gns3a.
config IX_OEM_PATH
config INFIX_OEM_PATH
string "Path to OEM br2-external"
help
A br2-external using Infix will likely want to version the branded
OS using their own GIT tags. Set this variable to point to the base
directory (absolute path) and the Infix post-build.sh will call `git
describe -C $IX_OEM_PATH`.
describe -C $INFIX_OEM_PATH`.
Note: the OS version (VERSION, VERSION_ID, BUILD_ID in
/etc/os-release) is always derived from `git describe`. The global
variable INFIX_RELEASE does not change it; it only labels the release
channel (IMAGE_VERSION) and names the published artifacts.
Note: for release builds the global variable INFIX_RELEASE overrides
the version information derived from `git describe`. However, the
GIT version is always saved as the BUILD_ID in /etc/os-releases.
endmenu
# For /etc/os-release, uses CondtionArchitechture= from systemd.unit(5)
config IX_ARCH
config INFIX_ARCH
string
default "arm" if BR2_arm
default "arm64" if BR2_aarch64
+93 -116
View File
@@ -1,21 +1,63 @@
[![License Badge][]][License] [![Release Badge][]][Release] [![GitHub Status][]][GitHub] [![Discord][discord-badge]][discord-url]
[![License Badge][]][License] [![Release Badge][]][Release] [![GitHub Status][]][GitHub] [![Coverity Status][]][Coverity Scan] [![Discord][discord-badge]][discord-url]
<img align="right" src="doc/logo.png" alt="Infix — Immutable.Friendly.Secure" width=380 padding=10>
<img align="right" src="doc/logo.png" alt="Infix — Immutable.Friendly.Secure" width=480 padding=10>
Infix turns an ARM or x86 device into a managed network appliance. The
same OS runs on a $35 Raspberry Pi and on enterprise switching hardware,
so you can build a router, an IoT gateway, or an edge device on whatever
you have on hand.
Turn any ARM or x86 device into a powerful, manageable network appliance
in minutes. From $35 Raspberry Pi boards to enterprise switches — deploy
routers, IoT gateways, edge devices, or custom network solutions that
just work.
More in-depth material is available in our blog and User Guide:
## Our Values
- <https://www.kernelkit.org/>
- <https://www.kernelkit.org/infix/>
**🔒 Immutable**
Your system never breaks. Read-only filesystem with atomic upgrades
means no configuration drift, no corrupted updates, and instant rollback
if something goes wrong. Deploy once, trust forever.
## See it in action
**🤝 Friendly**
Actually easy to use. Auto-generated CLI from standard YANG models comes
with built-in help for every command — just hit <kbd>?</kbd> or
<kbd>TAB</kbd> for context-aware assistance.
The CLI is generated from the [YANG models][inside], so it guides you with
built-in help. Here's setting an IP address on an interface:
Familiar NETCONF & RESTCONF APIs and [comprehensive documentation][4]
mean you're never stuck. Whether you're learning networking or managing
enterprise infrastructure.
**🛡️ Secure**
Built with security as a foundation, not an afterthought. Minimal
attack surface, separation between system and data, and container
isolation. Sleep better knowing your infrastructure is protected.
## Why Choose Infix
**Hardware Flexibility**: Start with a $35 Raspberry Pi, scale to
enterprise switching hardware. Same OS, same tools, same reliability.
**Standards-Based**: Built around YANG models and IETF standards. Learn
once, use everywhere - no vendor lock-in.
**Container Ready**: Run your applications alongside networking
functions. GPIO access, dedicated Ethernet ports, custom protocols —
your device, your rules.
## Use Cases
1. **Home Labs & Hobbyists**:
Transform a Raspberry Pi into a full-featured router with WiFi
1. **IoT & Edge Computing**:
Bridge devices to the cloud with reliable, updatable gateways
1. **Small Business Networks**:
Enterprise-grade features without the complexity or cost
1. **Developers & Makers**:
Test networking concepts, prototype IoT solutions, or build custom
appliances
1. **Network Professionals**:
Consistent tooling from development to production deployment.
How about a digital twin using raw Qemu or [GNS3](https://gns3.com/infix)!
## Quick Example
Configure an interface in seconds - the CLI guides you with built-in help:
<pre><code>admin@infix-12-34-56:/> <b>configure</b>
admin@infix-12-34-56:/config/> <b>edit interface eth0</b>
@@ -52,94 +94,38 @@ eth0 ethernet UP 52:54:00:12:34:56
admin@infix-12-34-56:/> <b>copy running startup</b>
</code></pre>
<kbd>TAB</kbd> completes available options and <kbd>?</kbd> shows online help
for each option and argument. `show` displays the current config, and `diff`
shows exactly what changed before you commit it with `leave`. See the [CLI
documentation][3] for more.
Notice how <kbd>TAB</kbd> completion shows available options, `show`
displays current config, and `diff` shows exactly what changed before
you commit your changes with the `leave` command.
## Web interface
For more information, see [CLI documentation][3].
If the CLI isn't your style, the same configuration is available through the
web interface. Log in from a browser, keep an eye on your device from the
Status dashboard and use the Configure > Interface setup wizard to create more
advanced setups, or just fold out an interface to add an IP address.
## Get Started
<p>
<a href="doc/img/webui-login.png"><img src="doc/img/webui-login.png" alt="Login" align="top" width=220></a>
<a href="doc/img/webui-dashboard.png"><img src="doc/img/webui-dashboard.png" alt="Dashboard" width=290></a>
<a href="doc/img/webui-wizard.png"><img src="doc/img/webui-wizard.png" alt="Setup wizard" width=260></a>
</p>
Get [pre-built images][5] for your hardware. Use the CLI, web
interface, or standard NETCONF/RESTCONF tools, e.g., `curl`. Add
containers for any custom functionality you need.
The web interface is built on the same concepts as the CLI, so operational
status and state are kept separate from configuration and commands.
### Supported Platforms
## Try it in 5 minutes
- **Raspberry Pi 2B/3B/4B/CM4** - Perfect for home labs, learning, and prototyping
- **Banana Pi-R3** - Your next home router and gateway
- **NanoPi R2S** - Compact dual-port router in a tiny package
- **x86_64** - Run in VMs or on mini PCs for development and testing
- **Marvell CN9130 CRB, EspressoBIN** - High-performance ARM64 platforms
- **Microchip SparX-5i** - Enterprise switching capabilities
- **Microchip SAMA7G54-EK** - ARM Cortex-A7
- **NXP i.MX8MP EVK** - Highly capable ARM64 SoC
- **StarFive VisionFive2** - RISC-V architecture support
You don't need hardware to get started:
*Why start with Raspberry Pi?* It's affordable, widely available, has
built-in WiFi + Ethernet, and runs the exact same Infix OS you'd deploy
in production. Perfect for learning, prototyping, or even small-scale
deployments.
- **In a virtual lab** — run a full topology in [GNS3][gns3-post] and test
networks entirely in software.
- **From source** — [build it and `make run`][build-post] to boot Infix in
QEMU, from `git clone` to pinging the internet.
- **On real hardware** — grab a [pre-built image][5] for your board, or run
the `x86_64` image in any VM.
Log in with `admin` / `admin` on the virtual and pre-built images. On
shipped products the factory-reset credentials are customizable — we
typically provision a unique per-device password stored in EEPROM/VPD.
## Supported hardware
- **Raspberry Pi 2B/3B/4B/CM4** - a good starting point; built-in WiFi and Ethernet
- **Banana Pi-R64/R3/R3 Mini/R4** - multi-port routers and gateways
- **NanoPi R2S** - compact dual-port router
- **x86_64** - VMs and mini PCs, for development or production
- **Marvell CN9130 CRB, EspressoBIN** - ARM64 development boards
- **Microchip SparX-5i** - enterprise switching
- **Microchip SAMA7G54-EK** - ARM Cortex-A7 evaluation kit
- **NXP i.MX8MP EVK** - ARM64 SoC evaluation kit
- **StarFive VisionFive2** - RISC-V board
*Why start with Raspberry Pi?* It's cheap, easy to get hold of, has
built-in WiFi and Ethernet, and runs the same Infix you'd deploy in
production — so what you learn on it carries straight over.
> [!TIP]
> 📖 **[Complete documentation][4]** • 💬 **[Join our Discord][discord-url]**
## Why Infix
**🔒 Immutable**
Read-only filesystem with atomic upgrades. An update either applies
cleanly or rolls back, so a failed upgrade or a power cut midway through
won't leave you with a half-broken system.
**🤝 Friendly**
The CLI is generated from the YANG models, so every command carries its
own help — hit <kbd>?</kbd> or <kbd>TAB</kbd> to see what's available.
The same models are reachable over NETCONF and RESTCONF, with
[documentation][4] for when you get stuck.
**🛡️ Secure**
A small attack surface, separation between system and data, and
container isolation. Since the system partition is read-only, a
compromised service or container can't rewrite the OS underneath it.
## Use cases
1. **Home labs & hobbyists**:
Turn a Raspberry Pi into a router with WiFi
1. **IoT & edge**:
Build gateways you can update in the field
1. **Small business networks**:
Routing, firewalling, and VLANs on affordable hardware
1. **Developers & makers**:
Prototype networking ideas, or build a custom appliance with containers
1. **Network professionals**:
The same tooling from lab to production — spin up a digital twin in raw
Qemu or [GNS3](https://gns3.com/infix)
## Under the hood
## Technical Details
<a href="https://bitsign.se">
<picture>
@@ -149,29 +135,27 @@ compromised service or container can't rewrite the OS underneath it.
</picture>
</a>
Built on [Linux][0], [Buildroot][1], and [sysrepo][2]:
Built on proven open-source foundations: [Linux][0], [Buildroot][1], and
[sysrepo][2] — for reliability you can trust:
- **Immutable OS**: read-only filesystem, atomic updates, rollback on failure
- **YANG configuration**: standard models with an auto-generated CLI and APIs
- **Hardware acceleration**: switchdev offload for wire-speed forwarding
- **Container integration**: Docker, with access to host network and hardware
- **Memory efficient**: runs on devices with as little as 256 MB RAM
- **Code signing**: releases are cryptographically signed
- **Immutable OS**: Read-only filesystem, atomic updates, instant rollback
- **YANG Configuration**: Industry-standard models with auto-generated tooling
- **Hardware Acceleration**: Linux switchdev support for wire-speed packet processing
- **Container Integration**: Docker support with flexible network and hardware access
- **Memory Efficient**: Runs comfortably on devices with as little as 256 MB RAM
- **Code Signing**: Releases are cryptographically signed for integrity verification
Because the whole system is modeled in YANG, every setting is reachable
the same way: from the CLI over console or SSH, or remotely over the
native NETCONF and RESTCONF APIs. The same models drive development,
testing, and day-to-day monitoring.
Perfect for everything from resource-constrained edge devices to
high-throughput network appliances.
With the entire system modeled in YANG, scalability is no longer an
issue, be it in development, testing, or end users deploying and
monitoring their devices. All knobs and dials are accessible from the
CLI (console/SSH), or remotely using the native NETCONF or RESTCONF
APIs.
> Check the *[Latest Build][]* for bleeding-edge features.
## Contributing
Bug reports, ideas, and pull requests are welcome. Start with
[CONTRIBUTING][contributing] and the [code of conduct][coc]. Found a
security issue? Follow the [security policy][security]. Need a hand?
See [support options][support] or [join us on Discord][discord-url].
---
<div align="center">
@@ -187,13 +171,6 @@ See [support options][support] or [join us on Discord][discord-url].
[3]: https://www.kernelkit.org/infix/latest/cli/introduction/
[4]: https://www.kernelkit.org/infix/
[5]: https://github.com/kernelkit/infix/releases/latest
[inside]: https://www.kernelkit.org/posts/inside-infix/
[gns3-post]: https://www.kernelkit.org/posts/infix-in-gns3/
[build-post]: https://www.kernelkit.org/posts/building-infix-from-source/
[contributing]: .github/CONTRIBUTING.md
[coc]: .github/CODE_OF_CONDUCT.md
[security]: .github/SECURITY.md
[support]: .github/SUPPORT.md
[Latest Build]: https://github.com/kernelkit/infix/releases/tag/latest "Latest build"
[License]: https://en.wikipedia.org/wiki/GPL_license
[License Badge]: https://img.shields.io/badge/License-GPL%20v2-blue.svg
@@ -22,7 +22,7 @@ image var.ext4 {
}
}
image #IX_ID##VERSION#-vero-w-#TARGET#.img {
image #INFIX_ID##VERSION#-vero-w-#TARGET#.img {
hdimage {
partition-table-type = "gpt"
gpt-no-backup = true
@@ -24,7 +24,7 @@ image var.ext4 {
}
}
image #IX_ID##VERSION#-bpi-r3-#TARGET#.img {
image #INFIX_ID##VERSION#-bpi-r3-#TARGET#.img {
hdimage {
partition-table-type = "gpt"
+42
View File
@@ -87,6 +87,45 @@ Infix ships with the following factory defaults.
> are bridged into the LAN as access points. WiFi is not included with the board
> and is not part of the factory default configuration.
## SIM Card Installation
The BPI-R4 has three SIM holders, one per PCIe slot:
| Slot | PCIe socket | Typical use |
|----------|-------------|--------------------------|
| **SIM1** | M.2 Key-B | 4G/5G WWAN modem |
| **SIM2** | mPCIe #1 | Cellular or other modem |
| **SIM3** | mPCIe #2 | Cellular or other modem |
All three take **nano-SIM (4FF)** cards.
> [!NOTE]
> The official Banana Pi pages show an older board revision with a sliding
> "sled" holder. Newer boards ship with a fixed friction-fit holder instead:
> there is no lid to lift and no spring eject. The [closest matching photo on
> bananapi.org][15] shows the current mechanism.
### Inserting a SIM
1. Orient the card with the gold contacts facing the PCB (printed
side up) and the cut corner pointing toward the M.2/mPCIe socket,
which on this board is also toward the outer edge. The silkscreen
next to each holder shows the same outline.
2. Push the SIM straight in until it is fully seated. There is no
click and the holder is not spring-loaded, so press firmly until
the contacts engage and the rear edge of the card sits flush with
the holder.
3. A SIM that still protrudes is not fully inserted; push again.
### Removing a SIM
The friction grip on these holders is tight. Gently pry the card out
with a fingernail or a thin plastic spudger. Avoid metal tweezers
near the contacts. Removing the front panel of the metal case is
absolutely necessary to access the SIM holder.
For software configuration once the modem is recognised, see the
[Cellular Modem User's Guide][16].
## Getting Started
@@ -358,3 +397,6 @@ make aarch64
[12]: https://github.com/frank-w/u-boot/releases
[13]: https://github.com/frank-w/u-boot/releases/download/CI-BUILD-2026-01-bpi-2026.01-2026-01-15_2013/bpi-r4_spim-nand_bl2.img
[14]: https://github.com/frank-w/u-boot/releases/download/CI-BUILD-2026-01-bpi-2026.01-2026-01-15_2013/bpi-r4_spim-nand_fip.bin
[15]: https://docs.banana-pi.org/bpi-r4/bpi-r4_4g5g_2.jpg
[16]: https://www.kernelkit.org/infix/latest/modem/
@@ -24,7 +24,7 @@ image var.ext4 {
}
}
image #IX_ID##VERSION#-bpi-r4-#TARGET#.img {
image #INFIX_ID##VERSION#-bpi-r4-#TARGET#.img {
hdimage {
partition-table-type = "gpt"
gpt-no-backup = true
@@ -10,6 +10,13 @@
"state": {
"admin-state": "unlocked"
}
},
{
"name": "USB2",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked"
}
}
]
},
@@ -366,7 +373,7 @@
]
},
"infix-meta:meta": {
"version": "1.7"
"version": "1.8"
},
"infix-services:mdns": {
"enabled": true
@@ -10,6 +10,13 @@
"state": {
"admin-state": "unlocked"
}
},
{
"name": "USB2",
"class": "infix-hardware:usb",
"state": {
"admin-state": "unlocked"
}
}
]
},
@@ -358,7 +365,7 @@
]
},
"infix-meta:meta": {
"version": "1.7"
"version": "1.8"
},
"infix-services:mdns": {
"enabled": true
@@ -24,7 +24,7 @@ image var.ext4 {
}
}
image #IX_ID##VERSION#-bpi-r64-#TARGET#.img {
image #INFIX_ID##VERSION#-bpi-r64-#TARGET#.img {
hdimage {
partition-table-type = "hybrid"
# MT7622 TF-A partition driver detects GPT by checking MBR[0]
@@ -26,7 +26,7 @@ image var.ext4 {
}
}
image #IX_ID##VERSION#-nanopi-r2s-sdcard.img {
image #INFIX_ID##VERSION#-nanopi-r2s-sdcard.img {
hdimage {
partition-table-type = "gpt"
}
@@ -24,7 +24,7 @@ image var.ext4 {
}
}
image #IX_ID##VERSION#-espressobin-#TARGET#.img {
image #INFIX_ID##VERSION#-espressobin-#TARGET#.img {
hdimage {
partition-table-type = "gpt"
}
@@ -36,7 +36,7 @@ image var.ext4 {
}
}
image #IX_ID##VERSION#-rpi64-sdcard.img {
image #INFIX_ID##VERSION#-rpi64-sdcard.img {
hdimage {
partition-table-type = "hybrid"
}
@@ -39,7 +39,7 @@ image var.ext4 {
}
}
image #IX_ID##VERSION#-sama7g54-ek-#TARGET#.img {
image #INFIX_ID##VERSION#-sama7g54-ek-#TARGET#.img {
hdimage {
partition-table-type = "hybrid"
}
+1 -1
View File
@@ -36,7 +36,7 @@ image var.ext4 {
}
}
image #IX_ID##VERSION#-rpi2-sdcard.img {
image #INFIX_ID##VERSION#-rpi2-sdcard.img {
hdimage {
partition-table-type = "hybrid"
}
+8 -8
View File
@@ -11,7 +11,7 @@ source "$BR2_EXTERNAL_INFIX_PATH/board/common/image/image-readme/Config.in"
endmenu
config IX_QEMU_SCRIPTS
config QEMU_SCRIPTS
bool "QEMU scripts"
default y
help
@@ -19,20 +19,20 @@ config IX_QEMU_SCRIPTS
directory, which can be used to launch virtual Infix
instances.
menuconfig IX_TRUSTED_KEYS
menuconfig TRUSTED_KEYS
bool "Trusted keys for image"
help
Keys that will be accepted for this image
config IX_TRUSTED_KEYS_DEVELOPMENT
config TRUSTED_KEYS_DEVELOPMENT
bool "Development key"
depends on IX_TRUSTED_KEYS
depends on TRUSTED_KEYS
config IX_TRUSTED_KEYS_DEVELOPMENT_PATH
config TRUSTED_KEYS_DEVELOPMENT_PATH
string
depends on IX_TRUSTED_KEYS_DEVELOPMENT
depends on TRUSTED_KEYS_DEVELOPMENT
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.crt"
config IX_TRUSTED_KEYS_EXTRA_PATH
config TRUSTED_KEYS_EXTRA_PATH
string "Path to extra keys to include in image"
depends on IX_TRUSTED_KEYS
depends on TRUSTED_KEYS
+3 -3
View File
@@ -1,14 +1,14 @@
include $(BR2_EXTERNAL_INFIX_PATH)/board/common/image/image.mk
include $(BR2_EXTERNAL_INFIX_PATH)/board/common/qemu/qemu.mk
ifeq ($(IX_TRUSTED_KEYS),y)
ifeq ($(TRUSTED_KEYS),y)
include $(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/uboot.mk
IX_TRUSTED_KEYS=$(IX_TRUSTED_KEYS_DEVELOPMENT_PATH) $(IX_TRUSTED_KEYS_EXTRA_PATH)
TRUSTED_KEYS=$(TRUSTED_KEYS_DEVELOPMENT_PATH) $(TRUSTED_KEYS_EXTRA_PATH)
define RAUC_POST_BUILD_INSTALL_CERT
@$(call IXMSG,"Installing signing cert for RAUC")
mkdir -p $(TARGET_DIR)/etc/rauc/keys
$(foreach crt,$(shell ls $(IX_TRUSTED_KEYS)), \
$(foreach crt,$(shell ls $(TRUSTED_KEYS)), \
cp $(crt) $(TARGET_DIR)/etc/rauc/keys/$(shell openssl x509 -hash -noout <$(crt)).0;)
endef
+5 -5
View File
@@ -1,4 +1,4 @@
config IX_IMAGE_EXT4_RAUC
config IMAGE_EXT4_RAUC
bool "RAUC upgrade bundle (ext4)"
depends on BR2_TARGET_ROOTFS_EXT2
select BR2_PACKAGE_HOST_RAUC
@@ -7,17 +7,17 @@ config IX_IMAGE_EXT4_RAUC
image. Intended for development boards whose bootloader does
not support squashfs.
config IX_IMAGE_EXT4_RAUC_KEY
config IMAGE_EXT4_RAUC_KEY
string "signing key"
depends on IX_IMAGE_EXT4_RAUC
depends on IMAGE_EXT4_RAUC
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.key"
help
Path to the private key, in PKCS#8 format, used to sign
the RAUC bundle; or a PKCS#11 URI.
config IX_IMAGE_EXT4_RAUC_CERT
config IMAGE_EXT4_RAUC_CERT
string "signing certificate"
depends on IX_IMAGE_EXT4_RAUC
depends on IMAGE_EXT4_RAUC
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.crt"
help
Path to the X509 certificate which will be associated with
+2 -2
View File
@@ -1,6 +1,6 @@
config IX_IMAGE_ITB_AUX
config IMAGE_ITB_AUX
bool "aux partition"
depends on IX_IMAGE_ITB_ROOTFS
depends on IMAGE_ITB_ROOTFS
select BR2_PACKAGE_HOST_UBOOT_TOOLS
select BR2_PACKAGE_HOST_GENIMAGE
help
@@ -1,4 +1,4 @@
menuconfig IX_IMAGE_ITB_DL_RELEASE
menuconfig IMAGE_ITB_DL_RELEASE
bool "Download existing release"
depends on !BR2_TARGET_ROOTFS_SQUASHFS
help
@@ -7,9 +7,9 @@ menuconfig IX_IMAGE_ITB_DL_RELEASE
Infix image, to create a full disk image that can be
provisioned to an SD-card or eMMC.
config IX_IMAGE_ITB_DL_RELEASE_URL
config IMAGE_ITB_DL_RELEASE_URL
string "URL"
depends on IX_IMAGE_ITB_DL_RELEASE
depends on IMAGE_ITB_DL_RELEASE
default "https://github.com/kernelkit/infix/releases/download/latest/infix-${BR2_ARCH}.tar.gz"
help
URL to release tarball.
+6 -6
View File
@@ -1,23 +1,23 @@
menuconfig IX_IMAGE_ITB_GNS3A
menuconfig IMAGE_ITB_GNS3A
bool "GNS3 Appliance (ITB)"
depends on BR2_x86_64
select IX_IMAGE_ITB_QCOW
select IMAGE_ITB_QCOW
help
Create a GNS3 appliance description that, together with the
disk image, can be imported into GNS3.
config IX_IMAGE_ITB_GNS3A_RAM
config IMAGE_ITB_GNS3A_RAM
int "Reserved RAM (MiB)"
depends on IX_IMAGE_ITB_GNS3A
depends on IMAGE_ITB_GNS3A
default "192"
help
Amount of host RAM reserved for an appliance instance.
Minimum supported size is 192M.
config IX_IMAGE_ITB_GNS3A_IFNUM
config IMAGE_ITB_GNS3A_IFNUM
int "Number of interfaces"
depends on IX_IMAGE_ITB_GNS3A
depends on IMAGE_ITB_GNS3A
default "1"
help
Number of Ethernet interfaces to create for an appliance instance.
+16 -16
View File
@@ -1,6 +1,6 @@
menuconfig IX_IMAGE_ITB_QCOW
menuconfig IMAGE_ITB_QCOW
bool "QEMU disk image (ITB)"
depends on (IX_IMAGE_ITB_ROOTFS && IX_IMAGE_ITB_AUX) || IX_IMAGE_ITB_DL_RELEASE
depends on (IMAGE_ITB_ROOTFS && IMAGE_ITB_AUX) || IMAGE_ITB_DL_RELEASE
select BR2_PACKAGE_HOST_GENIMAGE
help
Compose a full disk image with redundant Linux OS partitions,
@@ -11,9 +11,9 @@ menuconfig IX_IMAGE_ITB_QCOW
- Creating a GNS3 appliance
- Developing/debugging issues in the boot process in QEMU
menuconfig IX_IMAGE_ITB_QCOW_SIZE
menuconfig IMAGE_ITB_QCOW_SIZE
string "Image size"
depends on IX_IMAGE_ITB_QCOW
depends on IMAGE_ITB_QCOW
default "512M"
help
Create a disk image of this size. A K/M/G suffix may be used
@@ -26,22 +26,22 @@ menuconfig IX_IMAGE_ITB_QCOW_SIZE
choice
prompt "Bootloader"
depends on IX_IMAGE_ITB_QCOW
default IX_IMAGE_ITB_QCOW_BOOT_EFI if BR2_x86_64
default IX_IMAGE_ITB_QCOW_BOOT_NONE
depends on IMAGE_ITB_QCOW
default IMAGE_ITB_QCOW_BOOT_EFI if BR2_x86_64
default IMAGE_ITB_QCOW_BOOT_NONE
config IX_IMAGE_ITB_QCOW_BOOT_NONE
config IMAGE_ITB_QCOW_BOOT_NONE
bool "None"
help
Do not create any bootloader partition in the disk image.
config IX_IMAGE_ITB_QCOW_BOOT_EFI
config IMAGE_ITB_QCOW_BOOT_EFI
bool "EFI"
help
Create a boot partition from a directory containing an EFI
boot application, e.g. GRUB.
config IX_IMAGE_ITB_QCOW_BOOT_BIN
config IMAGE_ITB_QCOW_BOOT_BIN
bool "Binary"
help
Create a boot partition from a raw image containing the boot
@@ -49,18 +49,18 @@ config IX_IMAGE_ITB_QCOW_BOOT_BIN
endchoice
config IX_IMAGE_ITB_QCOW_BOOT_DATA
config IMAGE_ITB_QCOW_BOOT_DATA
string "Bootloader data"
depends on IX_IMAGE_ITB_QCOW
depends on IX_IMAGE_ITB_QCOW_BOOT_EFI || IX_IMAGE_ITB_QCOW_BOOT_BIN
depends on IMAGE_ITB_QCOW
depends on IMAGE_ITB_QCOW_BOOT_EFI || IMAGE_ITB_QCOW_BOOT_BIN
default "${BINARIES_DIR}/efi-part/EFI" if BR2_x86_64
help
Path to the directory or file holding the bootloader data.
config IX_IMAGE_ITB_QCOW_BOOT_OFFSET
config IMAGE_ITB_QCOW_BOOT_OFFSET
hex "Bootloader offset"
depends on IX_IMAGE_ITB_QCOW
depends on IX_IMAGE_ITB_QCOW_BOOT_EFI || IX_IMAGE_ITB_QCOW_BOOT_BIN
depends on IMAGE_ITB_QCOW
depends on IMAGE_ITB_QCOW_BOOT_EFI || IMAGE_ITB_QCOW_BOOT_BIN
default 0x8000
help
Offset at which the bootloader partition is placed. Remember
@@ -6,8 +6,8 @@
# We can source the rootfs+aux from a local build, or from a
# downloaded release; so adjust our dependencies accordingly.
IMAGE_ITB_QCOW_SRC-$(IX_IMAGE_ITB_ROOTFS) := image-itb-rootfs image-itb-aux
IMAGE_ITB_QCOW_SRC-$(IX_IMAGE_ITB_DL_RELEASE) := image-itb-dl-release
IMAGE_ITB_QCOW_SRC-$(IMAGE_ITB_ROOTFS) := image-itb-rootfs image-itb-aux
IMAGE_ITB_QCOW_SRC-$(IMAGE_ITB_DL_RELEASE) := image-itb-dl-release
IMAGE_ITB_QCOW_DEPENDENCIES := host-genimage $(IMAGE_ITB_QCOW_SRC-y)
IMAGE_ITB_QCOW_CONFIG_VARS := BOOT_DATA BOOT_OFFSET SIZE
+6 -6
View File
@@ -1,23 +1,23 @@
menuconfig IX_IMAGE_ITB_RAUC
menuconfig IMAGE_ITB_RAUC
bool "RAUC upgrade bundle (ITB)"
select IX_IMAGE_ITB_ROOTFS
select IMAGE_ITB_ROOTFS
select BR2_PACKAGE_HOST_RAUC
help
Create RAUC upgrade bundle, for targets using ITB images,
that can be used to upgrade a running system to this version
of Infix.
config IX_IMAGE_ITB_RAUC_KEY
config IMAGE_ITB_RAUC_KEY
string "signing key"
depends on IX_IMAGE_ITB_RAUC
depends on IMAGE_ITB_RAUC
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.key"
help
Path to the private key, in PKCS#8 format, used to sign
the RAUC bundle; or a PKCS#11 URI.
config IX_IMAGE_ITB_RAUC_CERT
config IMAGE_ITB_RAUC_CERT
string "signing certificate"
depends on IX_IMAGE_ITB_RAUC
depends on IMAGE_ITB_RAUC
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.crt"
help
Path to the X509 certificate which will be associated with
@@ -1,4 +1,4 @@
menuconfig IX_IMAGE_ITB_ROOTFS
menuconfig IMAGE_ITB_ROOTFS
bool "rootfs.itb+.itbh"
select BR2_TARGET_ROOTFS_SQUASHFS
select BR2_PACKAGE_HOST_UBOOT_TOOLS
@@ -7,9 +7,9 @@ menuconfig IX_IMAGE_ITB_ROOTFS
and extract detached header (.itbh) for U-Boot based
targets.
config IX_IMAGE_ITB_ROOTFS_KEY
config IMAGE_ITB_ROOTFS_KEY
string "signing key"
depends on IX_IMAGE_ITB_ROOTFS
depends on IMAGE_ITB_ROOTFS
default "${BR2_EXTERNAL_INFIX_PATH}/board/common/signing-keys/development/infix.key"
help
Path to the private RSA key, in PKCS#8 format, used to sign
+1 -1
View File
@@ -1,4 +1,4 @@
config IX_IMAGE_README
config IMAGE_README
bool "Install README.md in images"
help
Install a README.md with useful information about getting
@@ -13,6 +13,6 @@ $(BINARIES_DIR)/README.md: $(IMAGE_README_DIR)/README.md
@mkdir -p $(BINARIES_DIR)
@cp $< $@
ifeq ($(IX_IMAGE_README),y)
ifeq ($(IMAGE_README),y)
TARGETS_ROOTFS += image-readme
endif
+4 -6
View File
@@ -12,17 +12,15 @@ $(1): $$($(2)_DEPENDENCIES)
BINARIES_DIR=$$(BINARIES_DIR) \
BR2_EXTERNAL_INFIX_PATH=$$(BR2_EXTERNAL_INFIX_PATH) \
ARTIFACT=$$(INFIX_ARTIFACT) \
COMPATIBLE=$$(IX_COMPATIBLE) \
COMPATIBLE=$$(INFIX_COMPATIBLE) \
VERSION=$$(INFIX_VERSION) \
$$(foreach var,$$($(2)_CONFIG_VARS),$$(var)=$$($(3)_$$(var)) ) \
$$(foreach var,$$($(2)_CONFIG_VARS),$$(var)=$$($(2)_$$(var)) ) \
$$($(2)_DIR)/generate.sh $$($(2)_OPTS)
ifeq ($$($(3)),y)
ifeq ($$($(2)),y)
TARGETS_ROOTFS += $(1)
endif
endef
# $(2) is the package-local make-var prefix (UPPERCASE pkgname); $(3) is
# the IX_ prefixed Kconfig symbol name, see issue #1305.
ix-image = $(call inner-ix-image,$(pkgname),$(call UPPERCASE,$(pkgname)),IX_$(call UPPERCASE,$(pkgname)))
ix-image = $(call inner-ix-image,$(pkgname),$(call UPPERCASE,$(pkgname)))
+1 -1
View File
@@ -16,7 +16,7 @@ die()
# DISK_IMAGE_SIZE="512"
# etc.
#
# Nested variables, like IX_COMPATIBLE="${IX_IMAGE_ID}"
# Nested variables, like INFIX_COMPATIBLE="${INFIX_IMAGE_ID}"
# are handled by sourcing the file in a subshell.
#
# shellcheck disable=SC1090
+19 -45
View File
@@ -37,7 +37,7 @@ EOF
}
if [ -f "$TARGET_DIR/etc/rauc/system.conf" ]; then
sed -i "s/compatible=.*/compatible=$IX_COMPATIBLE/" "$TARGET_DIR/etc/rauc/system.conf"
sed -i "s/compatible=.*/compatible=$INFIX_COMPATIBLE/" "$TARGET_DIR/etc/rauc/system.conf"
fi
if [ -n "${ID_LIKE}" ]; then
@@ -53,40 +53,40 @@ cp "$TARGET_DIR/etc/hostname" "$TARGET_DIR/etc/hostname.d/10-default"
ixmsg "Creating /etc/os-release"
rm -f "$TARGET_DIR/etc/os-release"
{
echo "NAME=\"$IX_NAME\""
echo "ID=$IX_ID"
echo "PRETTY_NAME=\"$IX_TAGLINE $INFIX_VERSION\""
echo "NAME=\"$INFIX_NAME\""
echo "ID=$INFIX_ID"
echo "PRETTY_NAME=\"$INFIX_TAGLINE $INFIX_VERSION\""
echo "ID_LIKE=\"${ID}\""
echo "DEFAULT_HOSTNAME=$BR2_TARGET_GENERIC_HOSTNAME"
echo "VERSION=\"${INFIX_VERSION}\""
echo "VERSION_ID=${INFIX_VERSION}"
echo "BUILD_ID=\"${INFIX_BUILD_ID}\""
if [ -n "$IX_IMAGE_ID" ]; then
echo "IMAGE_ID=\"$IX_IMAGE_ID\""
if [ -n "$INFIX_IMAGE_ID" ]; then
echo "IMAGE_ID=\"$INFIX_IMAGE_ID\""
fi
if [ -n "$INFIX_RELEASE" ]; then
echo "IMAGE_VERSION=\"$INFIX_RELEASE\""
fi
echo "ARCHITECTURE=\"${IX_ARCH}\""
echo "HOME_URL=$IX_HOME"
if [ -n "$IX_VENDOR" ]; then
echo "VENDOR_NAME=\"$IX_VENDOR\""
echo "ARCHITECTURE=\"${INFIX_ARCH}\""
echo "HOME_URL=$INFIX_HOME"
if [ -n "$INFIX_VENDOR" ]; then
echo "VENDOR_NAME=\"$INFIX_VENDOR\""
fi
if [ -n "$IX_VENDOR_HOME" ]; then
echo "VENDOR_HOME=\"$IX_VENDOR_HOME\""
if [ -n "$INFIX_VENDOR_HOME" ]; then
echo "VENDOR_HOME=\"$INFIX_VENDOR_HOME\""
fi
if [ -n "$IX_DOC" ]; then
echo "DOCUMENTATION_URL=\"$IX_DOC\""
if [ -n "$INFIX_DOC" ]; then
echo "DOCUMENTATION_URL=\"$INFIX_DOC\""
fi
if [ -n "$IX_SUPPORT" ]; then
echo "SUPPORT_URL=\"$IX_SUPPORT\""
if [ -n "$INFIX_SUPPORT" ]; then
echo "SUPPORT_URL=\"$INFIX_SUPPORT\""
fi
if [ -n "$IX_DESC" ]; then
echo "INFIX_DESC=\"$IX_DESC\""
if [ -n "$INFIX_DESC" ]; then
echo "INFIX_DESC=\"$INFIX_DESC\""
fi
} > "$TARGET_DIR/etc/os-release"
echo "$IX_TAGLINE $INFIX_VERSION -- $(date +"%b %e %H:%M %Z %Y")" > "$TARGET_DIR/etc/version"
echo "$INFIX_TAGLINE $INFIX_VERSION -- $(date +"%b %e %H:%M %Z %Y")" > "$TARGET_DIR/etc/version"
ixmsg "Creating /etc/version: $(cat "$TARGET_DIR/etc/version")"
# In case of ambguities, this is what the image was built from
@@ -120,29 +120,3 @@ grep -qsE '^/bin/clish$$' "$TARGET_DIR/etc/shells" \
if [ "$BR2_PACKAGE_HOST_PYTHON_YANGDOC" = "y" ]; then
mkyangdoc "$BINARIES_DIR/yangdoc.html"
fi
# Bundle the mkdocs User's Guide into the rootfs, served by the WebUI's
# nginx at /guide/. Only when the WebUI is present (nothing serves it
# otherwise, and it keeps minimal images small) and mkdocs is on the build
# host. Best-effort: a failed build warns but does not abort the image
# build, and the WebUI hides its User Guide entry when the docs are absent.
mkuserguide()
{
local cfg dst
cfg="$(readlink -f "$common/../..")/mkdocs.yml"
dst="$TARGET_DIR/var/www/guide"
if ! command -v mkdocs >/dev/null 2>&1; then
ixmsg "mkdocs not found, skipping User's Guide bundling"
return
fi
ixmsg "Building User's Guide into $dst"
if ! mkdocs build -f "$cfg" -d "$dst" --clean --quiet; then
ixmsg "WARNING: mkdocs build failed, shipping without on-device User's Guide"
rm -rf "$dst"
fi
}
if [ "$BR2_PACKAGE_WEBUI" = "y" ]; then
mkuserguide
fi
+92 -92
View File
@@ -1,85 +1,85 @@
mainmenu "QEMU Virtualization"
config IX_QEMU_ARCH_IS_32
config QEMU_ARCH_IS_32
bool
config IX_QEMU_ARCH_IS_64
config QEMU_ARCH_IS_64
bool
choice
prompt "Target Architecture"
default @ARCH@
config IX_QEMU_riscv64
bool "riscv64"
select IX_QEMU_ARCH_IS_64
config QEMU_riscv64
bool "risv64"
select QEMU_ARCH_IS_64
config IX_QEMU_x86_64
config QEMU_x86_64
bool "x86_64"
select IX_QEMU_ARCH_IS_64
select QEMU_ARCH_IS_64
config IX_QEMU_arm
config QEMU_arm
bool "AArch32 (little endian)"
select IX_QEMU_ARCH_IS_32
select QEMU_ARCH_IS_32
config IX_QEMU_aarch64
config QEMU_aarch64
bool "AArch64 (little endian)"
select IX_QEMU_ARCH_IS_64
select QEMU_ARCH_IS_64
endchoice
choice
prompt "Loader"
default IX_QEMU_LOADER_KERNEL
default QEMU_LOADER_KERNEL
config IX_QEMU_LOADER_KERNEL
config QEMU_LOADER_KERNEL
bool "Kernel"
config IX_QEMU_LOADER_UBOOT
config QEMU_LOADER_UBOOT
bool "U-Boot"
depends on IX_QEMU_aarch64
depends on QEMU_aarch64
config IX_QEMU_LOADER_OVMF
config QEMU_LOADER_OVMF
bool "OVMF (UEFI)"
depends on IX_QEMU_x86_64
depends on QEMU_x86_64
endchoice
choice
prompt "Rootfs type"
default IX_QEMU_ROOTFS_INITRD
default QEMU_ROOTFS_INITRD
config IX_QEMU_ROOTFS_MMC
config QEMU_ROOTFS_MMC
bool "MMC"
depends on IX_QEMU_aarch64
depends on QEMU_aarch64
config IX_QEMU_ROOTFS_INITRD
config QEMU_ROOTFS_INITRD
bool "Initrd"
depends on IX_QEMU_LOADER_KERNEL
depends on QEMU_LOADER_KERNEL
config IX_QEMU_ROOTFS_VSCSI
config QEMU_ROOTFS_VSCSI
bool "Virtio SCSI"
endchoice
choice
prompt "Console"
default IX_QEMU_CONSOLE_SERIAL if IX_QEMU_arm
default IX_QEMU_CONSOLE_VIRTIO
default QEMU_CONSOLE_SERIAL if QEMU_arm
default QEMU_CONSOLE_VIRTIO
config IX_QEMU_CONSOLE_VIRTIO
config QEMU_CONSOLE_VIRTIO
bool "Virtio (hvc0)"
config IX_QEMU_CONSOLE_SERIAL
config QEMU_CONSOLE_SERIAL
bool "Serial (ttyS0/ttyAMA0)"
depends on !IX_QEMU_LOADER_OVMF
depends on !QEMU_LOADER_OVMF
endchoice
config IX_QEMU_MACHINE
config QEMU_MACHINE
string "Select emulated machine"
default "qemu-system-arm -M virt,accel=kvm:tcg -cpu max" if IX_QEMU_arm
default "qemu-system-aarch64 -M virt,accel=kvm:tcg -cpu cortex-a53" if IX_QEMU_aarch64
default "qemu-system-x86_64 -M pc,accel=kvm:tcg -cpu max" if IX_QEMU_x86_64
default "qemu-system-arm -M virt,accel=kvm:tcg -cpu max" if QEMU_arm
default "qemu-system-aarch64 -M virt,accel=kvm:tcg -cpu cortex-a53" if QEMU_aarch64
default "qemu-system-x86_64 -M pc,accel=kvm:tcg -cpu max" if QEMU_x86_64
help
You should not have to change this setting, although you may
want to tweak it, or change the acceleration.
@@ -88,7 +88,7 @@ config IX_QEMU_MACHINE
the defconfig you started with. Currently Infix supports
arm (AArch32), aarch64 (ARM64), and x86_64 (AMD64).
config IX_QEMU_MACHINE_RAM
config QEMU_MACHINE_RAM
string "RAM size (k/M/G)"
default "448M"
help
@@ -96,62 +96,62 @@ config IX_QEMU_MACHINE_RAM
if you get kernel panic with: "System is deadlocked on memory",
try increasing this one.
config IX_QEMU_KERNEL
config QEMU_KERNEL
string
depends on IX_QEMU_LOADER_KERNEL
default "../zImage" if IX_QEMU_arm
default "../Image" if IX_QEMU_aarch64
default "../bzImage" if IX_QEMU_x86_64
depends on QEMU_LOADER_KERNEL
default "../zImage" if QEMU_arm
default "../Image" if QEMU_aarch64
default "../bzImage" if QEMU_x86_64
config IX_QEMU_BIOS
config QEMU_BIOS
string
depends on !IX_QEMU_LOADER_KERNEL
default "../u-boot.bin" if IX_QEMU_LOADER_UBOOT
default "../OVMF.fd" if IX_QEMU_LOADER_OVMF
depends on !QEMU_LOADER_KERNEL
default "../u-boot.bin" if QEMU_LOADER_UBOOT
default "../OVMF.fd" if QEMU_LOADER_OVMF
config IX_QEMU_ROOTFS
config QEMU_ROOTFS
string
default "@DISK_IMG@" if !IX_QEMU_ROOTFS_INITRD
default "../rootfs.squashfs" if IX_QEMU_ROOTFS_INITRD
default "@DISK_IMG@" if !QEMU_ROOTFS_INITRD
default "../rootfs.squashfs" if QEMU_ROOTFS_INITRD
config IX_QEMU_DTB_EXTEND
config QEMU_DTB_EXTEND
bool
depends on IX_QEMU_LOADER_UBOOT
default y if IX_QEMU_aarch64
depends on QEMU_LOADER_UBOOT
default y if QEMU_aarch64
if IX_QEMU_ROOTFS_INITRD
if QEMU_ROOTFS_INITRD
config IX_QEMU_RW
config QEMU_RW
string "Writable /cfg layer"
depends on IX_QEMU_ROOTFS_INITRD
depends on QEMU_ROOTFS_INITRD
default "cfg.ext4"
config IX_QEMU_RW_VAR_OPT
config QEMU_RW_VAR_OPT
bool "Separate writable /var"
if IX_QEMU_RW_VAR_OPT
config IX_QEMU_RW_VAR_SIZE
if QEMU_RW_VAR_OPT
config QEMU_RW_VAR_SIZE
string "Size of /var"
default "256M"
config IX_QEMU_RW_VAR
config QEMU_RW_VAR
string "Writable /var layer"
default "var.ext4"
endif
endif
config IX_QEMU_VPD
config QEMU_VPD
bool "Emulate a Vital Product Data (VPD) Memory"
config IX_QEMU_HOST
config QEMU_HOST
string "Export host filesystem path"
default "/tmp"
config IX_QEMU_APPEND
config QEMU_APPEND
string "Extra kernel options"
depends on !IX_QEMU_ROOTFS_MMC
depends on !QEMU_ROOTFS_MMC
config IX_QEMU_EXTRA
config QEMU_EXTRA
string "Extra QEMU options"
@@ -159,72 +159,72 @@ comment "RTC"
choice
prompt "Mode"
default IX_QEMU_RTC_UTC
default QEMU_RTC_UTC
config IX_QEMU_RTC_UTC
config QEMU_RTC_UTC
bool "UTC"
config IX_QEMU_RTC_LOCAL
config QEMU_RTC_LOCAL
bool "Local time"
config IX_QEMU_RTC_RANDOM
config QEMU_RTC_RANDOM
bool "Random"
endchoice
choice
prompt "Clock"
default IX_QEMU_CLOCK_HOST
default QEMU_CLOCK_HOST
config IX_QEMU_CLOCK_HOST
config QEMU_CLOCK_HOST
bool "Host clock"
config IX_QEMU_CLOCK_RT
config QEMU_CLOCK_RT
bool "Independent (monotonic)"
config IX_QEMU_CLOCK_VM
config QEMU_CLOCK_VM
bool "Virtual"
endchoice
config IX_QEMU_RTC
config QEMU_RTC
string
default "utc" if IX_QEMU_RTC_UTC
default "localtime" if IX_QEMU_RTC_LOCAL
default "random" if IX_QEMU_RTC_RANDOM
default "utc" if QEMU_RTC_UTC
default "localtime" if QEMU_RTC_LOCAL
default "random" if QEMU_RTC_RANDOM
config IX_QEMU_CLOCK
config QEMU_CLOCK
string
default "host" if IX_QEMU_CLOCK_HOST
default "rt" if IX_QEMU_CLOCK_RT
default "vm" if IX_QEMU_CLOCK_VM
default "host" if QEMU_CLOCK_HOST
default "rt" if QEMU_CLOCK_RT
default "vm" if QEMU_CLOCK_VM
comment "Networking"
choice
prompt "Network Mode"
default IX_QEMU_NET_USER
default QEMU_NET_USER
config IX_QEMU_NET_NONE
config QEMU_NET_NONE
bool "None"
config IX_QEMU_NET_BRIDGE
config QEMU_NET_BRIDGE
bool "Bridged"
config IX_QEMU_NET_USER
config QEMU_NET_USER
bool "User"
config IX_QEMU_NET_TAP
config QEMU_NET_TAP
bool "TAP"
config IX_QEMU_NET_ROCKER
config QEMU_NET_ROCKER
bool "Rocker"
endchoice
config IX_QEMU_NET_MODEL
config QEMU_NET_MODEL
string "Interface model"
default "virtio-net-device" if IX_QEMU_arm
default "virtio-net-device" if QEMU_arm
default "virtio-net-pci"
help
The default, virtio-net-pci, NIC works for most use-cases, but
@@ -233,23 +233,23 @@ config IX_QEMU_NET_MODEL
Note: ARM 32-bit uses virtio-net-device (MMIO) by default.
config IX_QEMU_NET_BRIDGE_DEV
config QEMU_NET_BRIDGE_DEV
string "Bridge device"
depends on IX_QEMU_NET_BRIDGE
depends on QEMU_NET_BRIDGE
default "virbr0"
config IX_QEMU_NET_USER_OPTS
config QEMU_NET_USER_OPTS
string "User mode options"
depends on IX_QEMU_NET_USER
depends on QEMU_NET_USER
help
Extra -nic user,<OPTIONS>
config IX_QEMU_NET_TAP_N
config QEMU_NET_TAP_N
int "Number of TAPs"
depends on IX_QEMU_NET_TAP
depends on QEMU_NET_TAP
default 1
config IX_QEMU_NET_PORTS
config QEMU_NET_PORTS
int "Number of Rocker switch ports"
depends on IX_QEMU_NET_ROCKER
depends on QEMU_NET_ROCKER
default 10
+2 -2
View File
@@ -10,7 +10,7 @@ qemu-kconfig = \
BR2_CONFIG="$(BINARIES_DIR)/qemu/.config" \
$(BUILD_DIR)/buildroot-config/$(1) $(2) "$(BINARIES_DIR)/qemu/Config.in"
ifeq ($(IX_QEMU_SCRIPTS),y)
ifeq ($(QEMU_SCRIPTS),y)
.PHONY: run
run:
@@ -33,7 +33,7 @@ $(BINARIES_DIR)/qemu/run.sh: $(QEMU_SCRIPTS_DIR)/run.sh
$(BINARIES_DIR)/qemu/Config.in: $(QEMU_SCRIPTS_DIR)/Config.in.in
@mkdir -p $(dir $@)
@sed \
-e "s:@ARCH@:IX_QEMU_$(BR2_ARCH):" \
-e "s:@ARCH@:QEMU_$(BR2_ARCH):" \
-e "s:@DISK_IMG@:../$(INFIX_ARTIFACT).qcow2:" \
< $< >$@
+73 -73
View File
@@ -40,7 +40,7 @@ usage()
echo " ARGS1 Args before the '--' separator are for kernel space"
echo " -- Separator"
echo " ARGS2 Args after the '--' separator are for the init process"
echo " Also, qemu.cfg has IX_QEMU_APPEND which can affect this."
echo " Also, qemu.cfg has QEMU_APPEND which can affect this."
echo
echo "Example:"
echo " $prognm -- finit.debug"
@@ -62,45 +62,45 @@ load_qemucfg()
# shellcheck disable=SC1090
. "./.config"
[ "$CONFIG_IX_QEMU_MACHINE" ] || die "Missing IX_QEMU_MACHINE"
[ "$CONFIG_IX_QEMU_ROOTFS" ] || die "Missing IX_QEMU_ROOTFS"
[ "$CONFIG_QEMU_MACHINE" ] || die "Missing QEMU_MACHINE"
[ "$CONFIG_QEMU_ROOTFS" ] || die "Missing QEMU_ROOTFS"
[ -n "$CONFIG_IX_QEMU_KERNEL" ] && [ -n "$CONFIG_IX_QEMU_BIOS" ] \
&& die "IX_QEMU_KERNEL conflicts with IX_QEMU_BIOS"
[ -n "$CONFIG_QEMU_KERNEL" ] && [ -n "$CONFIG_QEMU_BIOS" ] \
&& die "QEMU_KERNEL conflicts with QEMU_BIOS"
[ -z "$CONFIG_IX_QEMU_KERNEL" ] && [ -z "$CONFIG_IX_QEMU_BIOS" ] \
&& die "IX_QEMU_KERNEL or IX_QEMU_BIOS must be set"
[ -z "$CONFIG_QEMU_KERNEL" ] && [ -z "$CONFIG_QEMU_BIOS" ] \
&& die "QEMU_KERNEL or QEMU_BIOS must be set"
}
loader_args()
{
if [ "$CONFIG_IX_QEMU_BIOS" ]; then
echo -n "-bios $CONFIG_IX_QEMU_BIOS "
elif [ "$CONFIG_IX_QEMU_KERNEL" ]; then
echo -n "-kernel $CONFIG_IX_QEMU_KERNEL "
if [ "$CONFIG_QEMU_BIOS" ]; then
echo -n "-bios $CONFIG_QEMU_BIOS "
elif [ "$CONFIG_QEMU_KERNEL" ]; then
echo -n "-kernel $CONFIG_QEMU_KERNEL "
fi
}
append_args()
{
# ARM 32-bit doesn't support virtio console properly, always use serial
if [ "$CONFIG_IX_QEMU_arm" ]; then
if [ "$CONFIG_QEMU_arm" ]; then
echo -n "console=ttyAMA0 "
elif [ "$CONFIG_IX_QEMU_CONSOLE_VIRTIO" ]; then
elif [ "$CONFIG_QEMU_CONSOLE_VIRTIO" ]; then
echo -n "console=hvc0 "
elif [ "$CONFIG_IX_QEMU_x86_64" ]; then
elif [ "$CONFIG_QEMU_x86_64" ]; then
echo -n "console=ttyS0 "
elif [ "$CONFIG_IX_QEMU_aarch64" ]; then
elif [ "$CONFIG_QEMU_aarch64" ]; then
echo -n "console=ttyAMA0 "
else
die "Unknown console"
fi
if [ "$CONFIG_IX_QEMU_ROOTFS_INITRD" = "y" ]; then
if [ "$CONFIG_QEMU_ROOTFS_INITRD" = "y" ]; then
# Size of initrd, rounded up to nearest kb
size=$((($(stat -c %s "$CONFIG_IX_QEMU_ROOTFS") + 1023) >> 10))
size=$((($(stat -c %s "$CONFIG_QEMU_ROOTFS") + 1023) >> 10))
echo -n "root=/dev/ram0 ramdisk_size=${size} "
elif [ "$CONFIG_IX_QEMU_ROOTFS_VSCSI" = "y" ]; then
elif [ "$CONFIG_QEMU_ROOTFS_VSCSI" = "y" ]; then
echo -n "root=PARTLABEL=primary "
fi
@@ -110,20 +110,20 @@ append_args()
echo -n "debug "
fi
echo -n "${IX_QEMU_APPEND} ${QEMU_EXTRA_APPEND} "
echo -n "${QEMU_APPEND} ${QEMU_EXTRA_APPEND} "
}
rootfs_args()
{
if [ "$CONFIG_IX_QEMU_ROOTFS_INITRD" = "y" ]; then
echo -n "-initrd $CONFIG_IX_QEMU_ROOTFS "
elif [ "$CONFIG_IX_QEMU_ROOTFS_MMC" = "y" ]; then
if [ "$CONFIG_QEMU_ROOTFS_INITRD" = "y" ]; then
echo -n "-initrd $CONFIG_QEMU_ROOTFS "
elif [ "$CONFIG_QEMU_ROOTFS_MMC" = "y" ]; then
echo -n "-device sdhci-pci "
echo -n "-device sd-card,drive=mmc "
echo -n "-drive id=mmc,file=$CONFIG_IX_QEMU_ROOTFS,if=none,format=raw "
elif [ "$CONFIG_IX_QEMU_ROOTFS_VSCSI" = "y" ]; then
echo -n "-drive id=mmc,file=$CONFIG_QEMU_ROOTFS,if=none,format=raw "
elif [ "$CONFIG_QEMU_ROOTFS_VSCSI" = "y" ]; then
# ARM 32-bit virt machine uses MMIO virtio devices, not PCI
if [ "$CONFIG_IX_QEMU_arm" ]; then
if [ "$CONFIG_QEMU_arm" ]; then
echo -n "-drive file=qemu.qcow2,if=none,format=qcow2,id=rootfs "
echo -n "-device virtio-blk-device,drive=rootfs "
else
@@ -140,9 +140,9 @@ serial_args()
echo -n "-chardev stdio,id=console0,mux=on "
echo -n "-mon chardev=console0 "
if [ "$CONFIG_IX_QEMU_CONSOLE_VIRTIO" ]; then
if [ "$CONFIG_QEMU_CONSOLE_VIRTIO" ]; then
echo -n "-device virtconsole,nr=0,name=console,chardev=console0 "
elif [ "$CONFIG_IX_QEMU_CONSOLE_SERIAL" ]; then
elif [ "$CONFIG_QEMU_CONSOLE_SERIAL" ]; then
echo -n "-serial chardev:console0 "
else
die "Unknown console"
@@ -175,7 +175,7 @@ usb_args()
rw_args()
{
[ "$CONFIG_IX_QEMU_RW" ] || return
[ "$CONFIG_QEMU_RW" ] || return
command -v mkfs.ext4 >/dev/null || die "$prognm: cannot find mkfs.ext4"
@@ -184,45 +184,45 @@ rw_args()
mkfs.ext4 -L aux "aux.ext4" >/dev/null 2>&1
fi
if ! [ -f "$CONFIG_IX_QEMU_RW" ]; then
dd if=/dev/zero of="$CONFIG_IX_QEMU_RW" bs=16M count=1 >/dev/null 2>&1
mkfs.ext4 -L cfg "$CONFIG_IX_QEMU_RW" >/dev/null 2>&1
if ! [ -f "$CONFIG_QEMU_RW" ]; then
dd if=/dev/zero of="$CONFIG_QEMU_RW" bs=16M count=1 >/dev/null 2>&1
mkfs.ext4 -L cfg "$CONFIG_QEMU_RW" >/dev/null 2>&1
fi
# ARM 32-bit virt machine uses MMIO virtio devices, not PCI
if [ "$CONFIG_IX_QEMU_arm" ]; then
if [ "$CONFIG_QEMU_arm" ]; then
echo -n "-drive file=aux.ext4,if=none,format=raw,id=aux "
echo -n "-device virtio-blk-device,drive=aux "
echo -n "-drive file=$CONFIG_IX_QEMU_RW,if=none,format=raw,id=cfg "
echo -n "-drive file=$CONFIG_QEMU_RW,if=none,format=raw,id=cfg "
echo -n "-device virtio-blk-device,drive=cfg "
if [ "$CONFIG_IX_QEMU_RW_VAR_OPT" ]; then
if ! [ -f "$CONFIG_IX_QEMU_RW_VAR" ]; then
dd if=/dev/zero of="$CONFIG_IX_QEMU_RW_VAR" bs=$CONFIG_IX_QEMU_RW_VAR_SIZE count=1 >/dev/null 2>&1
mkfs.ext4 -L var "$CONFIG_IX_QEMU_RW_VAR" >/dev/null 2>&1
if [ "$CONFIG_QEMU_RW_VAR_OPT" ]; then
if ! [ -f "$CONFIG_QEMU_RW_VAR" ]; then
dd if=/dev/zero of="$CONFIG_QEMU_RW_VAR" bs=$CONFIG_QEMU_RW_VAR_SIZE count=1 >/dev/null 2>&1
mkfs.ext4 -L var "$CONFIG_QEMU_RW_VAR" >/dev/null 2>&1
fi
echo -n "-drive file=$CONFIG_IX_QEMU_RW_VAR,if=none,format=raw,id=var "
echo -n "-drive file=$CONFIG_QEMU_RW_VAR,if=none,format=raw,id=var "
echo -n "-device virtio-blk-device,drive=var "
fi
else
echo -n "-drive file=aux.ext4,if=virtio,format=raw,bus=0,unit=3 "
echo -n "-drive file=$CONFIG_IX_QEMU_RW,if=virtio,format=raw,bus=0,unit=1 "
echo -n "-drive file=$CONFIG_QEMU_RW,if=virtio,format=raw,bus=0,unit=1 "
if [ "$CONFIG_IX_QEMU_RW_VAR_OPT" ]; then
if ! [ -f "$CONFIG_IX_QEMU_RW_VAR" ]; then
dd if=/dev/zero of="$CONFIG_IX_QEMU_RW_VAR" bs=$CONFIG_IX_QEMU_RW_VAR_SIZE count=1 >/dev/null 2>&1
mkfs.ext4 -L var "$CONFIG_IX_QEMU_RW_VAR" >/dev/null 2>&1
if [ "$CONFIG_QEMU_RW_VAR_OPT" ]; then
if ! [ -f "$CONFIG_QEMU_RW_VAR" ]; then
dd if=/dev/zero of="$CONFIG_QEMU_RW_VAR" bs=$CONFIG_QEMU_RW_VAR_SIZE count=1 >/dev/null 2>&1
mkfs.ext4 -L var "$CONFIG_QEMU_RW_VAR" >/dev/null 2>&1
fi
echo -n "-drive file=$CONFIG_IX_QEMU_RW_VAR,if=virtio,format=raw,bus=0,unit=2 "
echo -n "-drive file=$CONFIG_QEMU_RW_VAR,if=virtio,format=raw,bus=0,unit=2 "
fi
fi
}
host_args()
{
[ "$CONFIG_IX_QEMU_HOST" ] || return
[ "$CONFIG_QEMU_HOST" ] || return
echo -n "-virtfs local,path=$CONFIG_IX_QEMU_HOST,security_model=none,writeout=immediate,mount_tag=hostfs "
echo -n "-virtfs local,path=$CONFIG_QEMU_HOST,security_model=none,writeout=immediate,mount_tag=hostfs "
}
net_dev_args()
@@ -230,7 +230,7 @@ net_dev_args()
name="e$1"
mac=$(printf "02:00:00:00:00:%02x" "$1")
echo -n "-device $CONFIG_IX_QEMU_NET_MODEL,netdev=$name,mac=$mac "
echo -n "-device $CONFIG_QEMU_NET_MODEL,netdev=$name,mac=$mac "
echo "$name $mac" >>"$mactab"
}
@@ -252,29 +252,29 @@ net_args()
:> "$mactab"
echo -n "-fw_cfg name=opt/mactab,file=$mactab "
if [ "$CONFIG_IX_QEMU_NET_BRIDGE" = "y" ]; then
echo -n "-netdev bridge,id=e1,br=$CONFIG_IX_QEMU_NET_BRIDGE_DEV "
if [ "$CONFIG_QEMU_NET_BRIDGE" = "y" ]; then
echo -n "-netdev bridge,id=e1,br=$CONFIG_QEMU_NET_BRIDGE_DEV "
net_dev_args 1
elif [ "$CONFIG_IX_QEMU_NET_TAP" = "y" ]; then
for i in $(seq 1 "$CONFIG_IX_QEMU_NET_TAP_N"); do
elif [ "$CONFIG_QEMU_NET_TAP" = "y" ]; then
for i in $(seq 1 "$CONFIG_QEMU_NET_TAP_N"); do
echo -n "-netdev tap,id=e$i,ifname=qtap$i "
net_dev_args "$i"
done
elif [ "$CONFIG_IX_QEMU_NET_ROCKER" = "y" ]; then
elif [ "$CONFIG_QEMU_NET_ROCKER" = "y" ]; then
sw=sw0 # Only single switch support atm.
echo -n "-device '{\"driver\":\"rocker\", \"name\":\"${sw}\", "
echo -n "\"fp_start_macaddr\":\"02:00:00:00:00:01\", "
echo -n "\"ports\":["
for i in $(seq 1 "$CONFIG_IX_QEMU_NET_PORTS"); do
for i in $(seq 1 "$CONFIG_QEMU_NET_PORTS"); do
[ "$i" -gt 1 ] && echo -n ", "
echo -n "\"${sw}p${i}\""
done
echo -n "]}' "
for i in $(seq 1 "$CONFIG_IX_QEMU_NET_PORTS"); do
for i in $(seq 1 "$CONFIG_QEMU_NET_PORTS"); do
rocker_port_args 0 "$i"
done
elif [ "$CONFIG_IX_QEMU_NET_USER" = "y" ]; then
[ "$CONFIG_IX_QEMU_NET_USER_OPTS" ] && useropts=",$CONFIG_IX_QEMU_NET_USER_OPTS"
elif [ "$CONFIG_QEMU_NET_USER" = "y" ]; then
[ "$CONFIG_QEMU_NET_USER_OPTS" ] && useropts=",$CONFIG_QEMU_NET_USER_OPTS"
echo -n "-netdev user,id=e1${useropts} "
net_dev_args 1
else
@@ -285,7 +285,7 @@ net_args()
# Vital Product data
vpd_args()
{
[ "$CONFIG_IX_QEMU_VPD" = "y" ] || return
[ "$CONFIG_QEMU_VPD" = "y" ] || return
vpd_file="${qdir}/vpd"
@@ -324,8 +324,8 @@ random_date()
rtc_args()
{
rtc="${CONFIG_IX_QEMU_RTC:-utc}"
clock="${CONFIG_IX_QEMU_CLOCK:-host}"
rtc="${CONFIG_QEMU_RTC:-utc}"
clock="${CONFIG_QEMU_CLOCK:-host}"
if [ "$rtc" = "random" ]; then
rtc=$(random_date)
fi
@@ -358,28 +358,28 @@ extract_squashfs()
run_qemu()
{
# Auto-extract rootfs.squashfs from rootfs.itb if needed for initrd mode
if [ "$CONFIG_IX_QEMU_ROOTFS_INITRD" = "y" ] && [ ! -f "$CONFIG_IX_QEMU_ROOTFS" ]; then
itb="${CONFIG_IX_QEMU_ROOTFS%.squashfs}.itb"
if [ "$CONFIG_QEMU_ROOTFS_INITRD" = "y" ] && [ ! -f "$CONFIG_QEMU_ROOTFS" ]; then
itb="${CONFIG_QEMU_ROOTFS%.squashfs}.itb"
if [ -f "$itb" ]; then
extract_squashfs "$itb" "$CONFIG_IX_QEMU_ROOTFS"
extract_squashfs "$itb" "$CONFIG_QEMU_ROOTFS"
else
die "Missing $CONFIG_IX_QEMU_ROOTFS and cannot find $itb to extract it from"
die "Missing $CONFIG_QEMU_ROOTFS and cannot find $itb to extract it from"
fi
fi
if [ "$CONFIG_IX_QEMU_ROOTFS_VSCSI" = "y" ]; then
if [ "$CONFIG_QEMU_ROOTFS_VSCSI" = "y" ]; then
if ! qemu-img check "qemu.qcow2"; then
rm -f "qemu.qcow2"
fi
if [ ! -f "qemu.qcow2" ]; then
echo "Creating qcow2 disk image for Qemu ..."
qemu-img create -f qcow2 -o backing_file="$CONFIG_IX_QEMU_ROOTFS" \
qemu-img create -f qcow2 -o backing_file="$CONFIG_QEMU_ROOTFS" \
-F qcow2 "qemu.qcow2" > /dev/null
fi
fi
read -r qemu <<EOF
$CONFIG_IX_QEMU_MACHINE -nodefaults -m $CONFIG_IX_QEMU_MACHINE_RAM \
$CONFIG_QEMU_MACHINE -nodefaults -m $CONFIG_QEMU_MACHINE_RAM \
$(loader_args) \
$(rootfs_args) \
$(serial_args) \
@@ -391,14 +391,14 @@ run_qemu()
$(rtc_args) \
$(vpd_args) \
$(gdb_args) \
$CONFIG_IX_QEMU_EXTRA
$CONFIG_QEMU_EXTRA
EOF
# Save resulting command to a script, because I cannot for the life
# of me figure out how to embed the JSON snippet for Rocker and run
# it here without issues, spent way too much time on it -- Joachim
run=$(mktemp -t run.qemu.XXX)
echo "#!/bin/sh" > "$run"
if [ "$CONFIG_IX_QEMU_KERNEL" ]; then
if [ "$CONFIG_QEMU_KERNEL" ]; then
echo "$qemu -append \"$(append_args)\" $*" >> "$run"
else
echo "$qemu $*" >> "$run"
@@ -419,9 +419,9 @@ EOF
dtb_args()
{
[ "$CONFIG_IX_QEMU_LOADER_UBOOT" ] || return
[ "$CONFIG_QEMU_LOADER_UBOOT" ] || return
if [ "$CONFIG_IX_QEMU_DTB_EXTEND" ]; then
if [ "$CONFIG_QEMU_DTB_EXTEND" ]; then
# On the current architecture, QEMU will generate an internal
# DT based on the system configuration.
@@ -445,12 +445,12 @@ dtb_args()
generate_dot()
{
[ "$CONFIG_IX_QEMU_NET_TAP" = "y" ] || return
[ "$CONFIG_QEMU_NET_TAP" = "y" ] || return
hostports="<qtap1> qtap1"
targetports="<e1> e1"
edges="host:qtap1 -- target:e1 [kind=mgmt];"
for tap in $(seq 2 $((CONFIG_IX_QEMU_NET_TAP_N - 1))); do
for tap in $(seq 2 $((CONFIG_QEMU_NET_TAP_N - 1))); do
hostports="$hostports | <qtap$tap> qtap$tap "
targetports="$targetports | <e$tap> e$tap "
edges="$edges host:qtap$tap -- target:e$tap;"
@@ -485,7 +485,7 @@ EOF
menuconfig()
{
grep -q IX_QEMU_MACHINE Config.in || die "$prognm: must be run from the $$O/images/qemu directory"
grep -q QEMU_MACHINE Config.in || die "$prognm: must be run from the $$O/images/qemu directory"
command -v kconfig-mconf >/dev/null || die "$prognm: cannot find kconfig-mconf for menuconfig"
exec kconfig-mconf Config.in
}
+4
View File
@@ -1 +1,5 @@
CONFD_TIMEOUT=60
#DEBUG=1
# -v debug
CONFD_ARGS=""
-5
View File
@@ -1,5 +0,0 @@
RESTCONF_URL=https://127.0.0.1/restconf
INSECURE_TLS=1
# Spool firmware uploads (and any other temp files) to persistent storage
# instead of the RAM-backed /tmp to enable push-upgrades on low-memory systems.
TMPDIR=/var/tmp
@@ -5,3 +5,4 @@
4 static
5 dhcp
6 random
7 wwan
@@ -1 +0,0 @@
../restconf.app
@@ -1,3 +0,0 @@
allow 127.0.0.1;
allow ::1;
deny all;
@@ -1 +0,0 @@
restconf-access-local.conf
@@ -1,6 +1,5 @@
# /telemetry/optics is for streaming (not used atm)
location ~ ^/(restconf|yang|.well-known)/ {
include /etc/nginx/restconf-access.conf;
grpc_pass grpc://[::1]:10080;
grpc_set_header Host $host;
grpc_set_header X-Real-IP $remote_addr;
@@ -1,3 +0,0 @@
if [ -s /run/os-update ]; then
printf '\n\033[1;33m *** %s ***\033[0m\n\n' "$(cat /run/os-update)"
fi
@@ -24,10 +24,6 @@ net.ipv4.conf.all.arp_ignore=1
net.ipv4.ip_forward=1
net.ipv4.ip_forward_update_priority=0
# Allow binding to non-local addresses, e.g. floating VIPs not yet
# configured on an interface, see issue #1022
net.ipv4.ip_nonlocal_bind=1
net.ipv4.conf.all.forwarding=0
net.ipv4.conf.default.forwarding=0
@@ -7,10 +7,6 @@ net.ipv6.conf.all.ignore_routes_with_linkdown=1
net.ipv6.conf.all.forwarding=0
net.ipv6.conf.default.forwarding=0
# Allow binding to non-local addresses, e.g. floating VIPs not yet
# configured on an interface, see issue #1022
net.ipv6.ip_nonlocal_bind=1
# Accept router advertisements even when forwarding is enabled
net.ipv6.conf.all.accept_ra=2
net.ipv6.conf.default.accept_ra=2
@@ -1 +0,0 @@
f /run/os-update 0666 admin admin
@@ -620,6 +620,73 @@ def probe_ptp_capabilities(out):
out.setdefault("interfaces", {}).update(ifaces)
def _usb_root_from_sysfs(dev_path):
p = dev_path
while p not in ("/", "/sys"):
parent = os.path.realpath(os.path.join(p, ".."))
basename = os.path.basename(parent)
if basename.startswith("usb") and basename[3:].isdigit():
return parent
p = parent
return None
def _read_usb_vid_pid(dev_path):
p = dev_path
while p not in ("/", "/sys"):
try:
vid = open(os.path.join(p, "idVendor")).read().strip()
pid = open(os.path.join(p, "idProduct")).read().strip()
return vid, pid
except OSError:
pass
p = os.path.dirname(p)
return "", ""
def probe_modems(out):
"""devpath is the USB bus root; ModemManager matches by path prefix.
seen_roots deduplicates cdc-wdm and ttyUSB ports of the same physical modem."""
seen_roots = set()
modems = []
idx = 0
def add_modem(dev_path):
nonlocal idx
usb_root = _usb_root_from_sysfs(dev_path)
if usb_root is None or usb_root in seen_roots:
return
seen_roots.add(usb_root)
vid, pid = _read_usb_vid_pid(dev_path)
modems.append({
"index": idx,
"name": "modem%d" % idx,
"devpath": usb_root,
"vid": vid,
"pid": pid,
})
idx += 1
for cls_dir, prefix in (("/sys/class/usbmisc", "cdc-wdm"),
("/sys/class/tty", "ttyUSB")):
try:
entries = os.listdir(cls_dir)
except OSError:
continue
for entry in entries:
if not entry.startswith(prefix):
continue
try:
dev_path = os.path.realpath(
os.path.join(cls_dir, entry, "device"))
add_modem(dev_path)
except OSError:
pass
if modems:
out["modem"] = modems
def main():
out = {
"vendor": None,
@@ -647,6 +714,7 @@ def main():
probe_wifi_radios(out)
probe_ptp_capabilities(out)
probe_modems(out)
if not out["factory-password-hash"]:
sys.stdout.write("\n\n\033[31mCRITICAL BOOTSTRAP ERROR\n" +
-55
View File
@@ -1,55 +0,0 @@
#!/bin/sh
# Check for available software updates and notify on login if one exists.
# Called by the scheduler.
NOTIFY_FILE=/run/os-update
TAG=os-update
# Source os-release for VERSION and IMAGE_ID
if [ ! -f /etc/os-release ]; then
logger -t "$TAG" "ERROR: /etc/os-release not found"
exit 1
fi
. /etc/os-release
# Dev/dirty builds have no comparable semver — always show the latest release
IS_RELEASE=true
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then
IS_RELEASE=false
fi
# Read configured update-url from running config, fall back to upstream
UPDATE_URL=$(copy running-config \
-x '/ietf-system:system/infix-system:software/check-update/update-url' \
2>/dev/null \
| jq -r '.. | objects | ."update-url"? // empty')
UPDATE_URL=${UPDATE_URL:-"https://github.com/kernelkit/infix"}
# Derive API URL from the configured update URL.
# Default (github.com): https://github.com/org/repo → https://api.github.com/repos/org/repo
REPO=$(echo "$UPDATE_URL" | sed 's|https://github.com/||; s|/*$||')
API_URL="https://api.github.com/repos/${REPO}/releases/latest"
LATEST_TAG=$(curl -sSL --max-time 10 "$API_URL" 2>/dev/null \
| jq -r '.tag_name // empty')
if [ -z "$LATEST_TAG" ]; then
logger -p daemon.info -t "$TAG" "Update check skipped: could not reach ${API_URL}"
exit 0
fi
LATEST=${LATEST_TAG#v}
# Compare: is $1 strictly newer than $2?
newer() {
[ "$1" = "$2" ] && return 1
[ "$(printf '%s\n%s' "$1" "$2" | sort -V | tail -1)" = "$1" ]
}
if [ "$IS_RELEASE" = false ] || newer "$LATEST" "$VERSION"; then
RELEASE_URL="${UPDATE_URL}/releases/${LATEST_TAG}"
MSG="Software update available: ${LATEST_TAG}, running ${VERSION} (see ${RELEASE_URL})"
logger -t "$TAG" "$MSG"
printf '%s\n' "$MSG" > "$NOTIFY_FILE"
else
logger -p daemon.debug -t "$TAG" "No update available (current: $VERSION, latest: $LATEST)"
printf '' > "$NOTIFY_FILE"
fi
+1 -10
View File
@@ -25,7 +25,7 @@ define UBOOT_PRE_BUILD_INSTALL_KEY
$(HOST_DIR)/bin/dtc -a 1024 <(echo '/dts-v1/; / { signature {}; };') \
>$(@D)/infix-key.dtb
$(foreach key, \
$(call qstrip,$(IX_TRUSTED_KEYS_DEVELOPMENT_PATH)) $(call qstrip,$(IX_TRUSTED_KEYS_EXTRA_PATH)),\
$(call qstrip,$(TRUSTED_KEYS_DEVELOPMENT_PATH)) $(call qstrip,$(TRUSTED_KEYS_EXTRA_PATH)),\
$(call uboot-add-pubkey,$(key),$(@D)/infix-key.dtb))
$(HOST_DIR)/bin/dtc -I dtb -O dts \
<$(@D)/infix-key.dtb \
@@ -46,12 +46,3 @@ define UBOOT_PRE_BUILD_INSTALL_ENV
$(@D)/arch/$(UBOOT_ARCH)/dts/
endef
UBOOT_PRE_BUILD_HOOKS += UBOOT_PRE_BUILD_INSTALL_ENV
# Stamp non-release builds so they cannot be mistaken for a release,
# U-Boot's setlocalversion picks up .scmversion, see issue #919.
define UBOOT_PRE_BUILD_DEVEL_VERSION
echo "-DEVEL" >$(@D)/.scmversion
endef
ifeq ($(INFIX_RELEASE),)
UBOOT_PRE_BUILD_HOOKS += UBOOT_PRE_BUILD_DEVEL_VERSION
endif
+14 -14
View File
@@ -27,7 +27,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.40"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.34"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
@@ -143,12 +143,13 @@ BR2_PACKAGE_MARVELL_CN9130_CRB=y
BR2_PACKAGE_MARVELL_ESPRESSOBIN=y
BR2_PACKAGE_RASPBERRYPI_RPI64=y
BR2_PACKAGE_STYX_DCP_SC_28P=y
IX_VENDOR_HOME="https://www.kernelkit.org"
IX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
IX_HOME="https://github.com/kernelkit/infix/"
IX_DOC="https://www.kernelkit.org/infix/"
IX_SUPPORT="mailto:kernelkit@googlegroups.com"
INFIX_VENDOR_HOME="https://www.kernelkit.org"
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://www.kernelkit.org/infix/"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_FEATURE_GPS=y
BR2_PACKAGE_FEATURE_MODEM=y
BR2_PACKAGE_FEATURE_WIFI=y
BR2_PACKAGE_FEATURE_WIFI_MEDIATEK=y
BR2_PACKAGE_FEATURE_WIFI_QUALCOMM=y
@@ -175,6 +176,7 @@ BR2_PACKAGE_FIREWALL=y
BR2_PACKAGE_IITO=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
@@ -186,14 +188,12 @@ BR2_PACKAGE_PODMAN_DRIVER_DEVICEMAPPER=y
BR2_PACKAGE_PODMAN_DRIVER_VFS=y
BR2_PACKAGE_TETRIS=y
BR2_PACKAGE_ROUSETTE=y
# BR2_PACKAGE_LANDING is not set
BR2_PACKAGE_WEBUI=y
BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y
BR2_PACKAGE_HOST_PYTHON_YANGDOC=y
BR2_PACKAGE_PCIUTILS=y
IX_IMAGE_ITB_AUX=y
IX_IMAGE_ITB_QCOW=y
IX_IMAGE_ITB_RAUC=y
IX_IMAGE_README=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
IMAGE_ITB_AUX=y
IMAGE_ITB_QCOW=y
IMAGE_ITB_RAUC=y
IMAGE_README=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+12 -13
View File
@@ -27,7 +27,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.40"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.34"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
@@ -121,11 +121,11 @@ BR2_PACKAGE_MARVELL_CN9130_CRB=y
BR2_PACKAGE_MARVELL_ESPRESSOBIN=y
BR2_PACKAGE_RASPBERRYPI_RPI64=y
BR2_PACKAGE_STYX_DCP_SC_28P=y
IX_VENDOR_HOME="https://www.kernelkit.org"
IX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
IX_HOME="https://github.com/kernelkit/infix/"
IX_DOC="https://www.kernelkit.org/infix/"
IX_SUPPORT="mailto:kernelkit@googlegroups.com"
INFIX_VENDOR_HOME="https://www.kernelkit.org"
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://www.kernelkit.org/infix/"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_NETD=y
BR2_PACKAGE_CONFD_TEST_MODE=y
@@ -144,16 +144,15 @@ BR2_PACKAGE_FIREWALL=y
BR2_PACKAGE_IITO=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
BR2_PACKAGE_ONIEPROM=y
BR2_PACKAGE_ROUSETTE=y
BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y
IX_IMAGE_ITB_AUX=y
IX_IMAGE_ITB_QCOW=y
IX_IMAGE_ITB_RAUC=y
IX_IMAGE_README=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
IMAGE_ITB_AUX=y
IMAGE_ITB_QCOW=y
IMAGE_ITB_RAUC=y
IMAGE_README=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -25,5 +25,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+13 -15
View File
@@ -28,7 +28,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.40"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.34"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/arm/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
@@ -129,7 +129,6 @@ BR2_PACKAGE_HOST_DOSFSTOOLS=y
BR2_PACKAGE_HOST_E2FSPROGS=y
BR2_PACKAGE_HOST_ENVIRONMENT_SETUP=y
BR2_PACKAGE_HOST_GENEXT2FS=y
BR2_PACKAGE_HOST_GO_BIN=y
BR2_PACKAGE_HOST_KMOD_XZ=y
BR2_PACKAGE_HOST_MTOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
@@ -137,11 +136,11 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
BR2_PACKAGE_MICROCHIP_SAMA7G54_EK=y
BR2_PACKAGE_RASPBERRYPI_RPI2=y
IX_VENDOR_HOME="https://www.kernelkit.org"
IX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
IX_HOME="https://github.com/kernelkit/infix/"
IX_DOC="https://www.kernelkit.org/infix/"
IX_SUPPORT="mailto:kernelkit@googlegroups.com"
INFIX_VENDOR_HOME="https://www.kernelkit.org"
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://www.kernelkit.org/infix/"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_FEATURE_GPS=y
BR2_PACKAGE_FEATURE_WIFI_MEDIATEK=y
BR2_PACKAGE_FEATURE_WIFI_REALTEK=y
@@ -163,6 +162,7 @@ BR2_PACKAGE_FIREWALL=y
BR2_PACKAGE_IITO=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
@@ -170,13 +170,11 @@ BR2_PACKAGE_NETBROWSE=y
BR2_PACKAGE_ONIEPROM=y
BR2_PACKAGE_TETRIS=y
BR2_PACKAGE_ROUSETTE=y
# BR2_PACKAGE_LANDING is not set
BR2_PACKAGE_WEBUI=y
BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y
BR2_PACKAGE_HOST_PYTHON_YANGDOC=y
IX_IMAGE_ITB_AUX=y
IX_IMAGE_ITB_QCOW=y
IX_IMAGE_ITB_RAUC=y
IX_IMAGE_README=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
IMAGE_ITB_AUX=y
IMAGE_ITB_QCOW=y
IMAGE_ITB_RAUC=y
IMAGE_README=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+12 -13
View File
@@ -28,7 +28,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.40"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.34"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/arm/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
@@ -119,11 +119,11 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
BR2_PACKAGE_MICROCHIP_SAMA7G54_EK=y
BR2_PACKAGE_RASPBERRYPI_RPI2=y
IX_VENDOR_HOME="https://www.kernelkit.org"
IX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
IX_HOME="https://github.com/kernelkit/infix/"
IX_DOC="https://www.kernelkit.org/infix/"
IX_SUPPORT="mailto:kernelkit@googlegroups.com"
INFIX_VENDOR_HOME="https://www.kernelkit.org"
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://www.kernelkit.org/infix/"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_NETD=y
BR2_PACKAGE_CONFD_TEST_MODE=y
@@ -142,16 +142,15 @@ BR2_PACKAGE_FIREWALL=y
BR2_PACKAGE_IITO=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
BR2_PACKAGE_ONIEPROM=y
BR2_PACKAGE_ROUSETTE=y
BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y
IX_IMAGE_ITB_AUX=y
IX_IMAGE_ITB_QCOW=y
IX_IMAGE_ITB_RAUC=y
IX_IMAGE_README=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
IMAGE_ITB_AUX=y
IMAGE_ITB_QCOW=y
IMAGE_ITB_RAUC=y
IMAGE_README=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -40,5 +40,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -38,5 +38,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -38,5 +38,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -38,5 +38,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -38,5 +38,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -38,5 +38,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -38,5 +38,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -45,5 +45,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
BR2_PACKAGE_BOOTLOADER_SPLASHSCREEN=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+12 -14
View File
@@ -164,15 +164,14 @@ BR2_TARGET_UBOOT_SPL=y
BR2_TARGET_UBOOT_SPL_NAME="spl/u-boot-spl.bin.normal.out"
BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_INFIX_PATH)/board/riscv64/visionfive2/uboot/visionfive2-env.dtsi"
BR2_PACKAGE_HOST_BMAP_TOOLS=y
BR2_PACKAGE_HOST_GO_BIN=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_VENDOR_HOME="https://www.kernelkit.org"
IX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
IX_HOME="https://github.com/kernelkit/infix/"
IX_DOC="https://www.kernelkit.org/infix/"
IX_SUPPORT="mailto:kernelkit@googlegroups.com"
INFIX_VENDOR_HOME="https://www.kernelkit.org"
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://www.kernelkit.org/infix/"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_FEATURE_GPS=y
BR2_PACKAGE_FEATURE_WIFI=y
BR2_PACKAGE_FEATURE_WIFI_MEDIATEK=y
@@ -195,6 +194,7 @@ BR2_PACKAGE_FIREWALL=y
BR2_PACKAGE_IITO=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
@@ -206,14 +206,12 @@ BR2_PACKAGE_PODMAN_DRIVER_DEVICEMAPPER=y
BR2_PACKAGE_PODMAN_DRIVER_VFS=y
BR2_PACKAGE_TETRIS=y
BR2_PACKAGE_ROUSETTE=y
# BR2_PACKAGE_LANDING is not set
BR2_PACKAGE_WEBUI=y
BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y
BR2_PACKAGE_HOST_PYTHON_YANGDOC=y
BR2_PACKAGE_PCIUTILS=y
IX_IMAGE_ITB_AUX=y
IX_IMAGE_ITB_QCOW=y
IX_IMAGE_ITB_RAUC=y
IX_IMAGE_README=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
IMAGE_ITB_AUX=y
IMAGE_ITB_QCOW=y
IMAGE_ITB_RAUC=y
IMAGE_README=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -40,5 +40,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
BR2_PACKAGE_BOOTLOADER_SPLASHSCREEN=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -34,5 +34,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+2 -2
View File
@@ -34,5 +34,5 @@ BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+1 -1
View File
@@ -1,4 +1,4 @@
BR2_TARGET_ROOTFS_EXT2=y
BR2_TARGET_ROOTFS_EXT2_4=y
BR2_TARGET_ROOTFS_EXT2_SIZE="512M"
IX_IMAGE_EXT4_RAUC=y
IMAGE_EXT4_RAUC=y
-5
View File
@@ -1,5 +0,0 @@
# Prefer internal download mirror over official upstream sites. If
# the mirror is unreachable, e.g., off-site without VPN, Buildroot
# falls back to the upstream URL and then sources.buildroot.net
# Set up a local mirror and add IP to /etc/hosts to override
BR2_PRIMARY_SITE="http://mirror.internal/pub"
+13 -14
View File
@@ -26,7 +26,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.40"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.34"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
@@ -139,11 +139,11 @@ BR2_PACKAGE_HOST_MTOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_VENDOR_HOME="https://www.kernelkit.org"
IX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
IX_HOME="https://github.com/kernelkit/infix/"
IX_DOC="https://www.kernelkit.org/infix/"
IX_SUPPORT="mailto:kernelkit@googlegroups.com"
INFIX_VENDOR_HOME="https://www.kernelkit.org"
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://www.kernelkit.org/infix/"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_FEATURE_GPS=y
BR2_PACKAGE_FEATURE_WIFI=y
BR2_PACKAGE_FEATURE_WIFI_MEDIATEK=y
@@ -169,6 +169,7 @@ BR2_PACKAGE_FIREWALL=y
BR2_PACKAGE_IITO=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
@@ -180,14 +181,12 @@ BR2_PACKAGE_PODMAN_DRIVER_DEVICEMAPPER=y
BR2_PACKAGE_PODMAN_DRIVER_VFS=y
BR2_PACKAGE_TETRIS=y
BR2_PACKAGE_ROUSETTE=y
# BR2_PACKAGE_LANDING is not set
BR2_PACKAGE_WEBUI=y
BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y
BR2_PACKAGE_HOST_PYTHON_YANGDOC=y
BR2_PACKAGE_PCIUTILS=y
IX_IMAGE_ITB_AUX=y
IX_IMAGE_ITB_QCOW=y
IX_IMAGE_ITB_RAUC=y
IX_IMAGE_README=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
IMAGE_ITB_AUX=y
IMAGE_ITB_QCOW=y
IMAGE_ITB_RAUC=y
IMAGE_README=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+12 -13
View File
@@ -26,7 +26,7 @@ BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_INFIX_PATH}/board/common/rootfs ${BR2_EXTERNA
BR2_ROOTFS_POST_BUILD_SCRIPT="board/qemu/x86_64/post-build.sh ${BR2_EXTERNAL_INFIX_PATH}/board/common/post-build.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.40"
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.34"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/board/x86_64/linux_defconfig"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
@@ -118,11 +118,11 @@ BR2_PACKAGE_HOST_MTOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FDT_ADD_PUBKEY=y
IX_VENDOR_HOME="https://www.kernelkit.org"
IX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
IX_HOME="https://github.com/kernelkit/infix/"
IX_DOC="https://www.kernelkit.org/infix/"
IX_SUPPORT="mailto:kernelkit@googlegroups.com"
INFIX_VENDOR_HOME="https://www.kernelkit.org"
INFIX_DESC="Infix is an immutable, friendly, and secure operating system that turns any ARM or x86 device into a powerful, manageable network appliance. Deploy on anything from $35 Raspberry Pi boards to enterprise switches as routers, IoT gateways, or edge devices. Infix models Linux networking features using YANG so you can manage your devices using NETCONF/RESTCONF APIs and focus on your business logic running in isolated containers."
INFIX_HOME="https://github.com/kernelkit/infix/"
INFIX_DOC="https://www.kernelkit.org/infix/"
INFIX_SUPPORT="mailto:kernelkit@googlegroups.com"
BR2_PACKAGE_CONFD=y
BR2_PACKAGE_NETD=y
BR2_PACKAGE_CONFD_TEST_MODE=y
@@ -141,16 +141,15 @@ BR2_PACKAGE_FIREWALL=y
BR2_PACKAGE_IITO=y
BR2_PACKAGE_KEYACK=y
BR2_PACKAGE_KLISH_PLUGIN_INFIX=y
BR2_PACKAGE_LANDING=y
BR2_PACKAGE_LOWDOWN=y
BR2_PACKAGE_MCD=y
BR2_PACKAGE_MDNS_ALIAS=y
BR2_PACKAGE_ONIEPROM=y
BR2_PACKAGE_ROUSETTE=y
BR2_PACKAGE_RAUC_INSTALLATION_STATUS=y
IX_IMAGE_ITB_AUX=y
IX_IMAGE_ITB_QCOW=y
IX_IMAGE_ITB_RAUC=y
IX_IMAGE_README=y
IX_TRUSTED_KEYS=y
IX_TRUSTED_KEYS_DEVELOPMENT=y
IMAGE_ITB_AUX=y
IMAGE_ITB_QCOW=y
IMAGE_ITB_RAUC=y
IMAGE_README=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
+14 -75
View File
@@ -3,92 +3,33 @@ Change Log
All notable changes to the project are documented in this file.
[v26.08.0][UNRELEASED]
-------------------------
[v26.06.0][UNRELEASED]
--------------
### Changes
- Upgrade Linux kernel to 6.18.40 (LTS)
- Upgrade Buildroot to 2025.02.15 (LTS)
- Add support for firewall address-set (ipset): named sets of IP addresses and
networks, usable as zone sources for per-IP access control, issue #1189
- Build RPi64 SD card images in release builds
- Include .pkg files in release builds
### Fixes
- Fix annoying "cannot deselect all services" or reset to YANG default in the
web interface's firewall configuration page
[v26.06.0][] - 2026-07-01
-------------------------
> [!NOTE]
> Noteworthy changes and additions in this release:
>
> **🌐 Web Interface:** Infix gets its first-ever web interface! Browse live
> status and a full operational tree, handle common tasks from curated
> configuration pages, and drop into a YANG tree editor for everything else.
> A maintenance section covers firmware upgrade, backup & restore, and more.
>
> **📶 Wi-Fi Roaming & Mesh:** Access points sharing an SSID can hand clients
> off seamlessly with 802.11k/v/r, form a cable-free 802.11s mesh backhaul,
> and steer dual-band clients onto the faster 5/6 GHz band.
>
> **🗓️ System Scheduling:** Reusable time schedules based on ietf-schedule
> (RFC 9922) let features like scheduled reboot and software update checks
> run on a recurring, cron-style calendar.
### Changes
- Upgrade Linux kernel to 6.18.37 (LTS)
- Upgrade Buildroot to 2025.02.15 (LTS)
- Add basic web interface: static status pages and a tree view of operational
status. Curated configuration pages for some common tasks and a YANG tree
editor for the rest. Also includes a maintenance section for firmware
upgrade, backup & restore, and more
- Add Wi-Fi roaming for fast, seamless handoff between access points that
share an SSID: 802.11k, 802.11v and 802.11r (over-the-air FT). See the
[Wi-Fi][wifi] guide for details
[Wi-Fi User's Guide][wifi] for details
- Add Wi-Fi 802.11s mesh support, letting access points form a wireless
backhaul between each other without cabling
- Add band steering for dual-band access points, nudging dual-band
clients onto the faster 5/6 GHz band
- Add `legacy-rates` option to re-enable 802.11b rates on 2.4 GHz for
old IoT devices (disabled by default)
- Add system scheduling based on ietf-schedule (RFC 9922), using the
iCalendar recurrence grouping pruned to cron-expressible rules. Schedules
are reusable time-specs; features (`scheduled-reboot`,
`software/check-update`) trigger off them via a schedule reference
- Configuring multiple BSS (more than one SSID) on a single Wi-Fi radio now
requires an explicitly configured MAC address per BSS
- New operational `advertised-pmd-types` leaf-list on each Ethernet interface,
exposing the link modes currently advertised, to compare against the
`supported-pmd-types` introduced in v26.05.0
- Release assets no longer ship separate `.sha256` checksum files; the
download page now publishes a SHA-256 checksum for each asset directly
- Add cellular modem (WWAN) support for USB-attached MBIM/QMI modems,
including USB dongles, mPCIe cards, and M.2 Key-B modules. Multiple
APNs per modem, SIM PIN configuration, and NMEA routing from modem
GPS to gpsd. See the [Modem User's Guide][modem] for details
### Fixes
- Fix #941: a VETH pair can now connect two containers directly, with both
ends assigned to containers.
- Enabling IP masquerading in the firewall no longer enables IP forwarding on
all interfaces. This has been an issue ever since the firewall support was
introduced in v25.10.0
- Fix file permission regression in `/cfg/startup-config.cfg`, causing the
default `admin` user no permission to read or write the file from shell
- Fix admin url shown for HTTP/HTTPS links in <https://network.local> browser,
used pre-conflict resolution hostname.local, instead of hostname-2.local
- Fix unreadable per-port temperature sensor names in `show hardware` on
Marvell based switches: each sensor is now named after the front-panel port
it serves (e.g. `e1`, `e2`) instead of a raw device-tree path. `show
system` also reports a representative SoC temperature on CN913x platforms
- Fix missing `contact` and `location` settings in operational status; the
values were configurable but never returned on RESTCONF/NETCONF reads
- Fix spurious YANG validation warnings, for NTP and WireGuard configuration,
emitted on every NETCONF session and schema load
- Firewall masquerade no longer enables the global IPv4/IPv6 forwarding
sysctls. You must now enable IP forwarding explicitly on the interfaces
that should route traffic; enabling NAT alone is no longer enough
[wifi]: https://www.kernelkit.org/infix/latest/wifi/
[wifi]: https://www.kernelkit.org/infix/latest/wifi/
[modem]: https://www.kernelkit.org/infix/latest/modem/
[v26.05.0][] - 2026-05-29
-------------------------
@@ -149,7 +90,7 @@ All notable changes to the project are documented in this file.
[ethernet]: https://www.kernelkit.org/infix/latest/ethernet/#restricting-advertised-link-modes
[BPI-R3]: https://docs.banana-pi.org/en/BPI-R3/BananaPi_BPI-R3
[AcerConnectVero]: https://github.com/kernelkit/infix/tree/main/board/aarch64/acer-connect-vero-w6m
[AcerConnectVero]: https://github.com/kernelkit/infix/tree/main/board/aarch64/acer-connect-vero-w6m/
[v26.04.0][] - 2026-04-30
-------------------------
@@ -2222,9 +2163,7 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
- N/A
[buildroot]: https://buildroot.org/
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v26.06.0...HEAD
[v26.08.0]: https://github.com/kernelkit/infix/compare/v26.06.0...v26.08.0
[v26.06.0]: https://github.com/kernelkit/infix/compare/v26.05.0...v26.06.0
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v26.05.0...HEAD
[v26.05.0]: https://github.com/kernelkit/infix/compare/v26.04.0...v26.05.0
[v26.04.0]: https://github.com/kernelkit/infix/compare/v26.03.0...v26.04.0
[v26.03.0]: https://github.com/kernelkit/infix/compare/v26.02.0...v26.03.0
+1
View File
@@ -23,6 +23,7 @@ regression test system solely relies on NETCONF and RESTCONF.
- [Network Configuration](networking.md)
- [Wi-Fi](wifi.md)
- [DHCP Server](dhcp.md)
- [Cellular Modem (WWAN)](modem.md)
- [Syslog Support](syslog.md)
- **Infix In-Depth**
- [Boot Procedure](boot.md)
+2 -2
View File
@@ -28,7 +28,7 @@ Verify the result after a build by inspecting:
> [!IMPORTANT]
> To get a proper GIT revision (hash) from your OS spin, remember to set
> in menuconfig `IX_OEM_PATH`. When unset, the Infix `post-build.sh`
> in menuconfig `INFIX_OEM_PATH`. When unset, the Infix `post-build.sh`
> script defaults to the Infix base path. The revision is stored in the
> file `/etc/os-release` as `BUILD_ID`, also in the file `/etc/version`.
> See below for more info.
@@ -427,7 +427,7 @@ Used for `BUILD_ID` in `/etc/os-release`.
**Default:** `$(git describe --always --dirty --tags)`, from the _top
directory_. By default, the top directory refers to the root of the
Infix source tree, but this can be changed by setting the branding
variable `IX_OEM_PATH`, e.g. in a `defconfig` file or via `make
variable `INFIX_OEM_PATH`, e.g. in a `defconfig` file or via `make
menuconfig`, to the path of an enclosing br2-external.
#### `INFIX_RELEASE`
+5 -3
View File
@@ -668,9 +668,11 @@ set:
For an example of both, see the next section.
> [!TIP]
> Both ends of a VETH pair may be assigned to containers, connecting two
> containers directly without involving the host namespace.
> [!IMPORTANT]
> **VETH Pair Limitation:** When using VETH pairs with containers, at least
> one side of the pair must remain in the host namespace. It is currently
> not possible to create VETH pairs where both ends are assigned to different
> containers. One end must always be accessible from the host.
[^3]: Something which the container bridge network type does behind the
scenes with one end of an automatically created VETH pair.
+5 -16
View File
@@ -122,21 +122,13 @@ recommend using `pipx` to install the necessary tooling:
```bash
$ sudo apt install pipx
$ pipx install mkdocs
$ pipx inject mkdocs mkdocs-material pymdown-extensions mkdocs-callouts mike mkdocs-to-pdf mkdocs-glightbox
$ pipx inject mkdocs mkdocs-material pymdown-extensions mkdocs-callouts mike mkdocs-to-pdf
```
The `mike` and `mkdocs-to-pdf` packages are used for online versioning
and PDF generation by GitHub Actions, but since every plugin is listed
in `mkdocs.yml`, anyone who wants to preview the documentation has to
install all the tooling.
> [!IMPORTANT]
> MkDocs is also required to **build a WebUI image**. The build bundles
> the User's Guide into the image (served on-device at `/guide/`), so
> `make` runs `mkdocs build` from `post-build.sh` when the `webui`
> package is selected. If MkDocs is missing the build still succeeds,
> but the image ships without the on-device guide. Minimal images and
> any build without the `webui` package skip this step entirely.
The last two packages, `mike` and `mkdocs-to-pdf`, are used for online
versioning and PDF generation by GitHub Actions, but since they are in
the `mkdocs.yml` file, everyone who wants to preview the documentation
have to install all the tooling.
Preview with:
@@ -190,9 +182,6 @@ To apply a single snippet to the current output directory:
make apply-ext4 # build an ext4 rootfs (needed for boards
# whose bootloader lacks squashfs support,
# e.g. Marvell ESPRESSObin)
make apply-mirror # prefer an internal download mirror
# (BR2_PRIMARY_SITE) over upstream sites,
# see utils/mirror-sync.sh for populating it
The `apply-*` targets require an existing `.config` (i.e. you must have
already run a `make <board>_defconfig`). The snippet is merged using
-90
View File
@@ -223,96 +223,6 @@ The firewall includes over 100 pre-defined services, such as:
> See the YANG model for the full list, or tap the ++question++ key
> when setting up an allowed host service in a zone `set service`
## Address Sets
Address sets are named collections of IP addresses and networks that can be
used as zone *sources*, alongside the `network` setting. Traffic from a
member of the set is classified into that zone regardless of which interface
it arrives on. Since source matching takes precedence over interface
matching, an address set in a trusted zone can selectively lift devices out
of a restrictive interface zone.
This enables per-IP access control: block everything by default and grant
individual end devices access at runtime.
> [!IMPORTANT]
> Assigning an address set to a zone only decides which zone the source IP
> belongs to. It does **not** by itself grant access to the device. Access
> to HOST services is still controlled by the zone's `action` and `service`
> settings. A common pattern is to keep the interface or default zone
> restrictive (`reject`/`drop`) and attach the address set to a separate
> trusted zone with `action accept`, as shown below.
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit firewall address-set allowed</b>
admin@example:/config/firewall/…/allowed/> <b>set description "End devices granted access"</b>
admin@example:/config/firewall/…/allowed/> <b>set entry 192.168.1.40</b>
admin@example:/config/firewall/…/allowed/> <b>end</b>
admin@example:/config/firewall/> <b>edit zone trusted</b>
admin@example:/config/firewall/…/trusted/> <b>set action accept</b>
admin@example:/config/firewall/…/trusted/> <b>set address-set allowed</b>
admin@example:/config/firewall/…/trusted/> <b>leave</b>
</code></pre>
### Static and Dynamic Entries
Entries come in two kinds:
- **Static** entries are set in the configuration, like `192.168.1.40`
above, and are restored at boot
- **Dynamic** entries are added and removed at runtime using the `add`,
`remove`, and `flush` actions. They take effect immediately and survive
firewall configuration changes, but are *not* saved to the configuration,
so a reboot starts from a clean slate
From admin-exec context in the CLI:
<pre class="cli"><code>admin@example:/> <b>firewall address-set allowed add 192.168.1.42</b>
admin@example:/> <b>show firewall address-set allowed</b>
name : allowed
family : ipv4
timeout : none
ENTRY TYPE EXPIRES
192.168.1.40 static
192.168.1.42 dynamic
admin@example:/> <b>firewall address-set allowed remove 192.168.1.42</b>
</code></pre>
The same actions are available over NETCONF and RESTCONF, e.g., allowing a
device from a network management system:
```json
~$ curl -kX POST -u admin:admin -H "Content-Type: application/yang-data+json" \
-d '{"infix-firewall:input": {"entry": "192.168.1.42"}}' \
https://example.local/restconf/data/infix-firewall:firewall/address-set=allowed/add
```
Static entries can only be removed by changing the configuration, the
`remove` action manages dynamic entries only. The `flush` action removes
all dynamic entries at once, leaving static entries in place.
### Expiring Entries
An address set can be created with a `timeout`, giving every dynamic entry a
limited lifetime. Such sets are dynamic-only: static entries cannot be
configured, and entries cannot be removed manually, they expire on their
own. This suits time-limited access grants and automated ban lists.
<pre class="cli"><code>admin@example:/config/firewall/> <b>edit address-set banned</b>
admin@example:/config/firewall/…/banned/> <b>set timeout 3600</b>
admin@example:/config/firewall/…/banned/> <b>leave</b>
admin@example:/> <b>firewall address-set banned add 203.0.113.99</b>
</code></pre>
The remaining lifetime of each entry is shown in the `EXPIRES` column of
<kbd>show firewall address-set</kbd>.
> [!NOTE]
> Entries in timeout sets do not survive firewall configuration changes,
> the set is flushed when the firewall configuration is rebuilt. Regular
> (non-timeout) sets keep their dynamic entries over configuration changes.
## Examples
### End Device Protection
Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

+438
View File
@@ -0,0 +1,438 @@
# Cellular Modem (WWAN)
Infix supports cellular modem connectivity via modems that expose a
QMI or MBIM control interface over USB. Form factor does not matter:
USB dongles, mPCIe cards, and M.2 Key-B modules all work as long as
the modem chipset uses USB on the connector (the typical case for
4G/LTE modems). See *Supported Modems* below for the exceptions.
Setup involves three configuration items:
- A `modem0` hardware component for the physical modem
- A `sim0` hardware component for the SIM card slot
- A `wwan0` network interface that references both and carries the
bearer (APN) configuration
## Architecture
Infix uses a three-layer architecture for cellular modem support:
1. **Modem hardware component (modem0)**: the physical modem
- Configured via `ietf-hardware` with class `infix-hardware:modem`
- `admin-state` controls whether ModemManager and modemd are active
- Holds physical-layer config: allowed bands, preferred mode, location
- Auto-discovered into factory-default config when the modem is
present at first boot
2. **SIM hardware component (sim0)**: the SIM card slot
- Configured via `ietf-hardware` with class `infix-hardware:sim`
- Holds PIN/PUK credentials and carrier profile
- Auto-discovered into factory-default config alongside the modem
3. **Network interface (wwan0)**: data bearer to the cellular network
- Configured via `ietf-interfaces` with type `infix-if-type:modem`
- References a modem component and a SIM component
- Holds bearer config: APN, IP type, roaming, route preference,
authentication
- Always added by the user, never auto-created
## Naming Conventions
| **Name Pattern** | **Type** | **Description** |
|------------------|----------------------|-------------------------------------------------|
| `modemN` | Modem hardware | Hardware component for the physical modem |
| `simN` | SIM hardware | Hardware component for the SIM card slot |
| `wwanN` | Modem interface | Network interface for cellular data |
Where `N` is a number (0, 1, 2, ...).
> [!TIP]
> Using these naming conventions simplifies configuration since type and
> class are automatically inferred. Creating a hardware component named
> `modem0` automatically sets its class to `infix-hardware:modem`, and
> creating an interface named `wwan0` automatically sets its type to
> `infix-if-type:modem`.
>
> **Note:** This inference only works via the CLI. When configuring
> over NETCONF or RESTCONF the class and type must be set explicitly.
## Multi-Bearer (Multiple APNs)
Multiple wwan interfaces can reference the same modem component, each
with a different APN. Same idea as multi-SSID on a WiFi radio: one
hardware modem, several independent data connections.
Configure `wwan0` and `wwan1` both pointing to `modem0`:
```
edit interface wwan0 wwan
set modem modem0
set bearer apn internet
edit interface wwan1 wwan
set modem modem0
set bearer apn corporate.vpn.apn
```
## Current Limitations
- The modem must be present at boot. Hot-plug is not supported.
- If the modem is absent at boot, and no `probe-timeout` is set, a
dummy `wwan0` placeholder is created immediately so IP configuration
can proceed. A reboot is required once the hardware is inserted.
## Supported Modems
Modems exposing a CDC-WDM control interface over USB are supported,
regardless of physical form factor. Two protocols are handled by
ModemManager:
- **MBIM**: Mobile Broadband Interface Model (e.g. Sierra Wireless,
Quectel EM06/EM12)
- **QMI**: Qualcomm MSM Interface (e.g. Sierra Wireless EM7xxx,
Quectel EM/RMxxx)
Most 4G/LTE modules (USB dongles, mPCIe cards, M.2 Key-B) use USB on
the connector even when the slot also carries PCIe lanes. From Infix's
view they are all USB modems. PCIe-only modems (some 5G NR modules)
are not supported, since the modemd / ModemManager pipeline assumes a
USB-attached control interface.
## Step-by-step Setup
### 1. Hardware Detection
At first boot, USB modems detected by the kernel are written to
`/run/system.json` and added as hardware components in the
factory-default configuration. Verify the modem appears:
<pre class="cli"><code>admin@example:/> <b>show modem</b>
──────────────────────────────────────────────────────────────
<span class="title">Cellular Modems</span>
NAME MANUFACTURER MODEL STATE NETWORK SIGNAL
modem0 Quectel EM06-E registered lte good
──────────────────────────────────────────────────────────────
<span class="title">SIM Cards</span>
NAME SLOT STATE OPERATOR
sim0 1 unlocked Tele2
</code></pre>
The `STATE`, `SIM STATE`, and `SIGNAL` columns are color-coded so the
healthy / attention / problem cases are visible at a glance: green for
`registered`, `connected`, `unlocked`, `excellent`, `good`; yellow for
transient or attention states like `enabling`, `pin-required`, `poor`;
red for `failed`, `not-inserted`, `bad`.
If `modem0` does not appear:
- Verify the kernel sees the modem (`dmesg | grep -i mbim` or
`dmesg | grep -i qmi`). Without a kernel driver no further setup
is possible.
- On boards with a custom factory configuration, or after replacing
hardware on a running system, the components may need to be added
manually. See Step 2.
### 2. Hardware Components
If `show modem` already lists `modem0` and `sim0`, the components were
auto-discovered into the factory-default configuration and you can skip
ahead to Step 3.
Otherwise, add them manually. The class is inferred from the component
name (`modemN``infix-hardware:modem`, `simN``infix-hardware:sim`).
The `admin-state` must be set explicitly. There is no implicit default,
and without `unlocked` confd will not start ModemManager or modemd:
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit hardware component modem0</b>
admin@example:/config/hardware/component/modem0/> <b>set state admin-state unlocked</b>
admin@example:/config/hardware/component/modem0/> <b>end</b>
admin@example:/config/hardware/> <b>edit component sim0</b>
admin@example:/config/hardware/component/sim0/> <b>set state admin-state unlocked</b>
admin@example:/config/hardware/component/sim0/> <b>leave</b>
admin@example:/>
</code></pre>
To take the modem offline cleanly without removing the configuration,
set `admin-state locked`. All related services are stopped and the
bearer is torn down before the modem goes offline:
<pre class="cli"><code>admin@example:/config/> <b>edit hardware component modem0</b>
admin@example:/config/hardware/component/modem0/> <b>set state admin-state locked</b>
admin@example:/config/hardware/component/modem0/> <b>leave</b>
</code></pre>
#### Slow USB Modems
USB modems can be slow to enumerate at boot. The kernel wwan interface
may not appear until several seconds after confd starts applying
configuration. The `probe-timeout` leaf inside the `modem` hardware
configuration container controls how long confd waits. It defaults to
30 seconds when the container is present.
To enable the timeout, create the modem configuration container (this
also lets you configure bands, preferred mode, etc.):
<pre class="cli"><code>admin@example:/config/> <b>edit hardware component modem0 modem</b>
admin@example:/config/hardware/component/modem0/modem/> <b>leave</b>
</code></pre>
With `probe-timeout` at its default of 30, confd waits up to 30 seconds
for the wwan interface to appear before proceeding. For most modems it
is ready in 2-5 seconds. If the modem has not appeared within the
timeout, a dummy placeholder interface is created and a reboot is
required for the real interface to take over. Set `probe-timeout 0`
to disable waiting entirely.
> [!NOTE]
> Some Quectel modules (e.g. EM05) re-enumerate the USB device several
> times during a cold-boot firmware-init sequence that takes around 50
> to 60 seconds. Bump `probe-timeout` to 90 for those, otherwise the
> dummy placeholder fires before the modem settles and the real
> interface ends up with a different name (`wwan1` instead of `wwan0`).
### 3. Configure the Bearer (APN)
Bearer configuration lives on the `wwan0` interface. Reference the
modem hardware component and set the APN:
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface wwan0</b>
admin@example:/config/interface/wwan0/> <b>set wwan modem modem0</b>
admin@example:/config/interface/wwan0/> <b>set wwan sim sim0</b>
admin@example:/config/interface/wwan0/> <b>set wwan bearer apn internet</b>
admin@example:/config/interface/wwan0/> <b>leave</b>
</code></pre>
The modem will connect automatically once the bearer is configured and
the hardware is unlocked.
**Key bearer parameters:**
- `apn`: Access Point Name, required, provided by your operator
(e.g. `internet`, `data.vodafone.com`, `web.tele2.se`)
- `route-preference`: Administrative distance for the default route
(default: `200`). Higher value = lower priority. The default of 200
places cellular behind wired Ethernet (distance 5) and WiFi, so
cellular acts as a failover when the wired link is up
- `roaming`: Allow data when roaming on a foreign network
(default: `false`)
- `ip-type`: `ipv4`, `ipv6`, or `ipv4v6` dual-stack
(default: `ipv4v6`)
### 4. Configure Authentication
Most consumer APNs connect without credentials. If your operator
requires authentication, first store the password in the keystore, then
reference it from the bearer.
Create the keystore entry for the APN password:
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit keystore symmetric-key apn-pass</b>
admin@example:/config/keystore/…/apn-pass/> <b>set key-format passphrase-key-format</b>
admin@example:/config/keystore/…/apn-pass/> <b>change cleartext-symmetric-key</b>
Passphrase: ************
Retype passphrase: ************
admin@example:/config/keystore/…/apn-pass/> <b>leave</b>
</code></pre>
Then point the bearer's authentication at it:
<pre class="cli"><code>admin@example:/> <b>configure</b>
admin@example:/config/> <b>edit interface wwan0 wwan bearer</b>
admin@example:/config/interface/wwan0/wwan/bearer/> <b>set authentication username myuser</b>
admin@example:/config/interface/wwan0/wwan/bearer/> <b>set authentication password apn-pass</b>
admin@example:/config/interface/wwan0/wwan/bearer/> <b>leave</b>
</code></pre>
Setting any leaf inside `authentication` creates the container, which
enables authentication. The `password` leaf is a reference to a
symmetric key in the keystore, not the plaintext password itself.
The authentication protocol defaults to `chap`. To use PAP instead:
<pre class="cli"><code>admin@example:/config/interface/wwan0/wwan/bearer/> <b>set authentication type pap</b>
</code></pre>
### 5. Configure SIM PIN
If the SIM requires a PIN to unlock, configure it on the SIM hardware
component:
<pre class="cli"><code>admin@example:/config/> <b>edit hardware component sim0</b>
admin@example:/config/hardware/component/sim0/> <b>set sim pin 1234</b>
admin@example:/config/hardware/component/sim0/> <b>leave</b>
</code></pre>
### 6. Verify Connectivity
Once connected, the `wwan0` interface receives an IP address from the
carrier and modemd installs the default route:
<pre class="cli"><code>admin@example:/> <b>show interface wwan0</b>
name : wwan0
type : modem
index : 5
mtu : 1500
operational status : up
ip forwarding : enabled
physical address : 12:34:56:78:9a:bc
ipv4 addresses : 10.142.87.33/30 (wwan)
ipv6 addresses : 2001:db8:1:2::1/64 (wwan)
in-octets : 84213
out-octets : 31456
</code></pre>
Check the full modem state including signal quality and registration:
<pre class="cli"><code>admin@example:/> <b>show modem modem0</b>
<span class="header">MODEM: modem0 </span>
──────────────────────────────────────────────────────────────
<span class="title">Hardware Information</span>
Manufacturer : Quectel
Model : EM06-E
Firmware Version : EM06ELAR04A07M4G
Serial Number : 352753090141905
IMSI : 240021234567890
ICCID : 8946020000001234567
──────────────────────────────────────────────────────────────
<span class="title">Status</span>
State : connected
Power State : on
Signal : Quality: 72% good RSSI: -59 dBm RSRP: -95 dBm RSRQ: -11.0 dB
──────────────────────────────────────────────────────────────
<span class="title">Cellular</span>
Registration : home
Service State : attached
Operator : Tele2
Operator ID : 23002
Network Type : lte
──────────────────────────────────────────────────────────────
<span class="title">SIM Card</span>
Name : sim0
Slot : 1
Lock State : unlocked
Operator : Tele2
</code></pre>
When the modem is in trouble, the same view shows why. A
`State: failed` line is followed by `Failed Reason` (e.g.
`sim-missing`), and the `SIM Card` section's `Lock State` reads
`not-inserted` or `pin-required` to match.
## Cellular Failover
The default `route-preference` (200) is deliberately higher than the
distances used by wired Ethernet (udhcpc default: 5) and WiFi. When a
wired link is up it takes precedence automatically; cellular becomes
the active path only if higher-priority routes are withdrawn.
A default route via the bearer is always installed when the bearer
connects. To adjust the failover priority between two cellular modems,
or to prefer cellular over WiFi, set `route-preference` explicitly:
<pre class="cli"><code>admin@example:/config/> <b>edit interface wwan0 wwan bearer</b>
admin@example:/config/interface/wwan0/wwan/bearer/> <b>set route-preference 100</b>
admin@example:/config/interface/wwan0/wwan/bearer/> <b>leave</b>
</code></pre>
Lower `route-preference` = higher priority.
## Roaming
Data roaming is disabled by default. To allow the modem to connect
when on a foreign (roaming) network:
<pre class="cli"><code>admin@example:/config/> <b>edit interface wwan0 wwan bearer</b>
admin@example:/config/interface/wwan0/wwan/bearer/> <b>set roaming true</b>
admin@example:/config/interface/wwan0/wwan/bearer/> <b>leave</b>
</code></pre>
> [!IMPORTANT]
> Enabling roaming may incur significant charges depending on your
> mobile subscription. Check with your operator before enabling.
## Management Commands
### Restart Bearer
Disconnect and reconnect all bearers without resetting the modem
hardware. Use this after changing APN or authentication settings:
<pre class="cli"><code>admin@example:/> <b>modem restart modem0</b>
</code></pre>
### Reset Modem
Factory-reset the modem firmware. This clears all modem-internal
settings and takes longer than a restart. Only use it if the modem is
in a bad state that a bearer restart cannot fix:
<pre class="cli"><code>admin@example:/> <b>modem reset modem0</b>
</code></pre>
> [!NOTE]
> Not all modules accept `--reset` from ModemManager. Quectel EM05,
> for example, rejects both `--reset` and `--factory-reset`. The only
> way to recover from a hung firmware on these is a physical power
> cycle. When the modem reports the rejection, modemd logs it once and
> stops retrying.
### Send SMS
Send an SMS message via the signalling plane. No active data bearer
is required; the modem only needs to be registered on the network:
<pre class="cli"><code>admin@example:/> <b>modem sms modem0 +46701234567 "Hello from Infix"</b>
</code></pre>
> [!NOTE]
> Some SIM cards have Fixed Dialing Number (FDN) enabled, which
> restricts outgoing SMS and calls to a pre-configured whitelist. If
> `modem sms` fails, check whether FDN is active with `mmcli -m 0` and
> look for `enabled locks: fixed-dialing` in the output.
## Troubleshooting
**Modem not detected (`show modem` shows no modem entry)**
- Verify the modem is connected and recognized by the kernel: check
`dmesg` for `cdc_mbim` or `qmi_wwan` driver messages
- Confirm `/sys/class/usbmisc/` contains a `cdc-wdm*` entry
- The modem must be present at boot; hotplug after boot is not
supported
**`wwan0` shows as `down` or has no IP address**
- Check `show modem modem0`. The State should show `registered` or
`connected`, not `failed`
- If the State is `failed`, look at the `Failed Reason` line that
immediately follows:
- `sim-missing`: the SIM Card section will also show
`Lock State: not-inserted`. Power off the device, insert the
SIM, power back on. A warm reboot is not enough; on most M.2
slots the SIM tray stays powered through reboot, so the modem
keeps the original not-inserted reading
- `unlock-required`: the SIM Card section will show
`Lock State: pin-required`. Configure the PIN with
`set hardware component sim0 sim pin <code>`
- `sim-wrong` / `sim-error`: the SIM is not compatible or is
damaged. Try a different SIM
- Verify the APN is correct for your operator
- Check system logs with `show log` for modemd or ModemManager
messages
**`wwan0` interface is a dummy (no data flows, no carrier address)**
- The modem was not enumerated by the kernel before confd applied
config
- Create the modem hardware configuration container (see Step 2),
which enables the default 30-second probe-timeout so confd waits for
the wwan interface before falling back to a dummy placeholder
**High latency or poor signal**
- Use `show modem modem0` to check signal quality and RSRP
- Signal below -110 dBm RSRP typically indicates poor coverage
- Consider repositioning the antenna or the device
+6 -8
View File
@@ -1,15 +1,13 @@
IXMSG = printf "\e[37;44m>>> $(call qstrip,$(1))\e[0m\n"
oem-dir := $(call qstrip,$(IX_OEM_PATH))
oem-dir := $(call qstrip,$(INFIX_OEM_PATH))
INFIX_TOPDIR = $(if $(oem-dir),$(oem-dir),$(BR2_EXTERNAL_INFIX_PATH))
# Unless the user specifies an explicit build id, source it from git.
# Exclude the moving 'latest*' tags so the version always resolves to a
# real release tag, see issue #1524. The build id is also the version
# shown to users; INFIX_RELEASE only labels the release channel and names
# artifacts (see INFIX_ARTIFACT below).
export INFIX_BUILD_ID ?= $(shell git -C $(INFIX_TOPDIR) describe --dirty --always --tags --exclude 'latest*')
export INFIX_VERSION = $(INFIX_BUILD_ID)
export INFIX_ARTIFACT = $(call qstrip,$(IX_IMAGE_ID)$(if $(INFIX_RELEASE),-$(INFIX_RELEASE)))
# The build id also becomes the image version, unless an official
# release is being built.
export INFIX_BUILD_ID ?= $(shell git -C $(INFIX_TOPDIR) describe --dirty --always --tags)
export INFIX_VERSION = $(if $(INFIX_RELEASE),$(INFIX_RELEASE),$(INFIX_BUILD_ID))
export INFIX_ARTIFACT = $(call qstrip,$(INFIX_IMAGE_ID)$(if $(INFIX_RELEASE),-$(INFIX_RELEASE)))
INFIX_CFLAGS:=-Wall -Werror -Wextra -Wno-unused-parameter -Wformat=2 -Wformat-overflow=2 -Winit-self -Wstrict-overflow=4 -Wno-format-truncation -Wno-format-nonliteral
+1
View File
@@ -44,6 +44,7 @@ nav:
- Overview: vpn.md
- WireGuard: vpn-wireguard.md
- Wireless LAN (WiFi): wifi.md
- Cellular Modem (wwan): modem.md
- Services:
- Device Discovery: discovery.md
- DHCP Server: dhcp.md
+2 -1
View File
@@ -2,6 +2,7 @@ menu "Packages"
comment "Hardware Support"
source "$BR2_EXTERNAL_INFIX_PATH/package/feature-gps/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/feature-modem/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/feature-wifi/Config.in"
comment "Software Packages"
@@ -30,6 +31,7 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/landing/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/libsrx/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/lowdown/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/mcd/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/modemd/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/mdns-alias/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/netbrowse/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/onieprom/Config.in"
@@ -42,7 +44,6 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/tetris/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/libyang-cpp/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/sysrepo-cpp/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/rousette/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/webui/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/nghttp2-asio/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/date-cpp/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/rauc-installation-status/Config.in"
+6 -8
View File
@@ -1,11 +1,9 @@
#set DEBUG=1
# Single daemon handles gen-config, datastore init, config load, and plugins
# log:prio:daemon.err
service log:console env:/etc/default/confd \
service log:console env:/etc/default/confd \
[S12345] <usr/ixinit> confd -f -v warning \
-F /etc/factory-config.cfg \
-S /cfg/startup-config.cfg \
-E /etc/failure-config.cfg \
-t $CONFD_TIMEOUT \
-F /etc/factory-config.cfg \
-S /cfg/startup-config.cfg \
-E /etc/failure-config.cfg \
-t $CONFD_TIMEOUT \
$CONFD_ARGS \
-- Configuration daemon
+5 -7
View File
@@ -36,10 +36,8 @@ else
CONFD_CONF_OPTS += --disable-gps
endif
define CONFD_INSTALL_EXTRA
for fn in confd.conf crond.conf resolvconf.conf; do \
cp $(CONFD_PKGDIR)/$$fn $(FINIT_D)/available/; \
done
for fn in confd.conf resolvconf.conf; do \
cp $(CONFD_PKGDIR)/$$fn $(FINIT_D)/available/; \
ln -sf ../available/$$fn $(FINIT_D)/enabled/$$fn; \
done
cp $(CONFD_PKGDIR)/tmpfiles.conf $(TARGET_DIR)/etc/tmpfiles.d/confd.conf
@@ -93,10 +91,10 @@ define CONFD_INSTALL_YANG_MODULES_GPS
$(BR2_EXTERNAL_INFIX_PATH)/utils/srload $(@D)/yang/gps.inc
endef
endif
ifeq ($(BR2_PACKAGE_WEBUI),y)
define CONFD_INSTALL_YANG_MODULES_WEBUI
ifeq ($(BR2_PACKAGE_FEATURE_MODEM),y)
define CONFD_INSTALL_YANG_MODULES_MODEM
$(COMMON_SYSREPO_ENV) \
$(BR2_EXTERNAL_INFIX_PATH)/utils/srload $(@D)/yang/web.inc
$(BR2_EXTERNAL_INFIX_PATH)/utils/srload $(@D)/yang/modem.inc
endef
endif
@@ -129,7 +127,7 @@ CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES_CONTAINERS
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES_WIFI
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES_GPS
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES_WEBUI
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_YANG_MODULES_MODEM
CONFD_POST_INSTALL_TARGET_HOOKS += CONFD_INSTALL_IN_ROMFS
CONFD_TARGET_FINALIZE_HOOKS += CONFD_CLEANUP
-2
View File
@@ -1,2 +0,0 @@
# Cron daemon for infix-schedule
service [2345] crond -f -- Cron daemon
+25
View File
@@ -0,0 +1,25 @@
config BR2_PACKAGE_FEATURE_MODEM
bool "Feature Modem"
select BR2_PACKAGE_MODEMD
select BR2_PACKAGE_MODEM_MANAGER
select BR2_PACKAGE_MODEM_MANAGER_ATVIADBUS
select BR2_PACKAGE_MODEM_MANAGER_LIBMBIM
select BR2_PACKAGE_MODEM_MANAGER_LIBQMI
select BR2_PACKAGE_MODEM_MANAGER_LIBQRTR
help
Enables cellular modem support in Infix via ModemManager and
the modemd management daemon. Includes drivers for common
USB option modems and QMI/MBIM-based devices.
ATVIADBUS allows raw AT commands over D-Bus (used by modemd to
enable GPS NMEA output via vendor-specific AT commands such as
AT+QGPS=1) without needing to start ModemManager in --debug
mode.
config BR2_PACKAGE_FEATURE_MODEM_QUALCOMM
bool "Qualcomm-based modems (QMI/QRTR/MHI)"
depends on BR2_PACKAGE_FEATURE_MODEM
help
Adds kernel support for Qualcomm-based cellular modems that use
the MHI bus and QRTR IPC router (e.g. Sierra Wireless EM7xxx,
Quectel EM/RMxxx, Telit LN9xx).
+26
View File
@@ -0,0 +1,26 @@
################################################################################
#
# Cellular modem support
#
################################################################################
FEATURE_MODEM_PACKAGE_VERSION = 1.0
FEATURE_MODEM_PACKAGE_LICENSE = MIT
define FEATURE_MODEM_LINUX_CONFIG_FIXUPS
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_SERIAL)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_SERIAL_WWAN)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_SERIAL_OPTION)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_WDM)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_NET_QMI_WWAN)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_CDC_MBIM)
$(call KCONFIG_ENABLE_OPT,CONFIG_USB_NET_CDC_MBIM)
$(if $(filter y,$(BR2_PACKAGE_FEATURE_MODEM_QUALCOMM)),
$(call KCONFIG_SET_OPT,CONFIG_QRTR,m)
$(call KCONFIG_SET_OPT,CONFIG_MHI_BUS,m)
$(call KCONFIG_ENABLE_OPT,CONFIG_QRTR_MHI)
)
endef
$(eval $(generic-package))

Some files were not shown because too many files have changed in this diff Show More