diff --git a/.github/actions/README.md b/.github/actions/README.md index a1af3c60..850ac116 100644 --- a/.github/actions/README.md +++ b/.github/actions/README.md @@ -2,9 +2,7 @@ | Action | Owns | Called by | Notes | |--------|------|-----------|-------| -| **buildroot-build** | Runner prep (disk, apt, five caches) + `make all` (main) or `make ` (kernel-only). Outputs: `output/images/` or `output-/images/` + legal-info on demand. | build.yml, release.yml, reproducibility.yml | Single source of truth for the Buildroot recipe across three workflows. main's cache key strings are byte-identical to before the variant input existed; existing cache entries keep hitting. Kernel variants derive their own cache namespaces from fragment existence. | -| **kernel-leg** | One kernel-variant matrix leg: build via buildroot-build, render job summary, stage artifact (zImage_dtb + .config + modules tar + legal-info), upload for `build` to merge. | build.yml (build-kernel matrix), release.yml (build-kernel matrix) | Moves the 72-identical shared lines from build.yml and release.yml's own copies. Inputs: kernel, full-legal-info, release-context. | -| **merge-kernel-modules** | Two phases: (1) phase=download: download kernel-leg artifacts, populate work/extra-modules-overlay/ (runs BEFORE buildroot-build); (2) phase=verify: assert every kver merged into output/target/ (runs AFTER buildroot-build). | build.yml, release.yml | Phase-gated input enforces sequence discipline and prevents silent overlay misses. Called twice per workflow (download then verify). | +| **buildroot-build** | Runner prep (disk, apt, caches) + `make all`. Outputs: `output/images/` (linux.img, zImage_dtb, zImage_dtb-rt, mister-initramfs.cpio) + legal-info on demand. Since ADR 0030 Phase C the RT kernel and the stage-1 initramfs are packages of the one build, so there is no kernel-only variant mode any more (the `variant` input errors on anything but `main`). | build.yml, release.yml, reproducibility.yml | Single source of truth for the Buildroot recipe across three workflows. main's cache key strings are byte-identical to before the variant input existed; existing cache entries keep hitting. Kernel variants derive their own cache namespaces from fragment existence. | | **verify-image** | Run parity suite (P3.12) + ABI/SONAME checker (P2.2) against built image. Uploads results artifact on every run (`if: always()`). | build.yml, release.yml | Input: skip-qemu-system (default "true" — byte-identical to old hard-coded "1"). Both workflows used to carry identical copies. | ## Rule: When to Add a Fifth Action @@ -12,7 +10,7 @@ **Only add a new composite action when ALL of these hold:** 1. The work is genuinely self-contained (no dependencies within another action's phase). 2. Its failure modes are independent (a failure does NOT require coordination with an existing action's state). -3. No workflow sequence rule applies (if two actions must run in order with state between them, use a phase input instead — see `merge-kernel-modules`). +3. No workflow sequence rule applies (if two actions must run in order with state between them, use a phase input instead). **Otherwise, extend an existing action via inputs.** diff --git a/.github/actions/buildroot-build/action.yml b/.github/actions/buildroot-build/action.yml index 8a82c1e3..58b1dc3e 100644 --- a/.github/actions/buildroot-build/action.yml +++ b/.github/actions/buildroot-build/action.yml @@ -1,333 +1,83 @@ ################################################################################ # -# buildroot-build — the ONE shared build recipe. Do not fork per-workflow -# copies — see docs/ci.md#why-shared-recipe for the incident that forced this -# consolidation. +# buildroot-build — prepare a GitHub-hosted runner and build the DE10-Nano image. # -# The caller owns what is genuinely its own (which ref to check out, what to do -# with the images afterwards). Everything from "make the runner able to build" -# through "the variant's images exist in output/images/ (main) or -# output-/images/" is here. +# Used by build.yml, release.yml and reproducibility.yml so the Buildroot recipe +# exists once. It is `make mister_de10nano_defconfig && make` with four caches +# around it: # -# ccache IS working as designed — before "fixing" a small cache, read -# docs/ci.md#cache-budget-and-sizing. +# 1. the pinned Buildroot tarball key: buildroot-tarball- +# 2. dl/ (every package source) key: br-dl-- +# 3. output/host (the cross toolchain) key: br-host--- +# 4. ccache key: # -# VARIANTS: "main" (default) or any kernel-only variant with a fragment at -# configs/mister_.fragment. Adding one needs NO change here (fragment -# existence IS the registry) and no workflow matrix edit either — build.yml -# and release.yml derive their `kernel:` matrix from this same registry via -# scripts/list-kernel-variants.sh. See docs/ci.md#variants. -# -# What the CALLER does with a variant's outputs — staging the module tree into -# work/extra-modules-overlay/ for the main build, shipping zImage_dtb- — -# is the caller's business (see build.yml/release.yml); this recipe ends at -# "output-/images/zImage_dtb and a depmod'd output-/target exist". +# Two rules keep the caches honest. dl/ is saved only when `make external-deps` +# confirms every required file is present, because a cache key is immutable and +# an incomplete dl/ could never repair itself. The toolchain is restored only +# when dl/ was, and its key hashes the workspace path (a Buildroot toolchain +# bakes its absolute O= path in) plus the toolchain-relevant lines of the +# defconfig and any patches to gcc/binutils/glibc — a package added to the image +# does not move it, a compiler change does. # ################################################################################ name: Build the MiSTer image (Buildroot) -description: >- - Prepares a GitHub-hosted runner for a Buildroot build (disk reclaim, apt - deps, five input caches), then builds the requested variant. main: configures - from the DE10-Nano fragment stack (configs/fragments/, stacks.mk) and runs - `make all` — linux.img + zImage_dtb in output/images/. Any other name is a - kernel-only variant (`make ` over the de10nano-kernel fragment stack - + configs/mister_.fragment) — the - variant kernel at output-/images/zImage_dtb plus a depmod'd module - tree in output-/target/. +description: Prepare the runner (disk, apt, caches), then `make mister_de10nano_defconfig && make`. inputs: - board: - description: >- - Which board's arch/toolchain sentinel expectations to check the - toolchain fingerprint against (scripts/lib/board-expectations.sh's - BOARD_FINGERPRINT_SENTINELS, docs/de25-readiness-ledger.md §5.2/§5.5): - "de10nano" (default — behavior and cache key strings identical to - before this input existed). This is the ONLY value accepted today: - BOARD selects an expectation row but does not yet route the - defconfig, cache key, output dir or make target, so any other board - (de25nano included, even though its row exists in the table) is - rejected up front rather than allowed to fail its sentinel late. - Widen BOARD_ROUTED below when board routing lands (ledger §3/§4). - required: false - default: "de10nano" extra-apt-packages: - description: >- - Space-separated apt packages to install on top of the mandatory build set - (release.yml adds p7zip-full to assemble release_YYYYMMDD.7z). + description: Space-separated apt packages on top of the build set (release.yml adds the 7z/genimage tools). required: false default: "" - ccache-max-size: - description: >- - Cap for the ccache cache. Default 4G: the real cold build fills 1.1 GB, so - this has ~4x headroom and has never evicted. Lower this FIRST if the repo's - caches approach GitHub's 10 GB ceiling — it is the cheapest one to shrink. - required: false - default: "4G" run-legal-info: - description: >- - Also run `make legal-info` (`make -legal-info` for a kernel - variant) — the SBOM — after the build. "true"/"false". + description: Also run `make legal-info` (the SBOM) after the build. "true"/"false". required: false default: "false" - variant: - description: >- - Which build to run: "main" (default — the two-stage 6.18 image; behavior - and cache key strings identical to before this input existed) or the - name of a kernel-only variant whose fragment exists at - configs/mister_.fragment (e.g. "rt", the PREEMPT_RT / Linux-7.2 - beta, docs/rt-beta-kernel.md). A name with no fragment fails fast in the - fingerprint step, before any cache or build work. - required: false - default: "main" runs: using: composite steps: - # MUST run first — reclaims ~30GB of preinstalled toolchains we never use - # so output/ (24GB) fits (ENOSPC killed run 29295920820). No `container:` - # here: that preinstalled software lives on the runner HOST, unreachable - # from inside a container. See docs/ci.md#no-container-disk-reclaim. - name: Free disk space on the runner shell: bash run: | echo "--- disk before ---"; df -h / - sudo rm -rf \ - /usr/share/dotnet \ - /usr/local/lib/android \ - /opt/ghc \ - /usr/local/.ghcup \ - /opt/hostedtoolcache/CodeQL \ - /usr/local/share/powershell \ - /usr/local/share/boost \ + sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /usr/local/.ghcup \ + /opt/hostedtoolcache/CodeQL /usr/local/share/powershell /usr/local/share/boost \ /usr/local/graalvm || true sudo docker image prune --all --force >/dev/null 2>&1 || true sudo apt-get clean || true echo "--- disk after ---"; df -h / - # BUILDROOT_VERSION lives in the Makefile (Renovate watches that same line), - # not in any workflow, so it cannot drift from what `make` actually fetches. - # - # WS_FP keys the toolchain caches on the workspace path — a Buildroot - # cross-toolchain bakes in absolute paths and is NOT relocatable. ccache is - # the one exception (BR2_CCACHE_USE_BASEDIR makes it so). See - # docs/ci.md#ws-fp. - - name: Resolve Buildroot version + cache fingerprints + - name: Resolve Buildroot version and the toolchain fingerprint shell: bash - env: - VARIANT: ${{ inputs.variant }} - BOARD: ${{ inputs.board }} run: | set -eu - - # shellcheck source=scripts/lib/board-expectations.sh - source scripts/lib/board-expectations.sh - - # --- Which board this run checks the fingerprint against --------------- - # Validated ONCE, here, before any cache/build work -- same idiom as - # the variant validation just below. Two gates, both fail-closed: - # (1) the board must have a row in the registry - # (scripts/lib/board-expectations.sh, ledger §5.5), and - # (2) it must be ROUTED: this action still fingerprints the DE10 - # defconfig, runs the DE10 lockstep check and builds `make all` / - # `make $VARIANT`, so a board that is in the table but not routed - # would fail its sentinel late and misleadingly. BOARD_ROUTED is - # the explicit list of boards this action can actually build; - # extend it in the same change that wires defconfig, cache key, - # output dir and make target per board (ledger §3/§4). - BOARD_ROUTED="de10nano" - if [ -z "${BOARD_FINGERPRINT_SENTINELS[$BOARD]+set}" ]; then - echo "::error::unknown board '$BOARD' -- no row in scripts/lib/board-expectations.sh's BOARD_FINGERPRINT_SENTINELS (known: ${!BOARD_FINGERPRINT_SENTINELS[*]})" >&2 - exit 1 - fi - case " $BOARD_ROUTED " in - *" $BOARD "*) ;; - *) echo "::error::board '$BOARD' has an expectation row but is not routed through this action yet (routed: $BOARD_ROUTED) -- it would fail its arch sentinel after the DE10 defconfig was fingerprinted. Wire the board through defconfig/cache/output/target selection before enabling it here." >&2 - exit 1 ;; - esac - echo "BOARD=$BOARD" >> "$GITHUB_ENV" - - # --- Which variant this run builds (see the file header) --------------- - # Validated ONCE, here, before any cache/build work — fragment - # existence IS the registry, so a new variant needs no edit here. - # Everything variant-shaped downstream reads the env this step - # computes. See docs/ci.md#variants. - case "$VARIANT" in - main) ;; - *[!a-z0-9_-]*|'') - echo "::error::invalid variant name '$VARIANT' -- kernel-variant names must be non-empty [a-z0-9_-]" >&2 - exit 1 - ;; - *) - if [ ! -f "configs/mister_${VARIANT}.fragment" ]; then - echo "::error::unknown variant '$VARIANT' -- .github/actions/buildroot-build accepts 'main' or any kernel variant with a fragment at configs/mister_.fragment (looked for configs/mister_${VARIANT}.fragment)" >&2 - exit 1 - fi - # Kernel variants build on the de10nano-kernel fragment stack, - # which shares its toolchain/kernel fragments with main's stack by - # construction (configs/fragments/stacks.mk) — assert that - # structure still holds BEFORE any cache work, or a drift builds - # wrong under a cache key that then pins the wrong toolchain in. - # See docs/ci.md#variants. - scripts/check-kernel-defconfig-sync.sh - ;; - esac - echo "VARIANT=$VARIANT" >> "$GITHUB_ENV" - - # Whitespace-tolerant on purpose, matching renovate.json's own - # matchString (BUILDROOT_VERSION\s*\?=\s*): the Makefile stanza is - # column-aligned, so the gap is more than one space and may move again - # the next time a neighboring variable changes length. A single-space - # match here broke on exactly that (run 32698708260). + # Same whitespace-tolerant read as renovate.json's matchString. ver=$(sed -n -e 's/[[:space:]]*$//' -e 's/^BUILDROOT_VERSION[[:space:]]*?=[[:space:]]*//p' Makefile | head -1) - if [ -z "$ver" ]; then - echo "::error::could not extract BUILDROOT_VERSION from Makefile (format changed?)" >&2 - exit 1 - fi + [ -n "$ver" ] || { echo "::error::could not read BUILDROOT_VERSION from Makefile" >&2; exit 1; } echo "BUILDROOT_VERSION=$ver" >> "$GITHUB_ENV" - ws_fp=$(printf '%s' "$GITHUB_WORKSPACE" | sha256sum | cut -c1-8) - echo "WS_FP=$ws_fp" >> "$GITHUB_ENV" - # --- Toolchain cache fingerprint: a DENY-list, not an ALLOW-list --- - # DENY-list, not ALLOW-list: an allow-list once silently missed - # BR2_cortex_a9=y (wrong -mcpu, no cache bust). Comments are stripped - # first so editing one can't evict the cross-toolchain either. See - # docs/ci.md#toolchain-fingerprint before changing this filter. - # - # Fingerprints the variant's own base STACK + fragment, not main's: - # main = the de10nano stack, a kernel variant = the de10nano-kernel - # stack (configs/fragments/stacks.mk, read through the same helper - # the check scripts use). The fragments are concatenated before the - # strip/filter/sort, so the residue is the same sorted set of lines - # the old single-file defconfig produced — the fingerprint, and - # therefore the cache key, did not move at the fragment split. - # See docs/ci.md#toolchain-fingerprint. - TC_GEN=1 - ROOT="$PWD" - # shellcheck source=scripts/lib/config-stacks.sh - source scripts/lib/config-stacks.sh - if [ "$VARIANT" = "main" ]; then - mapfile -t fp_files < <(config_stack_files DE10NANO) - else - mapfile -t fp_files < <(config_stack_files DE10NANO_KERNEL) - fi - if [ "${#fp_files[@]}" -eq 0 ]; then - echo "::error::configs/fragments/stacks.mk names no fragments for this variant's stack" >&2 - exit 1 - fi + # Toolchain fingerprint: the defconfig minus package and kernel lines + # (neither changes the compiler), plus any toolchain-source patches. sed -e 's/^[[:space:]]*#.*$//' -e 's/[[:space:]]\+#.*$//' -e 's/[[:space:]]*$//' \ - "${fp_files[@]}" \ + configs/mister_de10nano_defconfig \ | grep -vE '^($|BR2_PACKAGE_|BR2_LINUX_KERNEL)' \ | sort > .br-toolchain-fingerprint - - # Patches that rewrite the toolchain's OWN sources. patches/linux/ is - # deliberately not here: it changes on every kernel bump and cannot affect - # the cross-compiler. (None of these dirs exist today -- this closes the - # vector before someone opens it.) - for d in gcc binutils glibc musl uclibc; do - pd="board/mister/de10nano/patches/$d" - if [ -d "$pd" ]; then - find "$pd" -type f -exec sha256sum {} + | sort >> .br-toolchain-fingerprint - fi - done - echo "gen=$TC_GEN" >> .br-toolchain-fingerprint - - # Kernel variants: same strip/filter, appended for the fragment. Zero - # matches (grep exit 1) is the CORRECT, expected result today, but - # this step runs under pipefail — `|| [ $? -eq 1 ]` tolerates exactly - # that exit while a real grep failure (exit >=2) still aborts. See - # docs/ci.md#toolchain-fingerprint. - if [ "$VARIANT" != "main" ]; then - sed -e 's/^[[:space:]]*#.*$//' -e 's/[[:space:]]\+#.*$//' -e 's/[[:space:]]*$//' \ - "configs/mister_${VARIANT}.fragment" \ - | { grep -vE '^($|BR2_PACKAGE_|BR2_LINUX_KERNEL)' || [ $? -eq 1 ]; } \ - | sort >> .br-toolchain-fingerprint - fi - - # Fail loud if the defconfig is ever renamed/reformatted such that this - # produces an empty or degenerate fingerprint: a frozen cache key is the - # worst outcome available here (see docs/ci.md#toolchain-fingerprint). - # Assert the lines BOARD's row says no defconfig for that board can - # lack and that nothing legitimate ever removes (scripts/lib/ - # board-expectations.sh's BOARD_FINGERPRINT_SENTINELS; for the - # default "de10nano" this is the same two patterns as before this - # table existed). - # shellcheck disable=SC2086 # word splitting over the merged pattern list is intended - for must in ${BOARD_FINGERPRINT_SENTINELS[$BOARD]}; do - if ! grep -q "$must" .br-toolchain-fingerprint; then - echo "::error::toolchain fingerprint is missing '$must' -- the filter in .github/actions/buildroot-build/action.yml has gone stale, so this cache key can no longer detect a toolchain change. Refusing to build rather than risk restoring a wrong compiler." >&2 - exit 1 + for d in gcc binutils glibc; do + if [ -d "board/mister/de10nano/patches/$d" ]; then + find "board/mister/de10nano/patches/$d" -type f -exec sha256sum {} + | sort >> .br-toolchain-fingerprint fi done - echo "Toolchain fingerprint ($(grep -c . .br-toolchain-fingerprint) lines):" - cat .br-toolchain-fingerprint - - # Cache keys computed ONCE here, consumed by both restore and save - # steps below — duplicating them risks a silent "always cold" cache - # (each half reading a different key). sha256sum, not hashFiles(): - # this is shell, and both halves read the same env var either way. - # See docs/ci.md#cache-keys. + echo "gen=1" >> .br-toolchain-fingerprint + # If the arch line is not in the fingerprint the filter above is broken + # and this key could restore the wrong compiler. Refuse rather than guess. + grep -q '^BR2_arm=y' .br-toolchain-fingerprint || { echo "::error::toolchain fingerprint lost BR2_arm=y -- the filter in this action is stale" >&2; exit 1; } + echo "Toolchain fingerprint ($(grep -c . .br-toolchain-fingerprint) lines):"; cat .br-toolchain-fingerprint tc_hash=$(sha256sum .br-toolchain-fingerprint | cut -d' ' -f1) - # The stage-1 configuration is the initramfs-de10nano fragment stack - # (configs/fragments/stacks.mk), read through the same helper as the - # image/kernel stacks above so a fragment added to the stack moves this - # key without anyone editing a list here. - mapfile -t ir_files < <(config_stack_files INITRAMFS_DE10NANO) - [ "${#ir_files[@]}" -gt 0 ] || { echo "::error::configs/fragments/stacks.mk names no fragments for INITRAMFS_DE10NANO" >&2; exit 1; } - ir_hash=$(cat "${ir_files[@]}" | sha256sum | cut -d' ' -f1) - echo "BR_INITRAMFS_HOST_KEY=br-initramfs-host-${ws_fp}-${ver}-${ir_hash}" >> "$GITHUB_ENV" + echo "BR_HOST_KEY=br-host-${ws_fp}-${ver}-${tc_hash}" >> "$GITHUB_ENV" + echo "Buildroot $ver, workspace $ws_fp, toolchain ${tc_hash:0:12}" - # Variant-resolved host-toolchain key + paths (main's key STRING - # stays byte-identical for back-compat). Each variant gets its own - # br--host- namespace — NEVER share entries, since a - # cross-toolchain's absolute O= path makes them incompatible. See - # docs/ci.md#cache-keys. - if [ "$VARIANT" != "main" ]; then - { - echo "BR_HOST_KEY=br-${VARIANT}-host-${ws_fp}-${ver}-${tc_hash}" - echo "BR_HOST_PATHS<> "$GITHUB_ENV" - else - { - echo "BR_HOST_KEY=br-host-${ws_fp}-${ver}-${tc_hash}" - echo "BR_HOST_PATHS<> "$GITHUB_ENV" - fi - - echo "Resolved BUILDROOT_VERSION=$ver workspace-fp=$ws_fp variant=$VARIANT" - - ############################################################################ - # Five input caches, mindful of GitHub's 10GB/repo LRU eviction ceiling. - # Eviction is safe here — every cache is a pure accelerator, and an - # evicted entry means a cold, self-healing rebuild, never a wrong one. See - # docs/ci.md#cache-budget-and-sizing for the budget math and the cheapest - # levers if eviction thrash ever hurts. - ############################################################################ - - # dl/ (#2/#2b) restore/save split from the toolchains (#3/#4) on purpose: - # `actions/cache`'s save is post-if: success(), which is right for the - # toolchains (their stamps poison a restore if half-built) but wrong for - # dl/ (a miss just re-downloads) — so dl/ restores here, saves later - # under `always()`. See docs/ci.md#cache-save-policy. - # - # #2 (dl/) and #3 (host toolchain) restores are COUPLED — NEVER restore - # #3 without #2: its stamps lie about dl/'s contents. Cost run - # 29534917900 a 46-minute build. See docs/ci.md#cache-coupling. - - # 1. Buildroot release tarball (~20-30 MB). Kept SEPARATE from dl/ on purpose: - # it is redundant with the copy inside dl/, but keying it on the version ALONE - # means a mere defconfig change can never evict this tiny, cheap entry. - name: Restore Buildroot release tarball id: tarball-cache uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 @@ -335,105 +85,36 @@ runs: path: dl/buildroot-${{ env.BUILDROOT_VERSION }}.tar.gz key: buildroot-tarball-${{ env.BUILDROOT_VERSION }} - # 2. dl/ — every package source tarball. Lives at repo root (survives - # `make clean`) — NEVER move it under output/. Keyed on the full - # DE10-Nano fragment stack (the four files configs/fragments/stacks.mk - # lists for DE10NANO_FRAGMENTS — hashFiles() cannot read stacks.mk, so - # they are spelled out here; keep the two in step, which - # scripts/check-config-fragments.sh (e) asserts by comparing this list - # with the stack); restore-keys falls back to the version alone so an - # imperfect match still hydrates what didn't change. See - # docs/ci.md#dl-cache. - - name: Restore Buildroot dl/ download cache + - name: Restore dl/ download cache id: dl-cache - if: env.VARIANT == 'main' - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: dl/ - key: br-dl-${{ env.BUILDROOT_VERSION }}-${{ hashFiles('configs/fragments/common.fragment', 'configs/fragments/de10nano.fragment', 'configs/fragments/image-common.fragment', 'configs/fragments/de10nano-image.fragment') }} - restore-keys: | - br-dl-${{ env.BUILDROOT_VERSION }}- - - # 2b. A kernel variant's dl/, under its OWN key — cache keys are - # immutable, so a shared key would let whichever variant saves first - # lock the others' gaps in forever. restore-keys falls back through the - # variant's own prefix to MAIN's dl/ prefix; that fallback is safe - # despite the #2/#3 coupling above. See docs/ci.md#variant-dl-fallback. - - name: Restore Buildroot dl/ download cache (kernel variant) - id: dl-cache-variant - if: env.VARIANT != 'main' uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: dl/ - key: br-dl-${{ env.VARIANT }}-${{ env.BUILDROOT_VERSION }}-${{ hashFiles('configs/fragments/common.fragment', 'configs/fragments/de10nano.fragment', 'configs/fragments/kernel-only.fragment', format('configs/mister_{0}.fragment', env.VARIANT)) }} + key: br-dl-${{ env.BUILDROOT_VERSION }}-${{ hashFiles('configs/mister_de10nano_defconfig') }} restore-keys: | - br-dl-${{ env.VARIANT }}-${{ env.BUILDROOT_VERSION }}- br-dl-${{ env.BUILDROOT_VERSION }}- - # 3. The variant's cross-toolchain: /host plus its build stamps — THE - # big win, since restoring this is what skips rebuilding gcc/binutils/ - # glibc from scratch. Path/key are the variant-resolved env (never - # shared, see docs/ci.md#cache-keys). `if:` implements the #2/#3 - # coupling — restore only when a dl/ restore matched, else this build - # goes cold. See docs/ci.md#cache-coupling. - - name: Restore Buildroot host toolchain + # Only with dl/ in place: a restored toolchain whose sources must then be + # re-fetched anyway gains nothing and can mask a dl/ problem. + - name: Restore host toolchain id: host-cache - if: steps.dl-cache.outputs.cache-matched-key != '' || steps.dl-cache-variant.outputs.cache-matched-key != '' - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: ${{ env.BR_HOST_PATHS }} - key: ${{ env.BR_HOST_KEY }} - - # 4. The initramfs stage's separate static-musl toolchain. Shared across - # every variant (one key, one path) since the stage-1 cpio is embedded - # into every kernel this repo builds — so a kernel leg that runs first - # warms it for the main build that follows. Coupled to dl/ the same way - # as #3. See docs/ci.md#cache-coupling. - - name: Restore initramfs host toolchain - id: initramfs-host-cache - if: steps.dl-cache.outputs.cache-matched-key != '' || steps.dl-cache-variant.outputs.cache-matched-key != '' + if: steps.dl-cache.outputs.cache-matched-key != '' uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: | - output-initramfs/host - output-initramfs/build/host-* - key: ${{ env.BR_INITRAMFS_HOST_KEY }} - - # 5. ccache. CCACHE_DIR is exported here to match the BR2_CCACHE_DIR handed to - # `make` below, so the action caches the exact directory Buildroot's compiler - # wrapper writes to. Unlike the toolchain caches this one IS relocatable — - # BR2_CCACHE_USE_BASEDIR rewrites the absolute paths in cached objects — so it - # is deliberately NOT keyed on WS_FP. - - name: Configure ccache directory - shell: bash - run: echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> "$GITHUB_ENV" + output/host + output/build/host-* + key: ${{ env.BR_HOST_KEY }} - name: Cache ccache uses: hendrikmuhs/ccache-action@f09c25b45002a07be2955cbe52e8cee55643f89d # v1.2.24 - # This action runs its own apt-get; it used to be covered by a job-level - # DEBIAN_FRONTEND that the callers no longer carry, so set it here. env: DEBIAN_FRONTEND: noninteractive with: - # NOT "ccache-" (the action prepends its own prefix) and - # NEVER `append-timestamp: false` — the key is immutable, so the - # first save would own it forever and the hit rate would decay. - # See docs/ci.md#ccache-key. key: ${{ env.BUILDROOT_VERSION }} - max-size: ${{ inputs.ccache-max-size }} - # This action `apt-get install`s ccache itself, BEFORE our own apt step - # below has run `apt-get update` — so have it refresh the index first. - # (Introduced when we ran in a container with an empty index; kept because - # a runner's preinstalled index can be stale too, and it is what the first - # green run actually used.) + max-size: 4G update-package-index: true - # Package list = Buildroot's mandatory set + repo extras; per-package - # rationale in docs/ci.md#apt-deps. - # - # EXTRA_APT goes through the environment, not `${{ }}` interpolation — - # avoids the Actions script-injection footgun. See - # docs/ci.md#branch-name-injection. - name: Install build dependencies shell: bash env: @@ -442,7 +123,7 @@ runs: run: | set -eu sudo apt-get update - # shellcheck disable=SC2086 # word splitting of EXTRA_APT is intended + # shellcheck disable=SC2086 # EXTRA_APT is a deliberate word list sudo -E apt-get install -y --no-install-recommends \ build-essential bash bc bison flex gawk \ git patch gzip bzip2 xz-utils cpio unzip rsync \ @@ -453,134 +134,57 @@ runs: $EXTRA_APT sudo rm -rf /var/lib/apt/lists/* - # Fails fast and loud if the runner's `install` is ever not GNU coreutils - # (see the Makefile's `hostshim` target) — cheap to check before spending - # three hours of build time. - name: Verify host `install` is GNU coreutils shell: bash run: make hostshim - # Regenerate output/.config UNCONDITIONALLY every run — a stale cached - # one can silently override a fragment change (run 29293209070 died - # here after a 52min stage 1). MAIN-ONLY: a kernel variant's .config is - # never cached, so it can't go stale in the first place. See - # docs/ci.md#configure-buildroot. - - name: Configure Buildroot (generate output/.config from the fragment stack) - if: env.VARIANT == 'main' + - name: Configure shell: bash - run: make de10nano-defconfig + run: make mister_de10nano_defconfig - # `make all` builds both stages under one ccache (BR2_CCACHE propagates - # through MAKEFLAGS to the musl initramfs too — distinct ccache keys, so - # they coexist safely). MISTER_VERSION, if the caller exported it - # (release.yml does, ADR 0018), is inherited and baked into - # /MiSTer.version. See docs/ci.md#build-step. - - name: Build image (make all — initramfs + main rootfs, ccache both) - if: env.VARIANT == 'main' + - name: Build shell: bash - run: | - make all \ - BR2_CCACHE=y \ - BR2_CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" \ - BR2_CCACHE_USE_BASEDIR=y - - # A kernel variant: `make ` — stage-1 initramfs then the - # kernel-only build, sharing dl/ and ccache with main. The Makefile's - # variant target hard-asserts the built kernel's config (e.g. rt's - # CONFIG_PREEMPT_RT=y) — a fragment regression fails HERE, loudly, not - # on a device. See docs/ci.md#build-step. - - name: Build kernel variant (make — kernel-only Buildroot build) - if: env.VARIANT != 'main' - shell: bash - run: | - make "$VARIANT" \ - BR2_CCACHE=y \ - BR2_CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" \ - BR2_CCACHE_USE_BASEDIR=y + run: make BR2_CCACHE=y BR2_CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" BR2_CCACHE_USE_BASEDIR=y - # BR_LEGAL_TARGET is variant-resolved in the fingerprint step: `legal-info` - # for main, `-legal-info` for a kernel variant (same recipe, aimed at - # output-/ — kernel-only, so the bundle is dominated by the kernel - # source). - name: Generate legal-info (SBOM) if: inputs.run-legal-info == 'true' shell: bash - run: | - make "$BR_LEGAL_TARGET" \ - BR2_CCACHE=y \ - BR2_CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" \ - BR2_CCACHE_USE_BASEDIR=y - - ############################################################################ - # Save the download caches — PASS OR FAIL. dl/'s stamp-coupling with the - # toolchain caches is documented at docs/ci.md#cache-coupling; the save - # policy split is at docs/ci.md#cache-save-policy. Placed after - # legal-info, which itself may fetch tarballs missing from dl/. - ############################################################################ + run: make legal-info BR2_CCACHE=y BR2_CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" BR2_CCACHE_USE_BASEDIR=y - # TRAP: a partial dl/ save LOCKS a stub into the immutable cache key - # forever. Do NOT judge completeness with a size floor — one passed run - # 29534917900 while missing the exact file legal-info needed. The oracle - # below MUST use the same BR2_CCACHE=y as the real build, or it - # undercounts by 5 files (158 vs 163 — misses ccache itself). See - # docs/ci.md#dl-completeness. - - name: Verify dl/ is complete before caching it + - name: Check dl/ is complete before caching it id: dl-state if: always() shell: bash run: | set -uo pipefail - - # Bare basenames only: the wrapper Makefile's own recipe echo (plus, - # for a variant, its .config-generation trailer) always contains a - # '/', '=' or space; a leading '#' catches kconfig's own trailer too. - # No legitimate dl/ basename matches any of those. See - # docs/ci.md#dl-completeness. - if ! make "$BR_EXTDEPS_TARGET" BR2_CCACHE=y \ - BR2_CCACHE_DIR="$GITHUB_WORKSPACE/.ccache" \ - BR2_CCACHE_USE_BASEDIR=y 2>/dev/null \ - | grep -vE '/|=|^\s*$| |^#' | sort -u > /tmp/dl-needed.txt; then + if ! make external-deps 2>/dev/null | grep -vE '/|=|^\s*$| |^#' | sort -u > /tmp/dl-needed.txt; then echo "complete=false" >> "$GITHUB_OUTPUT" - echo "::notice title=dl/ not cached::Could not enumerate required downloads (make external-deps failed), so dl/ completeness is unknown and it was NOT saved. Erring toward a re-download rather than risk locking an incomplete dl/ into an immutable cache key." + echo "::notice title=dl/ not cached::make external-deps failed, so dl/ completeness is unknown and it was not saved." exit 0 fi - find dl -type f -printf '%f\n' 2>/dev/null | sort -u > /tmp/dl-have.txt comm -23 /tmp/dl-needed.txt /tmp/dl-have.txt > /tmp/dl-missing.txt || true - - needed=$(wc -l < /tmp/dl-needed.txt) missing=$(wc -l < /tmp/dl-missing.txt) - echo "dl/ requires $needed files; $missing missing; $(du -sh dl 2>/dev/null | cut -f1) on disk" - + echo "dl/ needs $(wc -l < /tmp/dl-needed.txt) files, $missing missing, $(du -sh dl 2>/dev/null | cut -f1) on disk" if [ "$missing" -eq 0 ]; then echo "complete=true" >> "$GITHUB_OUTPUT" else echo "complete=false" >> "$GITHUB_OUTPUT" echo "--- missing ---"; cat /tmp/dl-missing.txt - echo "::notice title=dl/ not cached::dl/ is missing $missing of $needed required source files, so it was NOT saved -- an incomplete dl/ would lock itself into an immutable cache key that later runs could not repair. Expected when a build fails before everything is fetched. The missing list is in this step's log." + echo "::notice title=dl/ not cached::dl/ is missing $missing required files (a build that failed early); not saved." fi - - # Existence check for the tarball save below, done here in shell rather - # than as hashFiles() in that step's `if:` — one less expression-context - # subtlety to be wrong about, and `actions/cache/save` hard-errors on a - # missing path rather than skipping. if [ -f "dl/buildroot-${BUILDROOT_VERSION}.tar.gz" ]; then echo "tarball=true" >> "$GITHUB_OUTPUT" else echo "tarball=false" >> "$GITHUB_OUTPUT" fi - # `cache-hit != 'true'` skips the upload only on an exact match; a - # restore-keys hit still saves (dl/ was hydrated from an older entry and - # has since grown). The `||` in `key:` resolves to whichever dl restore - # ran, keeping a variant's save inside its own key namespace — it can - # never write into main's. See docs/ci.md#dl-cache-save. - - name: Save Buildroot dl/ download cache - if: always() && steps.dl-cache.outputs.cache-hit != 'true' && steps.dl-cache-variant.outputs.cache-hit != 'true' && steps.dl-state.outputs.complete == 'true' + - name: Save dl/ download cache + if: always() && steps.dl-cache.outputs.cache-hit != 'true' && steps.dl-state.outputs.complete == 'true' uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: dl/ - key: ${{ steps.dl-cache.outputs.cache-primary-key || steps.dl-cache-variant.outputs.cache-primary-key }} + key: ${{ steps.dl-cache.outputs.cache-primary-key }} - name: Save Buildroot release tarball if: always() && steps.tarball-cache.outputs.cache-hit != 'true' && steps.dl-state.outputs.tarball == 'true' @@ -589,52 +193,21 @@ runs: path: dl/buildroot-${{ env.BUILDROOT_VERSION }}.tar.gz key: ${{ steps.tarball-cache.outputs.cache-primary-key }} - ############################################################################ - # Save the toolchain caches — GREEN BUILDS ONLY. No `always()` here is - # deliberate (an `if:` with no status function implies success() &&) — - # the one place in this file where its ABSENCE is load-bearing, not an - # oversight: these carry per-package stamps, and a half-built - # output/host restored WITH its stamps is a poisoned toolchain. See - # docs/ci.md#cache-save-policy. - ############################################################################ - - # `cache-hit != 'true'` covers both "restored and missed" and "restore was - # SKIPPED because dl/ missed" — the latter leaves the output empty, which is - # exactly the cold healing run whose freshly-built toolchain we most want to - # keep. Path and key are the variant-resolved env, same as the restore — the - # one step serves both key namespaces and can never cross them. - - name: Save Buildroot host toolchain + - name: Save host toolchain if: steps.host-cache.outputs.cache-hit != 'true' uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: ${{ env.BR_HOST_PATHS }} - key: ${{ env.BR_HOST_KEY }} - - # Every variant, like its restore: `make ` builds the initramfs - # stage too (its cpio is embedded into every kernel), so output-initramfs/ - # exists on green variant runs as well — and the key is variant-independent, - # so whichever variant builds it cold saves it for all. - - name: Save initramfs host toolchain - if: steps.initramfs-host-cache.outputs.cache-hit != 'true' - uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: | - output-initramfs/host - output-initramfs/build/host-* - key: ${{ env.BR_INITRAMFS_HOST_KEY }} + output/host + output/build/host-* + key: ${{ env.BR_HOST_KEY }} - - name: Report disk & cache usage + - name: Report disk and cache usage if: always() shell: bash run: | echo "--- disk free ---"; df -h . echo "--- dl/ ---"; du -sh dl 2>/dev/null || true - if [ "${VARIANT:-main}" = "main" ]; then - echo "--- output/host ---"; du -sh output/host 2>/dev/null || true - echo "--- output (total) ---"; du -sh output 2>/dev/null || true - else - echo "--- output-$VARIANT/host ---"; du -sh "output-$VARIANT/host" 2>/dev/null || true - echo "--- output-$VARIANT (total) ---"; du -sh "output-$VARIANT" 2>/dev/null || true - fi - echo "--- output-initramfs (total) ---"; du -sh output-initramfs 2>/dev/null || true + echo "--- output/host ---"; du -sh output/host 2>/dev/null || true + echo "--- output ---"; du -sh output 2>/dev/null || true echo "--- ccache ---"; du -sh "$GITHUB_WORKSPACE/.ccache" 2>/dev/null || true diff --git a/.github/actions/kernel-leg/action.yml b/.github/actions/kernel-leg/action.yml deleted file mode 100644 index a1c1d348..00000000 --- a/.github/actions/kernel-leg/action.yml +++ /dev/null @@ -1,258 +0,0 @@ -################################################################################ -# -# kernel-leg — one kernel-variant matrix leg's body: build the variant, render -# its job-summary overview, stage its artifact (zImage_dtb + .config + depmod'd -# modules + legal-info), and upload it for `build` to merge downstream. -# -# Extracted here because build.yml and release.yml each carried their own copy -# of this leg (measured 85 vs 91 lines, 72 identical). See docs/ci.md#why-shared-recipe. -# -# full-legal-info and release-context are the two real per-caller differences, -# kept as inputs rather than forked copies. See docs/ci.md#kernel-variant-matrix. -# -# What stays at the CALLER, not this recipe: runs-on, timeout-minutes, -# strategy.matrix, needs, if, and its own Checkout step. See docs/ci.md#recipe-boundary. -# -################################################################################ - -name: Build one kernel-variant matrix leg -description: >- - Builds a kernel-only Buildroot variant (via buildroot-build), renders its - job-summary overview, stages its artifact (zImage_dtb, .config, depmod'd - modules, legal-info), and uploads kernel-- for the - `build` job to merge downstream. - -inputs: - kernel: - description: >- - The kernel variant name (the matrix.kernel value from the calling job, - e.g. "rt") -- composite-action steps cannot read the caller's `matrix` - context directly, so the caller must pass it through. - required: true - full-legal-info: - description: >- - "true" ships the variant kernel's applied patches + SBOM (patches-only - mode: the freely-available upstream *.tar.* source archives are dropped - -- the leg distributes the variant kernel binary but not a rootfs, and - manifest.csv records the pinned upstream URL+hash; existence- and 2 GiB- - per-asset-guarded) -- for release.yml. "false" (default) ships a - manifest-only SBOM (all of legal-info/sources and legal-info/host-sources - excluded) -- for build.yml, whose CI push distributes nothing. - required: false - default: "false" - release-context: - description: >- - "true" leads the job-summary table with Tag (and a release-assets - footer) -- for release.yml. "false" (default) leads with Trigger/Commit - and adds a Packages (SBOM) row (and a u-boot-selection footer) -- for - build.yml's CI-only summary. - required: false - default: "false" - -runs: - using: composite - steps: - # MUST run first -- composite-action inputs are STRING booleans, so a caller - # typo ("yes"/"True") would otherwise waste a 240-min kernel build (and the - # `build` job it auto-skips). See docs/ci.md#composite-input-validation. - - name: Validate inputs - shell: bash - env: - FULL_LEGAL_INFO: ${{ inputs.full-legal-info }} - RELEASE_CONTEXT: ${{ inputs.release-context }} - run: | - set -euo pipefail - case "$FULL_LEGAL_INFO" in - true|false) ;; - *) - echo "::error::full-legal-info must be exactly \"true\" or \"false\", got \"$FULL_LEGAL_INFO\"" >&2 - exit 1 - ;; - esac - case "$RELEASE_CONTEXT" in - true|false) ;; - *) - echo "::error::release-context must be exactly \"true\" or \"false\", got \"$RELEASE_CONTEXT\"" >&2 - exit 1 - ;; - esac - - # No patch-header lint here: build.yml's `build` job lints the one shared - # patches dir (linux-patches-beta/ is symlinks + a series into it) -- - # release.yml does not lint patch headers at all. - - name: Build the kernel variant - uses: ./.github/actions/buildroot-build - with: - variant: ${{ inputs.kernel }} - run-legal-info: "true" - - # Best-effort job-summary overview (every fact guarded; a missing one never - # fails the build), mirroring the calling job's own step in build.yml/release.yml. - # PREEMPT_RT here only SURFACES the Makefile's hard assert -- docs/ci.md#build-step. - # Kernel-tree glob is uniqueness-guarded same as staging below -- docs/ci.md#unique-glob-guard. - - name: Kernel build overview (job summary) - shell: bash - env: - KERNEL: ${{ inputs.kernel }} - RELEASE_CONTEXT: ${{ inputs.release-context }} - run: | - set -u - # shellcheck source=scripts/ci-lib.sh - # Explicit fallback, not a silent skip -- see docs/ci.md#ci-lib-explicit-fallback. - source scripts/ci-lib.sh || { - echo "::warning::scripts/ci-lib.sh not found -- size facts below will read n/a" >&2 - ci_lib_sz() { echo "n/a"; } - } - case "$RELEASE_CONTEXT" in - true|false) ;; - *) - echo "::error::release-context must be exactly \"true\" or \"false\", got \"$RELEASE_CONTEXT\"" >&2 - exit 1 - ;; - esac - # NOT `ls -d ... | head -1` (SC2012; would silently render the WRONG - # kernel's version with a stale sibling tree present). Best-effort: any - # count other than 1 leaves kver empty, not a failure. See docs/ci.md#unique-glob-guard. - kver="" - modtrees=(output-"$KERNEL"/target/usr/lib/modules/*/) - if [ "${#modtrees[@]}" -eq 1 ] && [ -d "${modtrees[0]}" ]; then - kver=$(basename "${modtrees[0]}") - fi - rt="n/a" - trees=(output-"$KERNEL"/build/linux-[0-9]*/) - if [ "${#trees[@]}" -eq 1 ] && [ -d "${trees[0]}" ]; then - kcfg="${trees[0]}.config" - if [ -f "$kcfg" ]; then - grep -qx 'CONFIG_PREEMPT_RT=y' "$kcfg" && rt="✅ CONFIG_PREEMPT_RT=y" || rt="❌ NOT SET" - fi - elif [ "${#trees[@]}" -gt 1 ]; then - rt="n/a (${#trees[@]} kernel trees -- ambiguous)" - fi - zimg=$(ci_lib_sz "output-$KERNEL/images/zImage_dtb") - - if [ "$RELEASE_CONTEXT" = "true" ]; then - # Tag, not Trigger/Commit: a release build only ever runs from a v* - # tag push, so the tag IS the identifying fact. GITHUB_REF_NAME is - # the runner's own default env var (equivalent to github.ref_name), - # available here exactly as it is in any other step. - { - echo "## ⏱️ Kernel variant release build (${KERNEL})" - echo "" - echo "| Fact | Value |" - echo "|---|---|" - echo "| Tag | \`${GITHUB_REF_NAME}\` |" - echo "| Kernel | \`${kver:-n/a}\` |" - echo "| PREEMPT_RT | ${rt} |" - echo "| zImage_dtb (ships as \`zImage_dtb-${KERNEL}\`) | ${zimg} |" - echo "" - echo "Kernel-only build; its module tree merges into the shipped linux.img in \`build\`," - echo "and \`zImage_dtb-${KERNEL}\` / \`linux-${KERNEL}.config\` / \`legal-info-${KERNEL}.tar.gz\`" - echo "become release assets." - } >> "$GITHUB_STEP_SUMMARY" - else - pkgs=$( [ -f "output-$KERNEL/legal-info/manifest.csv" ] && echo $(( $(wc -l < "output-$KERNEL/legal-info/manifest.csv") - 1 )) || echo "n/a" ) - { - echo "## ⏱️ Kernel variant build summary (${KERNEL})" - echo "" - echo "| Fact | Value |" - echo "|---|---|" - echo "| Trigger | \`${GITHUB_EVENT_NAME:-?}\` |" - echo "| Commit | \`${GITHUB_SHA:0:12}\` |" - echo "| Kernel | \`${kver:-n/a}\` |" - echo "| PREEMPT_RT | ${rt} |" - echo "| zImage_dtb (ships as \`zImage_dtb-${KERNEL}\`) | ${zimg} |" - echo "| Packages (SBOM) | ${pkgs} |" - echo "" - echo "Kernel-only build; its module tree merges into the ONE shipped linux.img in the" - echo "\`build\` job. Selected on-device via \`bootimage=/linux/zImage_dtb-${KERNEL}\` in u-boot.txt." - } >> "$GITHUB_STEP_SUMMARY" - fi - - # INTER-JOB TRANSPORT, not a deliverable -- uploads on ALL events (PRs - # included), unlike the main job's gated uploads: `build` needs the module - # tree/kver downstream. Sizes and both callers' payload diff: docs/ci.md#kernel-artifact-transport. - # - # Both globs are uniqueness-guarded (Copilot review) -- same trap as - # docs/ci.md#unique-glob-guard. - - name: Stage the kernel artifact (zImage_dtb, config, modules, legal-info) - shell: bash - env: - KERNEL: ${{ inputs.kernel }} - FULL_LEGAL_INFO: ${{ inputs.full-legal-info }} - run: | - set -euo pipefail - # shellcheck source=scripts/ci-lib.sh - source scripts/ci-lib.sh - case "$FULL_LEGAL_INFO" in - true|false) ;; - *) - echo "::error::full-legal-info must be exactly \"true\" or \"false\", got \"$FULL_LEGAL_INFO\"" >&2 - exit 1 - ;; - esac - # nullglob -- without it a zero-match glob leaves the LITERAL pattern in - # the array and "found 1" would lie about an empty build. Same shopt as - # `build`'s Populate step. See docs/ci.md#unique-glob-guard. - shopt -s nullglob - mkdir -p kernel-artifact - cp "output-$KERNEL/images/zImage_dtb" "kernel-artifact/zImage_dtb-$KERNEL" - - # UNIFIED wording (build.yml's and release.yml's copies of this guard - # had already drifted -- build.yml's named the Makefile assert, - # release.yml's did not. Keeping the more informative one now that - # there is only one copy to read.) - trees=(output-"$KERNEL"/build/linux-[0-9]*/) - if [ "${#trees[@]}" -ne 1 ] || [ ! -d "${trees[0]}" ]; then - echo "::error::expected exactly one kernel tree at output-$KERNEL/build/linux-[0-9]*/ but found ${#trees[@]} -- cannot stage linux-$KERNEL.config (zero: the build produced no kernel tree; more than one: a stale sibling from a version bump -- the Makefile's own assert should have caught either)" >&2 - exit 1 - fi - cp "${trees[0]}.config" "kernel-artifact/linux-$KERNEL.config" - - mods=(output-"$KERNEL"/target/usr/lib/modules/*/) - if [ "${#mods[@]}" -ne 1 ] || [ ! -d "${mods[0]}" ]; then - echo "::error::expected exactly one module tree under output-$KERNEL/target/usr/lib/modules/ but found ${#mods[@]} -- cannot stage the modules tar (zero: depmod/target-finalize never ran; more than one: a stale sibling from a version bump)" >&2 - exit 1 - fi - kver=$(basename "${mods[0]}") - printf '%s\n' "$kver" > "kernel-artifact/kver-$KERNEL.txt" - - # Depmod'd by target-finalize (the whole point of the kernel config's - # BR2_TARGET_ROOTFS_TAR); tar'd from target/ so the paths inside are - # exactly what work/extra-modules-overlay/ needs. - tar -czf "kernel-artifact/modules-$KERNEL.tar.gz" -C "output-$KERNEL/target" usr/lib/modules - - if [ "$FULL_LEGAL_INFO" = "true" ]; then - # Kernel-variant release bundle: our applied kernel patches + the - # SBOM (manifest.csv / license texts / buildroot.config), but NOT the - # upstream source archives -- this leg ships only the variant kernel - # binary + module tree, whose pinned upstream tree manifest.csv - # records the URL+hash of and this repo rebuilds from (patches-only - # mode; see ci_lib_package_legal_info for the full rationale and the - # ~520 MiB it drops). Existence-asserted (don't assume run-legal-info - # produced it) and 2 GiB-per-asset capped, same guard as the main - # legal-info step. See docs/ci.md#legal-info-2gib-cap. - if [ ! -d "output-$KERNEL/legal-info" ]; then - echo "::error::output-$KERNEL/legal-info does not exist -- did 'make $KERNEL-legal-info' run?" >&2 - exit 1 - fi - ci_lib_package_legal_info "output-$KERNEL" "kernel-artifact/legal-info-$KERNEL.tar.gz" patches-only - ci_lib_check_release_asset_size "kernel-artifact/legal-info-$KERNEL.tar.gz" "legal-info-$KERNEL.tar.gz" \ - " -- split the source bundle (see the main legal-info step's guard for options)." - else - # build.yml: manifest-only SBOM (CI push distributes nothing) -- same - # exclusions as the main job's SBOM. See docs/ci.md#kernel-variant-matrix. - ci_lib_package_legal_info "output-$KERNEL" "kernel-artifact/legal-info-$KERNEL.tar.gz" manifest-only - fi - - ls -la kernel-artifact/ - - # sha-named, not ref_name -- upload-artifact REJECTS '/' in names and every - # branch here is slash-named; a ref_name key would kill a branch dispatch - # AFTER the multi-hour build. See docs/ci.md#artifact-naming-slash-trap. - - name: Upload kernel artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: kernel-${{ inputs.kernel }}-${{ github.sha }} - path: kernel-artifact/ - if-no-files-found: error - retention-days: 14 diff --git a/.github/actions/merge-kernel-modules/action.yml b/.github/actions/merge-kernel-modules/action.yml deleted file mode 100644 index c677be25..00000000 --- a/.github/actions/merge-kernel-modules/action.yml +++ /dev/null @@ -1,95 +0,0 @@ -################################################################################ -# -# merge-kernel-modules — folds every kernel-variant module tree into the ONE -# shipped linux.img, in two phases split around buildroot-build (`phase: -# download` before, `phase: verify` after). Inputs are always strings: every -# `if:` below MUST compare against 'download'/'verify' literally, never as a -# truthiness check. See docs/ci.md#merge-kernel-modules. -# -################################################################################ - -name: Merge kernel-variant module trees into the image -description: >- - Downloads every kernel-variant artifact (build-kernel matrix leg), unpacks - its module tree into work/extra-modules-overlay/ (phase: download -- run - BEFORE buildroot-build), or asserts every downloaded kver actually merged - into output/target/usr/lib/modules/ (phase: verify -- run AFTER - buildroot-build). - -inputs: - phase: - description: >- - Which half of the merge to run: "download" (download the kernel-variant - artifacts and populate the extra-modules overlay -- must run BEFORE the - buildroot-build action) or "verify" (assert every kernel-variant module - tree merged into the built image -- must run AFTER buildroot-build). - required: true - -runs: - using: composite - steps: - # Every phase step below is gated with `if:` and has NO else-branch — an - # unrecognised phase MUST fail loud here, not fall through as a silent - # no-op. See docs/ci.md#merge-kernel-modules-fail-loud. - - name: Reject unknown phase - if: inputs.phase != 'download' && inputs.phase != 'verify' - shell: bash - env: - PHASE: ${{ inputs.phase }} - run: | - echo "::error::merge-kernel-modules: phase must be 'download' or 'verify', got '${PHASE}'" >&2 - exit 1 - - # The kernel legs' module trees, into the overlay the main defconfig's - # BR2_ROOTFS_OVERLAY names — Buildroot rsyncs it into TARGET_DIR at - # target-finalize, which is how the ONE shipped linux.img ends up carrying - # every variant's modules next to main's own. - - name: Download kernel-variant artifacts - if: inputs.phase == 'download' - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - pattern: kernel-*-${{ github.sha }} - path: kernel-artifacts - merge-multiple: true - - - name: Populate the extra-modules overlay from the kernel legs - if: inputs.phase == 'download' - shell: bash - run: | - set -euo pipefail - mkdir -p work/extra-modules-overlay - shopt -s nullglob - tars=(kernel-artifacts/modules-*.tar.gz) - # Zero tars is a wiring bug, not an empty matrix: this job only runs - # after build-kernel succeeded, and every leg uploads a modules tar. - if [ "${#tars[@]}" -eq 0 ]; then - echo "::error::no modules-*.tar.gz found under kernel-artifacts/ -- the build-kernel legs uploaded nothing this job can merge" >&2 - exit 1 - fi - for t in "${tars[@]}"; do - echo "unpacking ${t##*/} into work/extra-modules-overlay/" - tar -xzf "$t" -C work/extra-modules-overlay - done - echo "--- overlay module trees ---" - find work/extra-modules-overlay/usr/lib/modules -mindepth 1 -maxdepth 1 -type d | sort - - # A silent overlay miss must fail loudly: if a downloaded kver never made - # it into the built rootfs (overlay path typo, BR2_ROOTFS_OVERLAY edit), - # nothing else in this job would notice — the image builds green, it just - # ships a kernel whose modules are not there. - - name: Assert every kernel-variant module tree merged into the image - if: inputs.phase == 'verify' - shell: bash - run: | - set -euo pipefail - rc=0 - for f in kernel-artifacts/kver-*.txt; do - kver=$(tr -d '[:space:]' < "$f") - if [ -d "output/target/usr/lib/modules/$kver" ]; then - echo "merged: $kver (${f##*/})" - else - echo "::error::kernel-variant module tree '$kver' (${f##*/}) is MISSING from output/target/usr/lib/modules/ -- the extra-modules overlay did not reach target-finalize" >&2 - rc=1 - fi - done - exit "$rc" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7ea2d926..8912b21c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,7 +68,6 @@ jobs: runs-on: ubuntu-26.04 outputs: build_needed: ${{ steps.decide.outputs.build_needed }} - kernel_variants: ${{ steps.variants.outputs.kernel_variants }} steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -76,18 +75,6 @@ jobs: # Full history: the diff range below reaches back to a base commit # that a shallow clone would not have. fetch-depth: 0 - - # Computed UNCONDITIONALLY, before `decide` below -- `build-kernel`'s - # matrix needs a well-formed array even on a doc-only run where the job - # then never executes. Only a genuine repo bug should fail this step. - # See docs/ci.md#variants. - - name: Derive kernel-variant matrix - id: variants - run: | - set -euo pipefail - json=$(scripts/list-kernel-variants.sh) - echo "kernel_variants=$json" >> "$GITHUB_OUTPUT" - - name: Decide id: decide env: @@ -160,7 +147,7 @@ jobs: # wrapper Makefile) and runs kconfig -- no toolchain, no package, no # compile. See docs/ci.md#lint-config. lint-config: - name: Lint configuration (patch headers, fragment stacks) + name: Lint configuration (patch headers, defconfigs) needs: gate if: needs.gate.outputs.build_needed == 'true' runs-on: ubuntu-26.04 @@ -175,57 +162,16 @@ jobs: - name: Lint kernel patch headers (git am-ability, both series) run: scripts/lint-kernel-patches.sh - # Text-level: the image and kernel-only fragment stacks share their - # toolchain/kernel fragments by construction -- assert that structure - # holds (no Buildroot tree needed; the kernel legs re-run this before - # any cache restore). See docs/ci.md#kernel-defconfig-lockstep. - - name: Lint kernel-defconfig lockstep - run: scripts/check-kernel-defconfig-sync.sh - - # Resolved-level: regenerate every fragment stack through Buildroot's - # own merge_config.sh + olddefconfig and assert no redefinition - # between fragments, no silently dropped symbol, resolved lockstep, - # and the golden hash of the resolved DE10 configuration. See - # docs/ci.md#lint-config. - - name: Check fragment stacks (regenerate + golden hashes) - run: scripts/check-config-fragments.sh - - # KERNEL-ONLY leg per variant (ADR 0021); runs before `build`, which - # consumes its module tree -- a failed leg auto-skips `build` (see - # `status`). Add a variant = one new configs/mister_.fragment; - # everything here derives from the name via `gate`. See docs/ci.md#variants. - build-kernel: - name: Build kernel (${{ matrix.kernel }}) - needs: [gate, lint-config] - if: needs.gate.outputs.build_needed == 'true' - runs-on: ubuntu-26.04 - strategy: - matrix: - kernel: ${{ fromJSON(needs.gate.outputs.kernel_variants) }} - - # 240 min: an ESTIMATE -- no kernel-only leg has run yet. Re-derive from - # real runs once they exist. See docs/ci.md#kernel-leg-timeout. - timeout-minutes: 240 - - steps: - - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Check defconfigs (load, canonical, every profile select lands) + run: scripts/check-defconfigs.sh - # The shared leg recipe (build the variant, job-summary overview, stage - # + upload the artifact) -- see .github/actions/kernel-leg. Both inputs - # default to "false": manifest-only SBOM (a CI push distributes - # nothing) and the CI-flavoured Trigger/Commit/Packages(SBOM) summary. - - name: Build kernel leg (${{ matrix.kernel }}) - uses: ./.github/actions/kernel-leg - with: - kernel: ${{ matrix.kernel }} build: - name: Build image (two-stage Buildroot) + name: Build image # needs on the matrix job aggregates ALL its legs; a failed (or cancelled) # leg therefore auto-skips this job — `status` below translates that skip # into "the kernel leg is the root cause", not a second failure. - needs: [gate, lint-config, build-kernel] + needs: [gate, lint-config] if: needs.gate.outputs.build_needed == 'true' runs-on: ubuntu-26.04 @@ -243,28 +189,11 @@ jobs: # fail-before-the-3h-build property, minus the wait for the kernel # legs. See docs/ci.md#lint-config. - # Populates the overlay the build below consumes -- see - # .github/actions/merge-kernel-modules and docs/ci.md#kernel-module-overlay. - - name: Download + populate kernel-variant module overlay - uses: ./.github/actions/merge-kernel-modules - with: - phase: download - - # Everything from "prepare the runner" to "linux.img + zImage_dtb exist". - name: Build the image uses: ./.github/actions/buildroot-build with: run-legal-info: "true" - # Fails loudly on a silent overlay miss -- see - # .github/actions/merge-kernel-modules and docs/ci.md#kernel-module-overlay. - - name: Assert kernel-variant module trees merged - uses: ./.github/actions/merge-kernel-modules - with: - phase: verify - - # --- Build overview on the run's Summary page (best-effort) ------------ - # See docs/ci.md#build-summary-step. - name: Build overview (job summary) run: | set -u @@ -379,7 +308,7 @@ jobs: # needs..result is used instead of success()/failure()). status: name: Build status - needs: [gate, lint-config, build-kernel, build] + needs: [gate, lint-config, build] if: always() runs-on: ubuntu-26.04 steps: @@ -387,12 +316,11 @@ jobs: env: GATE_RESULT: ${{ needs.gate.result }} LINT_RESULT: ${{ needs.lint-config.result }} - KERNEL_RESULT: ${{ needs.build-kernel.result }} BUILD_RESULT: ${{ needs.build.result }} BUILD_NEEDED: ${{ needs.gate.outputs.build_needed }} run: | set -euo pipefail - echo "gate=$GATE_RESULT lint-config=$LINT_RESULT build-kernel=$KERNEL_RESULT build=$BUILD_RESULT build_needed=$BUILD_NEEDED" + echo "gate=$GATE_RESULT lint-config=$LINT_RESULT build=$BUILD_RESULT build_needed=$BUILD_NEEDED" if [ "$GATE_RESULT" != "success" ]; then echo "::error::The gate job did not succeed ($GATE_RESULT), so whether a build was needed is unknown. Failing rather than assuming it wasn't." @@ -402,7 +330,7 @@ jobs: rc=0 case "$LINT_RESULT" in success) - echo "lint-config: patch headers, lockstep and fragment stacks are clean." + echo "lint-config: patch headers and defconfigs are clean." ;; skipped) if [ "$BUILD_NEEDED" = "true" ]; then @@ -413,27 +341,7 @@ jobs: fi ;; *) - echo "::error::lint-config $LINT_RESULT. (Expect build-kernel and build to show as skipped below -- that is this failure cascading through needs, not two more bugs.)" - rc=1 - ;; - esac - - case "$KERNEL_RESULT" in - success) - echo "build-kernel: every kernel leg built and uploaded its module tree." - ;; - skipped) - if [ "$BUILD_NEEDED" = "true" ] && [ "$LINT_RESULT" != "success" ]; then - echo "build-kernel: skipped because lint-config did not succeed -- the needs-cascade, already failed above." - elif [ "$BUILD_NEEDED" = "true" ]; then - echo "::error::The gate asked for a build and build-kernel was skipped anyway. That is a workflow bug, not a docs change." - rc=1 - else - echo "build-kernel: documentation-only change, no build needed." - fi - ;; - *) - echo "::error::build-kernel $KERNEL_RESULT. (Expect build to show as skipped below -- that is this failure cascading through needs, not a second bug.)" + echo "::error::lint-config $LINT_RESULT. (Expect build to show as skipped below -- that is this failure cascading through needs, not a second bug.)" rc=1 ;; esac @@ -445,8 +353,8 @@ jobs: skipped) if [ "$BUILD_NEEDED" != "true" ]; then echo "build: documentation-only change, no build needed." - elif [ "$LINT_RESULT" != "success" ] || [ "$KERNEL_RESULT" != "success" ]; then - echo "build: skipped because lint-config or build-kernel did not succeed -- the needs-cascade, already failed above." + elif [ "$LINT_RESULT" != "success" ]; then + echo "build: skipped because lint-config did not succeed -- the needs-cascade, already failed above." else echo "::error::The gate asked for a build and build was skipped anyway. That is a workflow bug, not a docs change." rc=1 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 92a5ed02..d826b1e6 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -141,9 +141,9 @@ jobs: # are bash (BR2_PACKAGE_BASH is on the target). The rootfs tools are named # by their SOURCE path and carry no .sh extension -- the recursive find # above only covers scripts/, so nothing else would ever check them. - # The initramfs /init and initramfs-post-build.sh are `sh`: - # stage 1 has BusyBox ash and nothing else. `make initramfs-verify` - # additionally parses /init with the very ash we just built -- shellcheck + # The initramfs /init is `sh`: stage 1 has BusyBox ash and nothing + # else. package/mister-initramfs/verify.sh additionally parses /init with + # the very ash we just built, inside the package build -- shellcheck # checks the language, that checks the interpreter we ship. # # package/azcopy/azcopy-profile.sh is `sh` for the same reason. It is diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fad006ae..04a3df4e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,26 +1,20 @@ ################################################################################ # -# release.yml — tag-triggered release workflow + build provenance (TASKS.md -# P4.4, PLAN.md §9 "Build", docs/downloader-contract.md P0.6). +# release.yml — tag-triggered release: build, verify, package, attest, publish. # -# Builds via the same recipe as build.yml (.github/actions/buildroot-build), -# then assembles a GitHub Release for three downstream consumers: a human -# downloading assets from the Release page, the on-device Downloader_MiSTer -# (which never talks to GitHub Releases directly), and a human opting into -# the PREEMPT_RT beta kernel. See docs/ci.md#release-consumers. +# Four jobs: +# build `make` (the shared buildroot-build action) + ci-tests, then +# scripts/mk-release.sh turns output/ into a verified dist/ +# (stock archive fetched + verified, release_YYYYMMDD.7z +# assembled and round-tripped under the on-device 7za, +# SHA256SUMS), then scripts/mk-sdcard.sh adds the installer +# card image. Every step is a script you can run locally. +# build-azcopy the optional azcopy download, built as a separate config +# publish attest provenance, create a DRAFT GitHub Release +# dependency-graph submit the SBOM to GitHub's dependency graph # -# Rebuilds from the tagged commit and re-runs the full non-hardware -# verification suite rather than trusting build.yml's run or artifacts. -# See docs/ci.md#rebuild-not-adopt. -# -# Fetches (never vendors — G6) the stock uboot.img / files/linux/ payload -# from a commit-pinned third-party archive, verified before extraction. -# See docs/ci.md#stock-payload-sourcing, #stock-payload-verification, and -# the open provenance question at #stock-payload-open-decision. -# -# Tag convention (`v*`) is unratified, and the release filename / db.json -# version is deliberately decoupled from the git tag. See -# docs/ci.md#tag-convention and docs/ci.md#mister-version-coupling. +# Rationale, measurements and incident history: docs/ci.md. The STOCK_* pins +# below are Renovate-managed (docs/renovate.md). # ################################################################################ @@ -30,128 +24,33 @@ on: push: tags: - 'v*' - # Manual dispatch builds ONLY the opt-in full sdcard variant (tagged pushes - # always build the minimal one). MUST be dispatched against a tag ref, not - # a branch — the publish job is guarded to tag refs regardless, but a - # branch dispatch still burns a full build for nothing. See - # docs/ci.md#manual-full-sdcard-dispatch. + # Manual dispatch builds ONLY the opt-in full sdcard variant; dispatch it + # against a TAG ref (the publish job is guarded to tag refs regardless). workflow_dispatch: inputs: build_full_sdcard: - description: 'Also build + publish sdcard-full.img.xz (bundles _Console cores). Off by default; the minimal sdcard.img.xz is always built.' + description: 'Also build + publish sdcard-full.img.xz (bundles _Console cores). Off by default; the minimal sdcard.img.xz is always built on a tag push.' type: boolean default: false -# A re-pushed (corrected) tag should supersede an in-flight run for the same -# tag; distinct tags already get distinct concurrency groups via github.ref, -# so this never cancels a run for a DIFFERENT release. concurrency: group: release-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -# Least privilege at the workflow level; the `publish` job elevates its own -# permissions block (contents: write, id-token: write, attestations: write) -# only for the steps that actually need them (attest + create the release). permissions: contents: read jobs: - # ============================================================================ - # kernel-variants — derives the kernel-variant matrix from the filesystem - # registry; build.yml's `gate` job runs the identical script so the two - # workflows can't drift onto different matrix literals. Fails loudly on - # zero variants rather than skipping. See docs/ci.md#variants. - # ============================================================================ - kernel-variants: - name: Derive kernel-variant matrix - runs-on: ubuntu-26.04 - outputs: - kernel_variants: ${{ steps.variants.outputs.kernel_variants }} - steps: - - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - - name: Derive kernel-variant matrix - id: variants - run: | - set -euo pipefail - json=$(scripts/list-kernel-variants.sh) - echo "kernel_variants=$json" >> "$GITHUB_OUTPUT" - - # ============================================================================ - # build-kernel — the kernel-variant matrix (ADR 0021 as amended 2026-07-18), - # run BEFORE `build` because `build` merges each leg's module tree into the - # one shipped linux.img. Each leg ships the FULL kernel GPL-source bundle, - # not build.yml's manifest-only SBOM — a release DISTRIBUTES the variant - # kernel binary, so the source obligation is real. No MISTER_VERSION - # derivation here: a kernel-only build has no rootfs to bake it into. - # Adding a variant, and what still needs a hand-edit: docs/ci.md#variants. - # Matrix design (per-leg artifact contents): docs/ci.md#kernel-variant-matrix. - # No `container:` — see docs/ci.md#no-container-disk-reclaim. - # ============================================================================ - build-kernel: - name: Build kernel (${{ matrix.kernel }}) - needs: kernel-variants - runs-on: ubuntu-26.04 - strategy: - matrix: - kernel: ${{ fromJSON(needs.kernel-variants.outputs.kernel_variants) }} - - # Same estimate as build.yml's build-kernel: cold = cross-toolchain (~1h) - # + stage-1 initramfs (~30 min) + one kernel build; 240 is ~2x that. - timeout-minutes: 240 - - steps: - - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - # Shared leg recipe — see .github/actions/kernel-leg. full-legal-info - # ships the full GPL source bundle (docs/ci.md#kernel-variant-matrix); - # release-context swaps the summary for release-flavoured wording. - - name: Build kernel leg (${{ matrix.kernel }}) - uses: ./.github/actions/kernel-leg - with: - kernel: ${{ matrix.kernel }} - full-legal-info: "true" - release-context: "true" - - # ============================================================================ - # build — produces every release asset and the pinned-7za-verified archive. - # Runs after the kernel matrix so it can merge each leg's module tree into - # linux.img. No `container:` — see docs/ci.md#no-container-disk-reclaim. - # ============================================================================ build: name: Build image + assemble release_YYYYMMDD.7z - needs: build-kernel runs-on: ubuntu-26.04 - - # Cold build measured at 3h19m (run 29300460591) plus stock-archive fetch, - # archive assembly, and the sdcard steps' installer build + kernel relink - # (the relink REUSES output/, no second from-scratch build — do not - # reintroduce one; an earlier from-scratch design overran the runner's - # hard 360-min cap and the release never published). See - # docs/ci.md#sdcard-timing-6h-cap. + # Cold build ~3h20m plus packaging and the sdcard installer relink; the + # runner's hard cap is 360. See docs/ci.md#sdcard-timing-6h-cap. timeout-minutes: 355 - outputs: - release_date: ${{ steps.mister_version.outputs.release_date }} - + release_date: ${{ steps.release.outputs.release_date }} env: DEBIAN_FRONTEND: noninteractive - - # --- Pinned stock reference archive -------------------------------- - # The ONLY source in this pipeline for uboot.img and the files/linux/ - # payload we do not vendor (G6). See docs/ci.md#stock-payload-sourcing. - # - # release_20260907 is committed upstream as TWO split 7z volumes - # (.7z.001 + .7z.002 -- consecutive byte slices of one archive, not - # two archives). STOCK_RELEASE_URL is therefore a whitespace-separated - # list, in volume order; `fetch-stock` downloads each and concatenates - # them into the single stock_release.7z every later step verifies, so - # MD5/SHA-256/SIZE below are those of the JOINED file -- the same bytes - # Distribution_MiSTer's own joiner mirrors as linux_release_20260907.7z - # and the only form the on-device 7za ever sees. Verified byte-identical - # to that mirror: docs/verification/stock-release-20260907.md §1/§6. STOCK_RELEASE_URL: >- https://raw.githubusercontent.com/MiSTer-devel/SD-Installer-Win64_MiSTer/76fd6f4ced6350b0ad56a7013b41526f47e3a2fb/release_20260907.7z.001 https://raw.githubusercontent.com/MiSTer-devel/SD-Installer-Win64_MiSTer/76fd6f4ced6350b0ad56a7013b41526f47e3a2fb/release_20260907.7z.002 @@ -171,387 +70,63 @@ jobs: STOCK_7ZA_GZ_URL: https://github.com/MiSTer-devel/SD-Installer-Win64_MiSTer/raw/master/7za.gz STOCK_7ZA_GZ_MD5: ed1ad5185fbede55cd7fd506b3c6c699 STOCK_7ZA_GZ_SIZE: "465600" - steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - # MUST run before the build: post-build.sh reads MISTER_VERSION to bake - # /MiSTer.version into the image (ADR 0018). Derived from the tagged - # commit's UTC date, not SOURCE_DATE_EPOCH, so distinct tags produce - # distinct versions. See docs/ci.md#mister-version-coupling. + # /MiSTer.version is YYMMDD of the tagged commit (UTC); post-build.sh + # bakes $MISTER_VERSION into the image and mk-release.sh reads it back. - name: Derive release version (YYMMDD) from the tagged commit run: | set -eu v="${MISTER_VERSION:-$(TZ=UTC git show -s --format=%cd --date=format-local:%y%m%d HEAD)}" - case "$v" in - [0-9][0-9][0-9][0-9][0-9][0-9]) : ;; - *) echo "::error::derived MISTER_VERSION '$v' is not 6 digits YYMMDD" >&2; exit 1 ;; - esac + case "$v" in [0-9][0-9][0-9][0-9][0-9][0-9]) ;; *) echo "::error::derived MISTER_VERSION '$v' is not 6 digits YYMMDD" >&2; exit 1 ;; esac echo "MISTER_VERSION=$v" >> "$GITHUB_ENV" echo "Release version (YYMMDD) = $v -> /MiSTer.version, release_20${v}.7z, db.json" - # Populates the extra-modules overlay before the build — see - # .github/actions/merge-kernel-modules for the mechanism. Also feeds - # dist/'s per-variant zImage_dtb/config/legal-info assets, staged later - # in this job. - - name: Download + populate kernel-variant module overlay - uses: ./.github/actions/merge-kernel-modules - with: - phase: download - - # Shared recipe (disk reclaim, caches, apt, defconfig, `make all`). - # p7zip-full here is a DIFFERENT 7za than the pinned ARM dynamic one - # fetched below — this one only creates/inspects the archive on the - # x86_64 runner. See docs/ci.md#stock-payload-verification. - name: Build the image uses: ./.github/actions/buildroot-build with: - # extra-apt-packages: p7zip-full assembles release_YYYYMMDD.7z; the - # rest are host-only tools scripts/mk-sdcard.sh needs (genimage, - # mtools, dosfstools, xz-utils, jq) — none enter the shipped rootfs. - # See docs/ci.md#release-apt-packages. + # p7zip-full packs the 7z; the rest are host tools mk-sdcard.sh needs. extra-apt-packages: p7zip-full genimage mtools dosfstools xz-utils jq run-legal-info: "true" - # Assert every kernel-variant module tree merged into the image -- see - # .github/actions/merge-kernel-modules/action.yml for the silent-overlay- - # miss guard this runs. - - name: Assert kernel-variant module trees merged - uses: ./.github/actions/merge-kernel-modules - with: - phase: verify - - # Re-runs build.yml's non-hardware parity suite (ci-tests.sh) and ABI/ - # SONAME checker (check-abi.sh) against THIS EXACT rootfs — the tagged - # commit may not be one build.yml ever validated. See - # docs/ci.md#rebuild-not-adopt. skip-qemu-system matches build.yml; - # see .github/actions/verify-image for the full rationale. - name: Run parity suite + ABI/SONAME checker uses: ./.github/actions/verify-image with: skip-qemu-system: "true" - ########################################################################## - # Assemble dist/. See docs/ci.md#dist-layout for the asset contract. - ########################################################################## - - - name: Stage dist/ and copy the two image assets - run: | - set -eu - mkdir -p dist - cp -f output/images/linux.img dist/linux.img - cp -f output/images/zImage_dtb dist/zImage_dtb - - - name: Copy buildroot.config and linux.config - run: | - set -eu - # nullglob keeps a zero-match glob's count truthful for the guard - # below (mirrors .github/actions/kernel-leg's staging step). See - # docs/ci.md#dist-layout. - shopt -s nullglob - cp -f output/.config dist/buildroot.config - trees=(output/build/linux-[0-9]*/) - if [ "${#trees[@]}" -ne 1 ] || [ ! -d "${trees[0]}" ]; then - echo "::error::expected exactly one kernel tree at output/build/linux-[0-9]*/ but found ${#trees[@]} -- cannot stage linux.config (zero: the build produced no kernel tree; more than one: a stale sibling from a version bump, e.g. linux-headers-*/linux-firmware-* are excluded by the glob but another linux-/ would not be)" >&2 - exit 1 - fi - cp -f "${trees[0]}.config" dist/linux.config - - # patches-only: ship our applied patches + the SBOM (manifest.csv with - # each package's pinned upstream URL+hash, license texts, buildroot.config) - # but NOT the upstream *.tar.* source archives. Each archive is the - # freely-available, hash-pinned upstream manifest.csv points to and this - # public repo rebuilds byte-for-byte, so bundling ~1.4 GiB of it into - # every release (591 MiB of that the linux-firmware blob alone) only - # duplicated what the repo + upstream already provide and left ~664 MiB - # under GitHub's 2 GiB per-asset cap as firmware grows each release. The - # complete corresponding source is this repo at the tag + that referenced - # upstream; the release notes below carry the GPLv2 written offer. - # host-sources/ (the build-time toolchain) is dropped in every mode - # regardless. See docs/ci.md#legal-info-2gib-cap. - - name: Archive legal-info as legal-info.tar.gz - run: | - set -eu - # shellcheck source=scripts/ci-lib.sh - source scripts/ci-lib.sh - if [ ! -d output/legal-info ]; then - echo "::error::output/legal-info does not exist -- did 'make legal-info' run?" >&2 - exit 1 - fi - ci_lib_package_legal_info output dist/legal-info.tar.gz patches-only - - # GitHub's hard per-asset ceiling is 2 GiB. Fail here, with a clear - # message, rather than at the upload. - ci_lib_check_release_asset_size dist/legal-info.tar.gz legal-info.tar.gz \ - ". The package set has outgrown a single source bundle -- split it (e.g. sources/ as its own asset, or publish sources to a separate host and reference them from manifest.csv)." - - # The per-variant release extras, straight from the leg artifacts (the - # legs already applied the uniqueness guards and the legal-info size - # guard). Copied by glob so a future matrix entry needs no edit here; - # each glob must match at least once — zero matches means the download - # step above silently changed shape, and cp's own failure catches that. - - name: Stage kernel-variant assets into dist/ - run: | - set -eu - cp -f kernel-artifacts/zImage_dtb-* kernel-artifacts/linux-*.config \ - kernel-artifacts/legal-info-*.tar.gz dist/ - ls -la dist/ - - ########################################################################## - # /MiSTer.version -> RELEASE_DATE. LOAD-BEARING: db.json's linux.version - # must equal, byte-for-byte, this baked value (docs/downloader-contract.md - # §3/§12) — see docs/ci.md#mister-version-coupling. - ########################################################################## - - name: Extract and validate /MiSTer.version from the built image - id: mister_version - run: | - set -eu - workdir=$(mktemp -d ./mister-version.XXXXXX) - debugfs -R "rdump /MiSTer.version ${workdir}" output/images/linux.img >/dev/null 2>"${workdir}.debugfs.log" || true - verfile="${workdir}/MiSTer.version" - if [ ! -f "$verfile" ]; then - echo "::error::debugfs could not extract /MiSTer.version from output/images/linux.img" >&2 - sed 's/^/ /' "${workdir}.debugfs.log" >&2 || true - exit 1 - fi - n=$(wc -c < "$verfile") - if [ "$n" -ne 6 ]; then - echo "::error::/MiSTer.version is ${n} bytes, expected exactly 6 (docs/downloader-contract.md §3/§12)" >&2 - exit 1 - fi - last_byte_hex=$(tail -c1 "$verfile" | od -An -tx1 | tr -d ' ') - if [ "$last_byte_hex" = "0a" ]; then - echo "::error::/MiSTer.version ends in a newline -- this permanently breaks the Downloader's version-equality check (docs/downloader-contract.md §3)" >&2 - exit 1 - fi - yymmdd=$(cat "$verfile") - case "$yymmdd" in - [0-9][0-9][0-9][0-9][0-9][0-9]) : ;; - *) - echo "::error::/MiSTer.version content '$yymmdd' is not 6 ASCII digits" >&2 - exit 1 - ;; - esac - # Verify the build honored the MISTER_VERSION override (ADR 0018): - # /MiSTer.version must equal what we asked post-build.sh to bake. - if [ "$yymmdd" != "${MISTER_VERSION:-}" ]; then - echo "::error::built /MiSTer.version '$yymmdd' != requested MISTER_VERSION '${MISTER_VERSION:-}' -- post-build.sh did not honor the override" >&2 - exit 1 - fi - # Assumption, flagged: century is hardcoded "20" (valid until the - # year 2100). /MiSTer.version itself only ever carries YYMMDD, same - # as stock's own convention (e.g. "250402" for release_20250402.7z). - release_date="20${yymmdd}" - echo "release_date=${release_date}" >> "$GITHUB_OUTPUT" - echo "Resolved /MiSTer.version='${yymmdd}' -> RELEASE_DATE=${release_date}" - - ########################################################################## - # Fetch + verify the pinned stock archive — MUST fully verify (MD5+size, - # then a separate 7z internal-CRC test) before extracting a byte. These - # four steps call scripts/verify-stock-payload.sh (runnable standalone); - # the STOCK_* pins live only in this job's env: block above. See - # docs/ci.md#stock-payload-verification. - ########################################################################## - - name: Fetch pinned stock release archive - run: scripts/verify-stock-payload.sh fetch-stock stock_release.7z - - - name: Verify stock archive integrity (MD5, SHA-256, size) - run: scripts/verify-stock-payload.sh verify-stock stock_release.7z - - - name: Extract files/linux/* from the verified stock archive - run: scripts/verify-stock-payload.sh extract-stock stock_release.7z stock-extract - - - name: Re-verify stock uboot.img and updateboot hashes (defense in depth) - run: scripts/verify-stock-payload.sh verify-uboot stock-extract - - ########################################################################## - # Overlay our freshly built linux.img/zImage_dtb onto the verified stock - # files/linux/ tree — mirrors the real Downloader's own on-device rsync. - # See docs/ci.md#stock-payload-verification. - ########################################################################## - - name: Assemble release tree (files/linux/*) - run: | - set -eu - mkdir -p release-stage - cp -a stock-extract/files release-stage/files - cp -f output/images/linux.img release-stage/files/linux/linux.img - cp -f output/images/zImage_dtb release-stage/files/linux/zImage_dtb - # ADD (not overlay) the statically-linked 7-Zip 26.03 that - # package/7zip builds. The stock archive has NO 7za of any kind -- - # which is exactly why a stock device downloads p7zip 16.02 (2016) - # from SD-Installer-Win64_MiSTer the first time it needs to extract - # an update. The Downloader's own flash-phase rsync has no --delete - # but DOES overwrite files present in the source, so shipping it here - # replaces whatever /media/fat/linux/7za a device already has, on - # every update. ADR 0023, docs/downloader-contract.md §4. - # - # This does NOT relax the hard constraint that our archive must stay - # extractable by that old pinned binary: the very update that - # installs our 7za is itself unpacked by whatever 7za was already - # there. The qemu-arm round-trip step further down still runs the - # 2016 binary against this archive, and must keep passing. - cp -f output/images/7za release-stage/files/linux/7za - echo "release-stage/files/linux/ contents:" - find release-stage/files/linux -maxdepth 1 -printf '%f\n' | sort - - - name: Create release_${RELEASE_DATE}.7z (plain solid LZMA2, no BCJ2) - env: - RELEASE_DATE: ${{ steps.mister_version.outputs.release_date }} - run: | - set -eu - # Plain solid LZMA2, not stock's BCJ2 (a Windows-7-Zip-GUI artifact, - # irrelevant here) — see docs/ci.md#stock-payload-verification. - # - # -mf=off IS LOAD-BEARING, added 2026-07-27 with ADR 0023's files/linux/7za. - # 7-Zip auto-detects an executable filter from the CONTENT it is given, so - # the moment the payload gained an ARM ELF the encoding silently changed: - # reproduced with this exact command, `Method = LZMA2 ARM` and Blocks = 2, - # where the same command over an ELF-free payload gives plain - # `Method = LZMA2`, Blocks = 1. That contradicts the "no BCJ/BCJ2/ARM - # filter" guarantee docs/downloader-contract.md §4 makes, which the - # pinned-2016-extractor constraint rests on. The ARM filter happens to be - # readable by p7zip 16.02 (checked: `t` exit 0, extraction byte-identical), - # so this is determinism and keeping a documented invariant TRUE, not a bug - # fix — but the point of that invariant is precisely not to gamble on which - # filters a decade-old extractor implements, and auto-detection is exactly a - # gamble: a future payload member could trip a filter 16.02 lacks. The - # roundtrip step below would catch that after the fact; -mf=off means it - # cannot arise. - # - # NOT passing -snl, deliberately: upstream 7-Zip DEREFERENCES symlinks when - # writing unless told otherwise (p7zip 16.02 stored them as links by - # default — the defaults differ). release-stage/files/ holds no symlinks - # today so there is nothing to preserve, and enabling it would add an - # untested archive shape. If a symlink is ever added to the payload, revisit - # this line: it would otherwise be silently flattened into a copy. - ( cd release-stage && 7z a -mx=9 -m0=lzma2 -mf=off -ms=on "../dist/release_${RELEASE_DATE}.7z" files/ ) - echo "Created dist/release_${RELEASE_DATE}.7z" - - ########################################################################## - # Verify with the EXACT pinned ARM 7za the real Downloader uses, - # under qemu-arm — not a modern host 7z. See - # docs/ci.md#stock-payload-verification. - ########################################################################## - - name: Fetch and verify the pinned ARM 7za - run: scripts/verify-stock-payload.sh fetch-7za 7za - - # The pinned 7za is dynamically linked (glibc), not static -- qemu-arm - # needs -L pointed at an ARM sysroot to resolve its loader/shared libs. - # output/target (this job's own build) already has a matching glibc - # sysroot, so it's reused here rather than installing armhf multiarch - # packages on the runner. See docs/ci.md#stock-payload-verification. - - name: Verify our archive extracts under the pinned ARM 7za (qemu-arm) - env: - RELEASE_DATE: ${{ steps.mister_version.outputs.release_date }} - run: scripts/verify-stock-payload.sh roundtrip "dist/release_${RELEASE_DATE}.7z" ./7za downloader-extract output/target - - - name: Re-verify uboot.img/updateboot after the ARM-7za round trip - run: scripts/verify-stock-payload.sh verify-uboot downloader-extract --hash-only - - - name: Verify archive layout matches the assembled contract tree - env: - RELEASE_DATE: ${{ steps.mister_version.outputs.release_date }} - run: scripts/verify-stock-payload.sh verify-layout "dist/release_${RELEASE_DATE}.7z" release-stage - - # Generated ONCE, covering every asset (main seven + kernel-variant - # extras) — no publish-side append step anymore. See - # docs/ci.md#old-two-image-design-retired. - - name: Generate SHA256SUMS - env: - RELEASE_DATE: ${{ steps.mister_version.outputs.release_date }} + - name: Stage, package and verify the release assets (scripts/mk-release.sh) + id: release run: | set -eu - ( cd dist && sha256sum "release_${RELEASE_DATE}.7z" linux.img zImage_dtb buildroot.config linux.config legal-info.tar.gz \ - zImage_dtb-* linux-*.config legal-info-*.tar.gz > SHA256SUMS ) - cat dist/SHA256SUMS - - ########################################################################## - # sdcard installer image (TASKS.md P5.3, ADR 0017 §4 amended by ADR 0020). - # Standalone flashable assets — never in release_YYYYMMDD.7z, never - # referenced by db.json. See docs/ci.md#sdcard-contract. - ########################################################################## - - # Reuses the stock archive already verified above by seeding - # fetch-sdcard-payload.sh's own cache (it re-checks size+MD5+SHA-256, so - # this is a hand-off of verified bytes, not a bypass). Skipped only on - # an opt-in full-sdcard dispatch, where it would be pure redundancy. See - # docs/ci.md#sdcard-contract and docs/ci.md#manual-full-sdcard-dispatch. - - name: Build sdcard.img.xz (minimal installer image) - if: ${{ !inputs.build_full_sdcard }} - env: - STAGE_DIR: ${{ github.workspace }}/output-sdcard-stage - run: | - set -eu - mkdir -p "$STAGE_DIR/.fetch-cache" - cp -f stock_release.7z "$STAGE_DIR/.fetch-cache/stock_release.7z" - scripts/mk-sdcard.sh - ls -la output/images/sdcard.img output/images/sdcard.img.xz - - # Static, offline contract check (partition table, uboot.img head, FAT32 - # payload inventory vs docs/verification/sdcard-payload.md). STOCK_UBOOT_* - # come from the job env for the default uboot head compare. Same skip - # condition as the build step it verifies. - - name: Verify sdcard.img (scripts/check-sdcard.sh) - if: ${{ !inputs.build_full_sdcard }} - run: scripts/check-sdcard.sh output/images/sdcard.img + scripts/mk-release.sh output dist + echo "release_date=$(cat dist/RELEASE_DATE)" >> "$GITHUB_OUTPUT" - # Opt-in only: the full variant bundles _Console cores (much larger, needs - # the GitHub Contents API). Runs only on a workflow_dispatch with the input - # set. Reuses the same warm STAGE_DIR (stock archive + installer builds - # already there), just adds the cores; fetch-sdcard-payload.sh reconciles. - - name: Build + verify sdcard-full.img.xz (opt-in _Console cores) - if: ${{ inputs.build_full_sdcard }} + # Reuses the stock archive mk-release.sh already verified by seeding + # mk-sdcard.sh's fetch cache (it re-checks size/MD5/SHA-256 itself). + - name: Build + verify the sdcard installer image env: STAGE_DIR: ${{ github.workspace }}/output-sdcard-stage - SDCARD_CORES: "1" + SDCARD_CORES: ${{ inputs.build_full_sdcard && '1' || '0' }} GITHUB_TOKEN: ${{ github.token }} run: | set -eu mkdir -p "$STAGE_DIR/.fetch-cache" - cp -f stock_release.7z "$STAGE_DIR/.fetch-cache/stock_release.7z" + cp -f release-work/stock_release.7z "$STAGE_DIR/.fetch-cache/stock_release.7z" scripts/mk-sdcard.sh - scripts/check-sdcard.sh output/images/sdcard-full.img - ls -la output/images/sdcard-full.img output/images/sdcard-full.img.xz - - # Into dist/ so the existing "Upload release asset bundle" step carries them - # to the publish job. sdcard-full.img.xz is only present when the opt-in - # step above ran. - - name: Stage sdcard image(s) into dist/ - run: | - set -eu - # Stage whichever variant(s) this run actually built. A tag push builds - # the minimal image; an opt-in full dispatch (which SKIPS the minimal - # build above, since the tag already carries it) builds only the full - # one. The publish job's `gh release upload --clobber` then adds/refreshes - # exactly what landed in dist/, leaving any already-attached asset intact. - if [ -f output/images/sdcard.img.xz ]; then - cp -f output/images/sdcard.img.xz dist/sdcard.img.xz - fi - if [ -f output/images/sdcard-full.img.xz ]; then - cp -f output/images/sdcard-full.img.xz dist/sdcard-full.img.xz - fi + img=sdcard.img; [ "$SDCARD_CORES" = 1 ] && img=sdcard-full.img + scripts/check-sdcard.sh "output/images/$img" + cp -f "output/images/$img.xz" dist/ ls -la dist/ - # --- Release overview on the run's Summary page ------------------------ - # The tag, the internal version, the archive + image sizes, the full - # SHA256SUMS, and -- most importantly -- the draft/db.json coupling a - # human needs to understand before clicking Publish. - name: Release overview (job summary) env: - RELEASE_DATE: ${{ steps.mister_version.outputs.release_date }} + RELEASE_DATE: ${{ steps.release.outputs.release_date }} TAG: ${{ github.ref_name }} run: | set -u - # shellcheck source=scripts/ci-lib.sh - # Explicit fallback if ci-lib.sh is missing, rather than a silent - # abort. See docs/ci.md#ci-lib-source-fallback. - source scripts/ci-lib.sh || { - echo "::warning::scripts/ci-lib.sh not found -- size facts below will read n/a" >&2 - ci_lib_sz() { echo "n/a"; } - } - arc="dist/release_${RELEASE_DATE}.7z" - assets=$(find dist -maxdepth 1 -type f | wc -l) + source scripts/ci-lib.sh { echo "## 🚀 Release build summary" echo "" @@ -559,42 +134,27 @@ jobs: echo "|---|---|" echo "| Tag | \`${TAG}\` |" echo "| Internal version (\`/MiSTer.version\`) | \`${RELEASE_DATE}\` |" - echo "| Archive | \`release_${RELEASE_DATE}.7z\` ($(ci_lib_sz "$arc")) |" + echo "| Archive | \`release_${RELEASE_DATE}.7z\` ($(ci_lib_sz "dist/release_${RELEASE_DATE}.7z")) |" echo "| linux.img | $(ci_lib_sz dist/linux.img) |" - echo "| zImage_dtb | $(ci_lib_sz dist/zImage_dtb) |" - echo "| Assets staged | ${assets} |" + echo "| zImage_dtb / zImage_dtb-rt | $(ci_lib_sz dist/zImage_dtb) / $(ci_lib_sz dist/zImage_dtb-rt) |" + echo "| Assets staged | $(find dist -maxdepth 1 -type f | wc -l) |" echo "" - echo "**Verified before packaging:** stock archive MD5/SHA-256/size + 7z CRC · \`uboot.img\`/\`updateboot\` byte-identical to stock (before *and* after the archive round-trip) · our \`.7z\` extracts under the pinned ARM \`7za\` (qemu-arm) · archive member list matches docs/downloader-contract.md · rootfs passes the non-hardware parity suite (\`ci-tests.sh\`) and the ABI/SONAME checker (section above)." + echo "**Verified before packaging:** stock archive MD5/SHA-256/size + 7z CRC · \`uboot.img\`/\`updateboot\` byte-identical to stock before *and* after the round trip · our \`.7z\` extracts under the pinned ARM \`7za\` (qemu-arm) · archive member list matches the assembled tree · rootfs passes \`ci-tests.sh\` and the ABI/SONAME checker." echo "" - echo "**Next:** the \`publish\` job attests build provenance and creates a **DRAFT** GitHub Release. A draft is not public and does **not** trigger db.json publication (\`publish-db.yml\` gates on a *published, non-draft* release) until a human clicks **Publish**." + echo "**Next:** \`publish\` attests provenance and creates a **DRAFT** release; db.json is published only after a human clicks **Publish** (\`publish-db.yml\` gates on a non-draft release)." echo "" - echo "
SHA256SUMS" - echo "" - echo '```' - cat dist/SHA256SUMS 2>/dev/null || echo "(SHA256SUMS not found)" - echo '```' - echo "" - echo "
" + echo "
SHA256SUMS"; echo ""; echo '```'; cat dist/SHA256SUMS; echo '```'; echo ""; echo "
" } >> "$GITHUB_STEP_SUMMARY" - # A second, differently-timed disk/cache sample than the build action's - # own (action.yml, if: always()) — taken AFTER the stock-archive - # re-fetch, archive assembly, and sdcard builds, which are what's most - # likely to exhaust the runner's disk. Not a duplicate; do not remove. - # See docs/ci.md#disk-usage-double-sample. - name: Report disk & cache usage if: always() run: | echo "--- disk free ---"; df -h . echo "--- dl/ ---"; du -sh dl 2>/dev/null || true - echo "--- output/host ---"; du -sh output/host 2>/dev/null || true - echo "--- output (total) ---"; du -sh output 2>/dev/null || true + echo "--- output ---"; du -sh output 2>/dev/null || true echo "--- ccache ---"; du -sh "$GITHUB_WORKSPACE/.ccache" 2>/dev/null || true echo "--- dist/ ---"; ls -la dist/ 2>/dev/null || true - # sha-named, not ref_name: upload-artifact REJECTS '/' in names, and a - # branch dispatch's ref_name can contain one. See - # docs/ci.md#artifact-naming-slash-trap. - name: Upload release asset bundle uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: @@ -603,34 +163,6 @@ jobs: if-no-files-found: error retention-days: 14 - # ============================================================================ - # build-azcopy — builds the optional azcopy download (docs/azcopy.md). - # - # A SEPARATE JOB, AND THAT IS THE WHOLE POINT. azcopy is deliberately NOT in - # the image (BR2_PACKAGE_AZCOPY is unset; 39 MiB, see docs/azcopy.md §1), so - # the one thing this must never do is leak into linux.img. Building it in the - # `build` job's output/ would do exactly that, and not hypothetically: - # scripts/mk-sdcard.sh REGENERATES linux.img from that same output/ after the - # image has already been staged ("snapshots that image BEFORE its own step-2 - # relink regenerates it" -- its own header). Anything sitting in output/target - # at that moment ships. A different runner with a different checkout cannot - # make that mistake, at any point in the step order, no matter what is added - # to `build` later. - # - # It also costs nothing on the critical path. `build` is budgeted at 355 min - # against a hard 360-min cap and has already overrun it once (see that job's - # timeout comment); this runs concurrently instead of eating that ~36 min of - # slack. The trade is one extra runner: measured ~4-5 min for host-go plus - # ~12 s for azcopy itself, on top of the target toolchain. - # - # STATIC (CGO_ENABLED=0), for the same reason package/7zip ships a static - # /media/fat/linux/7za: a downloaded binary OUTLIVES the rootfs that put it - # there. It has to survive a rollback to an older linux.img, or to a stock - # image whose glibc is years behind ours. A dynamic build dies at exec with - # GLIBC_2.xx-not-found; static removes the failure mode. Costs the pure-Go - # DNS resolver instead of glibc NSS, which is not a difference anyone will - # notice here. - # ============================================================================ build-azcopy: name: Build azcopy (optional download) runs-on: ubuntu-26.04 @@ -666,15 +198,12 @@ jobs: restore-keys: br-dl-azcopy- # `echo >> .config` + olddefconfig is the standard Buildroot idiom for - # "the committed configuration, plus this one symbol". It is used rather - # than a committed fragment because there is exactly one symbol and no - # make target to hang a fragment off (unlike configs/mister_rt.fragment, - # which `make rt` exists to apply). BR2_PACKAGE_HOST_GO and - # BR2_PACKAGE_CA_CERTIFICATES come along via the package's own `select`s. - - name: Configure (DE10-Nano fragment stack + azcopy) + # "the committed configuration, plus this one symbol". BR2_PACKAGE_HOST_GO + # and BR2_PACKAGE_CA_CERTIFICATES come along via the package's own selects. + - name: Configure (the DE10 defconfig + azcopy) run: | set -eu - make de10nano-defconfig + make mister_de10nano_defconfig echo 'BR2_PACKAGE_AZCOPY=y' >> output/.config make olddefconfig grep -qx 'BR2_PACKAGE_AZCOPY=y' output/.config @@ -751,163 +280,72 @@ jobs: # ============================================================================ publish: name: Attest provenance + create GitHub Release - # build-azcopy is a hard dependency, not a soft one: a release that - # silently dropped the optional azcopy download because that job failed - # would look identical to a release that never carried it. Fail the - # publish instead. See docs/ci.md#azcopy-release-asset. needs: [build, build-azcopy] runs-on: ubuntu-26.04 - - # Only ever create a Release for a TAG. On a tag push this is always true, so - # existing behaviour is unchanged; it exists so a workflow_dispatch on a - # NON-tag ref (used to build the opt-in full sdcard variant) still runs the - # `build` job's build+verify but does NOT mint a branch-named release here. if: startsWith(github.ref, 'refs/tags/') - permissions: contents: write # create the Release and upload its assets id-token: write # attest-build-provenance's OIDC token exchange attestations: write # publish the attestation to this repo - steps: - # ONE bundle now — build stages everything (main seven, variant extras, - # sdcard images, SHA256SUMS) — nothing to merge/append here anymore. - # See docs/ci.md#old-two-image-design-retired. - name: Download release asset bundle uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: release-dist-${{ github.sha }} path: dist - # Into the same dist/ the main bundle landed in, so the assets array - # below stays one flat list. Separate artifact because it comes from a - # separate job -- see build-azcopy's header for why that job is separate. - name: Download azcopy asset uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: azcopy-dist-${{ github.sha }} path: dist - - name: List downloaded assets - run: ls -la dist/ - - # Re-derives the variant registry from dist/SHA256SUMS (this checkout- - # less job has no scripts/list-kernel-variants.sh on disk — see - # docs/ci.md#variants) and asserts BY NAME that all three files exist - # for EVERY variant. A glob-and-count check could only ever notice the - # ALL-missing case; this backstops the attestation step below, which - # cannot police itself either. See docs/ci.md#attest-provenance-scope. - - name: Verify every kernel variant's assets survived the artifact round trip + # The asset list is fixed; a file that did not survive the artifact + # round trip fails here rather than producing a release with a hole. + - name: Check every asset survived the artifact round trip + env: + RELEASE_DATE: ${{ needs.build.outputs.release_date }} run: | - set -euo pipefail - if [ ! -f dist/SHA256SUMS ]; then - echo "::error::dist/SHA256SUMS is missing -- the build job's 'Generate SHA256SUMS' step should have produced it; refusing to publish a release whose asset manifest did not survive the release-dist-${{ github.sha }} round trip" >&2 - exit 1 - fi - # `hash name` (two spaces; a leading '*' if it was ever hashed in - # binary mode) -- take field 2, keep only the zImage_dtb- - # rows, and strip the prefix to leave the variant names. - mapfile -t variants < <(awk '{ sub(/^\*/, "", $2); print $2 }' dist/SHA256SUMS | sed -n 's/^zImage_dtb-\(.*\)$/\1/p' | sort -u) - if [ "${#variants[@]}" -eq 0 ]; then - echo "::error::dist/SHA256SUMS records no zImage_dtb- entries (expected at least \`rt\`) -- the build-kernel matrix runs on every trigger that reaches this job, so zero variants is a bug, not a valid empty state" >&2 - exit 1 - fi - echo "kernel variants recorded in SHA256SUMS: ${variants[*]}" - missing=0 - : > "$RUNNER_TEMP/variant-assets.txt" - for v in "${variants[@]}"; do - for f in "dist/zImage_dtb-$v" "dist/linux-$v.config" "dist/legal-info-$v.tar.gz"; do - if [ ! -f "$f" ]; then - echo "::error::kernel-variant asset $f is missing from dist/ although SHA256SUMS records variant \`$v\` -- it went missing between the build job staging it and this job downloading release-dist-${{ github.sha }}" >&2 - missing=1 - continue - fi - printf '%s\n' "$f" >> "$RUNNER_TEMP/variant-assets.txt" - done + set -eu + ls -la dist/ + for f in "release_${RELEASE_DATE}.7z" linux.img zImage_dtb zImage_dtb-rt SHA256SUMS buildroot.config linux.config linux-rt.config legal-info.tar.gz; do + [ -f "dist/$f" ] || { echo "::error::dist/$f is missing -- it went missing between the build job and this one" >&2; exit 1; } done - if [ "$missing" -ne 0 ]; then - echo "::error::refusing to publish a release missing one or more kernel-variant assets" >&2 - exit 1 - fi - cat "$RUNNER_TEMP/variant-assets.txt" + ( cd dist && sha256sum -c SHA256SUMS ) + azc=(dist/azcopy-*-armv7.xz dist/azcopy-*-armv7.xz.sha256) + [ "${#azc[@]}" -eq 2 ] && [ -f "${azc[0]}" ] && [ -f "${azc[1]}" ] || { echo "::error::expected dist/azcopy--armv7.xz and its .sha256 from the build-azcopy job" >&2; exit 1; } - # Attests only the shipped binaries; the zImage_dtb-* glob covers - # whatever the kernel-variant matrix built. Do NOT rely on this action - # to catch a missing variant asset itself — the verify step above is - # what does that. See docs/ci.md#attest-provenance-scope. - name: Attest build provenance for the image assets uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 with: subject-path: | dist/linux.img dist/zImage_dtb - dist/zImage_dtb-* + dist/zImage_dtb-rt - # Created as a DRAFT, deliberately: publish-db.yml only fires on a - # published (non-draft) release — this is the human-approval gate - # between "CI built an image" and "every subscribed MiSTer is offered - # it." See docs/ci.md#release-draft-gate. - name: Create draft GitHub Release env: GITHUB_TOKEN: ${{ github.token }} - # GH_REPO required: no checkout here, and gh ignores - # $GITHUB_REPOSITORY — without it every `gh release` call dies at - # repo-resolution and a green ~9h build silently produces NO - # release. Inherited from origin/master's publish job; fixed here. - # See docs/ci.md#gh-repo-bug. GH_REPO: ${{ github.repository }} RELEASE_DATE: ${{ needs.build.outputs.release_date }} TAG: ${{ github.ref_name }} run: | set -eu - # sdcard*.img.xz — standalone assets, never in the 7z, never in - # db.json (ADR 0017 §4 / ADR 0020). See docs/ci.md#sdcard-contract. assets=( dist/"release_${RELEASE_DATE}.7z" - dist/linux.img - dist/zImage_dtb - dist/SHA256SUMS - dist/buildroot.config - dist/linux.config + dist/linux.img dist/zImage_dtb dist/zImage_dtb-rt + dist/SHA256SUMS dist/buildroot.config dist/linux.config dist/linux-rt.config dist/legal-info.tar.gz ) - # Per-variant assets are read back from - # $RUNNER_TEMP/variant-assets.txt (written by the verify step - # above), not named or globbed here — a glob-and-count could only - # ever notice the ALL-missing case. See - # docs/ci.md#release-assets-array. - mapfile -t variant_assets < "$RUNNER_TEMP/variant-assets.txt" - if [ "${#variant_assets[@]}" -eq 0 ]; then - echo "::error::no kernel-variant assets listed in \$RUNNER_TEMP/variant-assets.txt (expected at least zImage_dtb-rt, linux-rt.config, legal-info-rt.tar.gz) -- the 'Verify every kernel variant's assets survived the artifact round trip' step should have written them and failed the job if it could not; refusing to publish a release missing its kernel-variant assets" >&2 - exit 1 - fi - assets+=("${variant_assets[@]}") - [ -f dist/sdcard.img.xz ] && assets+=(dist/sdcard.img.xz) - [ -f dist/sdcard-full.img.xz ] && assets+=(dist/sdcard-full.img.xz) - # azcopy: globbed rather than named because the filename carries the - # package's version (azcopy--armv7.xz), and this job has no - # checkout to read AZCOPY_VERSION from. Unlike the sdcard lines above - # this is NOT optional -- build-azcopy is in `needs:` and uploads with - # if-no-files-found: error, so an empty glob here means something - # upstream lied and the release must not go out half-assembled. - mapfile -t azcopy_assets < <(ls dist/azcopy-*-armv7.xz dist/azcopy-*-armv7.xz.sha256 2>/dev/null || true) - if [ "${#azcopy_assets[@]}" -ne 2 ]; then - echo "::error::expected dist/azcopy--armv7.xz and its .sha256 from the build-azcopy job, found ${#azcopy_assets[@]} file(s); refusing to publish a release missing the optional azcopy download" >&2 - exit 1 - fi - assets+=("${azcopy_assets[@]}") - # Added unconditionally (build-kernel always runs, so at least one - # variant is guaranteed — the verify step above already failed the - # job otherwise). The release-notes prose below is a hand-edit per - # variant, same as mk-sdcard.sh's single bonus-kernel slot — see - # docs/ci.md#variants for the full accounting. + for f in dist/sdcard.img.xz dist/sdcard-full.img.xz; do [ -f "$f" ] && assets+=("$f"); done + assets+=(dist/azcopy-*-armv7.xz dist/azcopy-*-armv7.xz.sha256) notes="Automated release build. Internal linux version (baked \`/MiSTer.version\`): ${RELEASE_DATE}. See SHA256SUMS for asset hashes and the attached build-provenance attestation (verify with \`gh attestation verify --owner ${{ github.repository_owner }}\`). The \`sdcard*.img.xz\` assets are standalone flashable installer images (ADR 0020); they are NOT part of release_${RELEASE_DATE}.7z and are not referenced by db.json. - **Complete corresponding source (GPL/LGPL):** every binary here is built from free/open-source software with Buildroot. \`legal-info.tar.gz\` (main image) and \`legal-info-rt.tar.gz\` (RT kernel) ship the SBOM — \`manifest.csv\` listing each package's exact version, license, and pinned upstream source URL+hash — plus every license text, all local patches we apply, and \`buildroot.config\`. The upstream source archives themselves are deliberately NOT bundled: they are the freely-available, hash-pinned upstreams \`manifest.csv\` points to, and re-bundling ~1.4 GiB of them (591 MiB of that the linux-firmware blob alone) into every release only duplicated what upstream + this repo already provide. The complete corresponding source for every GPL/LGPL component is (a) the upstream archives at the exact versions/URLs in \`manifest.csv\`, byte-verifiable against their recorded hashes, plus (b) this repository at tag \`${{ github.ref_name }}\`, which carries the full Buildroot configuration and all applied patches and rebuilds the identical images with \`make\`. **Written offer:** for at least three years from this release, we will additionally provide a complete machine-readable copy of the corresponding source for any component on request — open an issue at https://github.com/${{ github.repository }}. + **Complete corresponding source (GPL/LGPL):** every binary here is built from free/open-source software with Buildroot. \`legal-info.tar.gz\` (the main image AND the RT kernel, which is a package of the same build) ships the SBOM — \`manifest.csv\` listing each package's exact version, license, and pinned upstream source URL+hash — plus every license text, all local patches we apply, and \`buildroot.config\`. The upstream source archives themselves are deliberately NOT bundled: they are the freely-available, hash-pinned upstreams \`manifest.csv\` points to, and re-bundling ~1.4 GiB of them (591 MiB of that the linux-firmware blob alone) into every release only duplicated what upstream + this repo already provide. The complete corresponding source for every GPL/LGPL component is (a) the upstream archives at the exact versions/URLs in \`manifest.csv\`, byte-verifiable against their recorded hashes, plus (b) this repository at tag \`${{ github.ref_name }}\`, which carries the full Buildroot configuration and all applied patches and rebuilds the identical images with \`make\`. **Written offer:** for at least three years from this release, we will additionally provide a complete machine-readable copy of the corresponding source for any component on request — open an issue at https://github.com/${{ github.repository }}. **azcopy (optional, ARMv7):** \`azcopy--armv7.xz\` is Microsoft's Azure Storage CLI, for backing the card's \`saves\`/\`savestates\`/\`screenshots\`/\`config\` up to Azure Storage from the board itself. It is a STANDALONE DOWNLOAD and is deliberately **not** in \`linux.img\`: at 39 MiB installed it would be the second-largest thing in the image after Samba, for a tool most owners will never run — and almost all of that size is Google Cloud Storage support that a MiSTer never executes (an empty Go binary is 1.2 MB; +Azure SDK 5.5 MB; +GCS 27.6 MB). Statically linked on purpose, so it keeps working if you roll back to an older image or to stock. To use it: \`xz -d\` it onto \`/media/fat\`, \`chmod +x\`, and set \`AZCOPY_JOB_PLAN_LOCATION\`/\`AZCOPY_LOG_LOCATION\` under \`/media/fat\` plus \`AZCOPY_BUFFER_GB=0.125\` — that last one matters, because AzCopy otherwise sizes its buffer cache at 1 GiB on a board with 511 MiB of RAM. Microsoft does not build or test AzCopy for 32-bit ARM; this build carries two local patches to make it compile and to stop every \`azcopy login\` dying on SIGILL. See \`docs/azcopy.md\` for the full write-up and the on-hardware test record. - **PREEMPT_RT beta (Linux 7.2):** \`zImage_dtb-rt\` is a separately compiled real-time kernel (docs/rt-beta-kernel.md, ADR 0021 as amended 2026-07-18) — never referenced by db.json, so the Downloader will not offer it. The ONE \`linux.img\` above already contains BOTH kernels' module trees, so no separate rootfs exists and — once the device is running THIS release's \`linux.img\` (a linux.img from before this release carries only 6.18 modules, and the RT kernel would boot with none of its drivers) — no extra flash is needed: opt in by copying \`zImage_dtb-rt\` to \`/media/fat/linux/\` and adding \`bootimage=/linux/zImage_dtb-rt\` to u-boot.txt (remove the line to roll back). \`linux-rt.config\` is its kernel config; \`legal-info-rt.tar.gz\` carries the RT kernel's applied patches + SBOM (license texts and manifest.csv with the pinned upstream source URL+hash) — the same patches-only form as the main \`legal-info.tar.gz\`, covered by the corresponding-source note above. It is a MANUAL download only: the sdcard installer image deliberately does NOT carry it (ADR 0021 item 4, reversed 2026-07-27 — an unvalidated real-time kernel does not belong on every user's card). Status: build-verified only. Earlier pins booted and ran MiSTer on one DE10-Nano — 7.2-rc4 on 2026-07-20 and 7.2-rc7 on 2026-08-14 — but boot is a per-version claim, so treat the kernel in THIS release as unvalidated on hardware unless a maintainer says otherwise. (This paragraph is hand-maintained prose and its version can go stale ahead of the pin; \`linux-rt.config\` in this same release is authoritative for what was actually built.) The pin tracks the 7.2.y line as of 2026-08-17 — it no longer follows mainline \`-rc\`, so this caveat is re-opened by a point release rather than weekly. No latency measurement has been taken on any version." + **PREEMPT_RT beta (Linux 7.2):** \`zImage_dtb-rt\` is a separately compiled real-time kernel (docs/rt-beta-kernel.md, ADR 0021 as amended 2026-07-18) — never referenced by db.json, so the Downloader will not offer it. The ONE \`linux.img\` above already contains BOTH kernels' module trees, so no separate rootfs exists and — once the device is running THIS release's \`linux.img\` (a linux.img from before this release carries only 6.18 modules, and the RT kernel would boot with none of its drivers) — no extra flash is needed: opt in by copying \`zImage_dtb-rt\` to \`/media/fat/linux/\` and adding \`bootimage=/linux/zImage_dtb-rt\` to u-boot.txt (remove the line to roll back). \`linux-rt.config\` is its kernel config; its applied patches, licence texts and manifest row are inside \`legal-info.tar.gz\` (package \`linux-rt\`), covered by the corresponding-source note above. It is a MANUAL download only: the sdcard installer image deliberately does NOT carry it (ADR 0021 item 4, reversed 2026-07-27 — an unvalidated real-time kernel does not belong on every user's card). Status: build-verified only. Earlier pins booted and ran MiSTer on one DE10-Nano — 7.2-rc4 on 2026-07-20 and 7.2-rc7 on 2026-08-14 — but boot is a per-version claim, so treat the kernel in THIS release as unvalidated on hardware unless a maintainer says otherwise. (This paragraph is hand-maintained prose and its version can go stale ahead of the pin; \`linux-rt.config\` in this same release is authoritative for what was actually built.) The pin tracks the 7.2.y line as of 2026-08-17 — it no longer follows mainline \`-rc\`, so this caveat is re-opened by a point release rather than weekly. No latency measurement has been taken on any version." # Upsert, not create-only: a tagged push already created the draft, # so an opt-in full-sdcard dispatch (same tag) must ADD assets # rather than fail on already-exists. See @@ -915,11 +353,7 @@ jobs: if gh release view "$TAG" >/dev/null 2>&1; then gh release upload "$TAG" --clobber "${assets[@]}" else - gh release create "$TAG" \ - --draft \ - --title "$TAG" \ - --notes "$notes" \ - "${assets[@]}" + gh release create "$TAG" --draft --title "$TAG" --notes "$notes" "${assets[@]}" fi - name: Publish summary (job summary) @@ -930,25 +364,11 @@ jobs: { echo "## 📦 Draft release created" echo "" - echo "Draft GitHub Release **${TAG}** created (internal version \`${RELEASE_DATE}\`); build provenance attested for \`linux.img\`, \`zImage_dtb\` and \`zImage_dtb-rt\`. The three \`*-rt\` assets are the PREEMPT_RT beta kernel (ADR 0021 as amended — its MODULES ride inside the one \`linux.img\`) — separate downloads, never in the 7z, never in db.json." + echo "Draft GitHub Release **${TAG}** (internal version \`${RELEASE_DATE}\`); provenance attested for \`linux.img\`, \`zImage_dtb\` and \`zImage_dtb-rt\`." echo "" - echo "> ⚠️ **This is a draft.** It is not public, and db.json is **not** published while it stays a draft." - echo "> Clicking **Publish release** — whether as a full release *or* a pre-release — fires \`publish-db.yml\`, which regenerates and publishes db.json to opted-in devices. **The pre-release flag does not prevent that** (the guard there checks draft, not pre-release). For a smoke test, leave it a draft and delete it when done." + echo "> ⚠️ **This is a draft.** Publishing it — as a release *or* a pre-release — fires \`publish-db.yml\`, which publishes db.json to opted-in devices. For a smoke test, leave it a draft and delete it when done." } >> "$GITHUB_STEP_SUMMARY" - # ============================================================================ - # dependency-graph — re-publishes the release's SBOM through GitHub's - # dependency submission API so it lands in /network/dependencies (and, for - # anything the advisory database can match, Dependabot). The SBOM itself is - # not regenerated here: the input is the manifest.csv inside the - # legal-info*.tar.gz assets the release actually shipped, so the graph and - # the tarball cannot disagree. - # - # RELEASE ONLY, deliberately — build.yml never submits. A dependency graph - # is a claim about what is published, and build.yml's manifest-only SBOM - # describes an image that is distributed to nobody. See - # docs/ci.md#dependency-graph-submission. - # ============================================================================ dependency-graph: name: Publish SBOM to the dependency graph # publish, not build: nothing should appear in the graph for a release @@ -985,65 +405,20 @@ jobs: name: release-dist-${{ github.sha }} path: dist - # ci_lib_package_legal_info archives with `-C legal-info`, - # so every bundle carries its manifest at exactly legal-info/manifest.csv. - # Each is unpacked under the Buildroot output dir it came from - # (legal-info.tar.gz -> output/, legal-info-rt.tar.gz -> output-rt/) and - # named that way in the snapshot, which is both stable across releases - # and self-describing in the graph UI. - # - # The variant glob is safe to trust here in a way it would not be in - # `publish`: `needs: publish` means that job's by-name check for - # legal-info-.tar.gz has already passed for EVERY variant in - # SHA256SUMS. Only the main bundle is re-asserted by name below. - - name: Extract each shipped legal-info bundle's manifest.csv + # One bundle since ADR 0030: legal-info.tar.gz covers the image, the RT + # kernel and the stage-1 packages (all packages of the one build). The + # snapshot names its manifest output/legal-info/manifest.csv, stable across + # releases and self-describing in the graph UI. + - name: Extract the SBOM manifest from legal-info.tar.gz id: manifests run: | set -euo pipefail - if [ ! -f dist/legal-info.tar.gz ]; then - echo "::error::dist/legal-info.tar.gz is missing from the release-dist bundle -- the main image's SBOM is what this job exists to publish; refusing to submit a dependency snapshot without it" >&2 - exit 1 - fi - shopt -s nullglob - : > "$RUNNER_TEMP/manifest-args.txt" - for tgz in dist/legal-info.tar.gz dist/legal-info-*.tar.gz; do - base=$(basename "$tgz" .tar.gz) - case "$base" in - legal-info) outdir=output ;; - legal-info-*) outdir="output-${base#legal-info-}" ;; - *) - echo "::error::unexpected legal-info bundle name '$tgz'" >&2 - exit 1 - ;; - esac - dest="$RUNNER_TEMP/sbom/$outdir" - mkdir -p "$dest" - # One member, named explicitly: a bundle that somehow lost its - # manifest must fail here, not silently contribute nothing. - if ! tar -xzf "$tgz" -C "$dest" legal-info/manifest.csv; then - echo "::error::$tgz does not contain legal-info/manifest.csv -- ci_lib_package_legal_info's archive layout changed, or the bundle is truncated" >&2 - exit 1 - fi - printf -- '--manifest\n%s\n' \ - "${outdir}/legal-info/manifest.csv=${dest}/legal-info/manifest.csv" \ - >> "$RUNNER_TEMP/manifest-args.txt" - echo "staged ${tgz} -> ${outdir}/legal-info/manifest.csv ($(wc -l < "${dest}/legal-info/manifest.csv") lines)" - done + [ -f dist/legal-info.tar.gz ] || { echo "::error::dist/legal-info.tar.gz is missing from the release-dist bundle" >&2; exit 1; } + mkdir -p "$RUNNER_TEMP/sbom/output" + tar -xzf dist/legal-info.tar.gz -C "$RUNNER_TEMP/sbom/output" legal-info/manifest.csv + printf -- '--manifest\n%s\n' "output/legal-info/manifest.csv=$RUNNER_TEMP/sbom/output/legal-info/manifest.csv" > "$RUNNER_TEMP/manifest-args.txt" + echo "manifest: $(wc -l < "$RUNNER_TEMP/sbom/output/legal-info/manifest.csv") lines (covers the image, the RT kernel and the stage-1 packages)" - # THE load-bearing step. GitHub only updates a repository's dependency - # results from a snapshot whose `ref` is the DEFAULT BRANCH: a - # refs/tags/... ref is accepted with a 201 and then quietly ignored - # ("The snapshot was accepted, but it is not for the default branch"), - # which is exactly the shape of failure this whole job was added to fix. - # Since a release tag is cut from master, the tagged commit IS on the - # default branch and submitting under refs/heads/ is accurate, - # not a fiction -- but that has to be CHECKED, not assumed, so a tag cut - # from an unmerged branch never claims to describe master. - # - # compare/...: `identical` = the tag is the branch tip, - # `behind` = the tagged commit is an ancestor of it. `ahead`/`diverged` - # mean the commit is not on the default branch at all. - # See docs/ci.md#dependency-graph-default-branch. - name: Resolve the ref to submit the snapshot under id: ref env: diff --git a/.github/workflows/renovate-hash-sync.yml b/.github/workflows/renovate-hash-sync.yml index 859704e6..da96fe0e 100644 --- a/.github/workflows/renovate-hash-sync.yml +++ b/.github/workflows/renovate-hash-sync.yml @@ -115,7 +115,7 @@ on: # The DE10 kernel pin (BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE) lives in # the board fragment since the 2026-09 fragment split; the kernel-only # stack shares that same file, so there is no second copy to list. - - "configs/fragments/de10nano.fragment" + - "configs/mister_de10nano_defconfig" # The RT/beta kernel pin. ADDED 2026-08-17: this file used to be # deliberately ABSENT here, because while that pin tracked mainline -rc # its hash could not be auto-refreshed at all (no signed manifest exists @@ -520,19 +520,9 @@ jobs: - name: Rebuild and refresh the azcopy vendored-tarball hash run: .hash-sync-tools/scripts/hash-sync-azcopy.sh "$GITHUB_WORKSPACE" - # --- 8. Golden config hashes (configs/fragments/golden.sha256) --------- - # NEW 2026-09-02, with the fragment split. A Buildroot bump changes - # Kconfig defaults and so moves every stack's golden resolved-config - # hash; lint-config only WARNS on a version with no golden line, so the - # bump PR still builds, and this case records the new lines in the same - # PR. Runs the TARGET branch's scripts/check-config-fragments.sh - # --update-golden through the target branch's Makefile (the golden - # format is that tree's), after case 6 has written the tarball hash the - # unpack verifies against. Never rewrites lines that already exist for - # the pinned version -- drift is lint-config's to fail, not this case's - # to bless. See the script's header and docs/renovate.md. - - name: Record golden config hashes for a bumped Buildroot - run: .hash-sync-tools/scripts/hash-sync-golden.sh "$GITHUB_WORKSPACE" + # (Case 8, golden config hashes, retired 2026-09-11 with the fragment + # stacks -- ADR 0030: the committed defconfigs are checked by + # scripts/check-defconfigs.sh, which needs no per-version record.) # Gate the push: ANY pin recorded "failed" (from any of the steps # above) suppresses the commit/push below. MUST run and be evaluated @@ -558,13 +548,13 @@ jobs: env.RT_PATCH_HASH_CHANGED == '1' || env.LZMA_SDK_HASH_CHANGED == '1' || env.SEVENZIP_HASH_CHANGED == '1' || env.PAYLOAD_HASH_CHANGED == '1' || env.BUILDROOT_HASH_CHANGED == '1' || - env.AZCOPY_HASH_CHANGED == '1' || env.GOLDEN_CHANGED == '1') && + env.AZCOPY_HASH_CHANGED == '1') && env.HASH_SYNC_FAILED == '0' run: | set -euo pipefail git config user.name "renovate-hash-sync[bot]" git config user.email "renovate-hash-sync@users.noreply.github.com" - git add Makefile package/*/*.hash board/mister/de10nano/patches/linux/linux.hash scripts/fetch-sdcard-payload.sh configs/fragments/golden.sha256 + git add Makefile package/*/*.hash board/mister/de10nano/patches/linux/linux.hash scripts/fetch-sdcard-payload.sh git commit -F - <<'COMMITMSG' renovate-hash-sync: refresh companion hash(es) for this PR @@ -600,12 +590,6 @@ jobs: the only way this value can be derived, since no URL serves that file (see package/azcopy/azcopy.hash's header). LICENSE and NOTICE.txt were re-hashed from the same tarball - - golden config hashes (configs/fragments/golden.sha256): on a - Buildroot bump only, the target branch's own - scripts/check-config-fragments.sh --update-golden was run - against the freshly unpacked (hash-verified) Buildroot tree and - the new version's lines recorded -- never a rewrite of lines - that already existed (docs/buildroot-config.md section 11) COMMITMSG # Shell variable, NOT a workflow-expression interpolation -- # TARGET_BRANCH is attacker-controlled text on a PR (command-injection @@ -651,9 +635,8 @@ jobs: # roster, which must never touch a golang-package) and so has to be # named here separately, exactly like the four pins before it. # - # `golden` joined on 2026-09-02 with case 8 (the resolved-config - # golden hashes a Buildroot bump moves; scripts/hash-sync-golden.sh). - all_pins="$HASH_SYNC_PACKAGES kernel kernel-rt lzma-sdk 7zip buildroot azcopy golden PINNED_UPDATE_ALL PINNED_WIFI_SH PINNED_CORES" + # (`golden`, case 8, was retired 2026-09-11 with the fragment stacks.) + all_pins="$HASH_SYNC_PACKAGES kernel kernel-rt lzma-sdk 7zip buildroot azcopy PINNED_UPDATE_ALL PINNED_WIFI_SH PINNED_CORES" complete_file=$(mktemp) cp "$outcomes_file" "$complete_file" diff --git a/.gitignore b/.gitignore index 50350504..314dad30 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ work/ output*/ dl/ dist/ +release-work/ *.img *.7z venv/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cdf763e1..93e0efb2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -98,7 +98,7 @@ All external sources (kernel, Buildroot, packages, firmware) must be: KERNEL_VERSION = 6.18.y # Good: pinned tag (version illustrative -- the live kernel pin is -# BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE in configs/fragments/de10nano.fragment, +# BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE in configs/mister_de10nano_defconfig, # which is the one place it is written down) KERNEL_VERSION = 6.18.38 diff --git a/Config.in b/Config.in index 520b4af7..311a1935 100644 --- a/Config.in +++ b/Config.in @@ -1,5 +1,17 @@ menu "MiSTer external options" +menu "MiSTer profiles (ADR 0030 -- one symbol selects a documented package set)" + # THE ONE DEPARTURE FROM A PLAIN BUILDROOT DEFCONFIG. In a plain project + # every package is a line in configs/_defconfig. Here the shared + # sets are Kconfig profiles that `select` their members, so two boards + # share a userspace by selecting one symbol and cannot drift apart on + # it. "Why is package X in my image?" -> the profile's Config.in, whose + # section headers mirror docs/buildroot-config.md §5. + source "$BR2_EXTERNAL_MISTER_PATH/package/mister-firmware/Config.in" + source "$BR2_EXTERNAL_MISTER_PATH/package/mister-drivers/Config.in" + source "$BR2_EXTERNAL_MISTER_PATH/package/mister-userspace/Config.in" +endmenu + menu "USB WiFi drivers (out-of-tree)" # MAINLINE-FIRST policy (ADR 0016). The rule is "use the in-kernel driver # for every chip the kernel can drive; keep an out-of-tree driver ONLY @@ -169,4 +181,26 @@ menu "Off-device backup" source "$BR2_EXTERNAL_MISTER_PATH/package/azcopy/Config.in" endmenu +menu "Kernel variants (ADR 0021)" + # A second kernel built beside the main one in this same tree (ADR 0030 + # Phase C): PREEMPT_RT on the 7.2.y line -> images/zImage_dtb-rt, with + # its module tree in the ONE rootfs. Same shape as Buildroot's own + # barebox-aux. Requires the stage-1 extension below (it embeds the same + # cpio). + source "$BR2_EXTERNAL_MISTER_PATH/package/linux-rt/Config.in" +endmenu + +menu "Stage-1 initramfs (ADR 0002)" + # The cpio the kernel embeds, built as a package of this configuration + # (ADR 0030): a static BusyBox and a static fsck.exfat from the main + # toolchain, plus board/mister/common/initramfs-overlay/init. The + # kernel side -- CONFIG_INITRAMFS_SOURCE pointing at the cpio -- is the + # linux extension BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS (Kernel -> + # Linux Kernel Extensions), which selects the package. The two + # sub-packages have no prompt of their own. + source "$BR2_EXTERNAL_MISTER_PATH/package/mister-initramfs/Config.in" + source "$BR2_EXTERNAL_MISTER_PATH/package/mister-initramfs-busybox/Config.in" + source "$BR2_EXTERNAL_MISTER_PATH/package/mister-initramfs-exfatprogs/Config.in" +endmenu + endmenu diff --git a/Makefile b/Makefile index 8ed2124b..67e8a3fe 100644 --- a/Makefile +++ b/Makefile @@ -1,1283 +1,95 @@ -################################################################################ -# -# Top-level wrapper for the MISTER BR2_EXTERNAL tree (P1.1, PLAN.md §6). -# -# Buildroot itself is NEVER vendored into this repository (G4/G6, TASKS.md -# standing rule 1 — "No binaries in git. Ever."). This Makefile: -# -# 1. Downloads the pinned upstream Buildroot release tarball into an -# untracked cache directory (dl/). -# 2. Verifies its SHA-256 against the pinned hash below and aborts loudly -# on any mismatch — it will NOT unpack an unverified tarball. -# 3. Unpacks it to work/buildroot/ (idempotent: if a Buildroot tree of the -# pinned version is already present there, the download/verify/unpack -# step is skipped entirely and no network access is made). -# 4. Generates each Buildroot configuration by layering the fragments under -# configs/fragments/ (configs/fragments/stacks.mk says which) with -# Buildroot's own merge_config.sh + olddefconfig -- there is no monolithic -# defconfig any more (docs/buildroot-config.md §1) -- and forwards every -# other target (menuconfig, olddefconfig, savedefconfig, ...) into that -# Buildroot tree with BR2_EXTERNAL set to this repo, O= pointed at an -# out-of-tree output directory, and BR2_DL_DIR pointed at the persistent -# download cache. -# -# work/, dl/, and output/ are all gitignored — see .gitignore. -# -# Reference: /mnt/source/sb-enema/Makefile (working 2026.02.3 pinned-tarball -# wrapper this is modeled on). That reference has no hash verification; this -# Makefile adds it, which is the whole point of P1.1. -# -################################################################################ - -# --- Buildroot pin ------------------------------------------------------------ -# P4.6 wires a Renovate custom regex manager over BUILDROOT_VERSION / -# BUILDROOT_SHA256 in this file (PLAN.md §9), the same way sb-enema's -# renovate.json does for BUILDROOT_VERSION — keep this stanza regex-friendly. -# -# WHERE BUILDROOT_SHA256 COMES FROM — read before changing it. -# The hash below is transcribed from Buildroot's GPG-clearsigned release -# manifest for this exact version: -# -# https://buildroot.org/downloads/buildroot-$(BUILDROOT_VERSION).tar.gz.sign -# -# which contains a "SHA256: buildroot-.tar.gz" line signed by -# the Buildroot maintainer. That signed file is the ONLY source of truth for -# this value. -# -# Do NOT produce this hash by downloading the tarball and running sha256sum on -# it. That is circular — it pins whatever bytes you happened to receive, and -# certifies nothing. A bump (manual or Renovate) MUST take the new hash from -# the .sign file for the new version. `make buildroot-showsig` prints it. -# -# Since 2026-08-24 a Renovate bump gets this transcription done FOR it: -# .github/workflows/renovate-hash-sync.yml case 6 -# (scripts/hash-sync-buildroot.sh) fetches the same .sign manifest and -# rewrites the hash below on the PR branch. That script transcribes the -# signed manifest exactly as a human would — it never downloads the tarball, -# so the prohibition above stands untouched. The manual `make -# buildroot-showsig` transcription remains the procedure for a hand bump, and -# the fallback whenever the sync run skipped (the PR then stays red at `make -# buildroot-verify`, which is the safe failure mode). +# MiSTer Buildroot external -- thin wrapper. Everything past `make _defconfig` +# is plain Buildroot: `make`, `make menuconfig`, `make linux-menuconfig`, +# `make legal-info`, `make -rebuild`, ... are forwarded unchanged, with +# BR2_EXTERNAL set to this tree and O= pointing at the output directory. The +# only thing this wrapper adds is that the pinned Buildroot release is fetched +# and hash-verified for you into work/buildroot (Buildroot is never vendored). +# +# make mister_de10nano_defconfig && make # the DE10-Nano image +# make O=output-de25 mister_de25nano_defconfig && make O=output-de25 # the DE25-Nano +# make linux-menuconfig | make linux-rt-menuconfig | make help +# +# ONE DEPARTURE FROM A PLAIN BUILDROOT DEFCONFIG, for newcomers: the shared +# package sets are Kconfig PROFILES (package/mister-userspace, -firmware, +# -drivers) that the defconfig enables with one line each, so two boards +# share a userspace without drifting apart. "Why is package X in my image?" +# -> package/mister-userspace/Config.in. See docs/buildroot-config.md. +# +# Documentation: README.md "Building it yourself"; docs/decisions/0030. + +# --- Buildroot pin ---------------------------------------------------------- +# Renovate bumps BUILDROOT_VERSION; BUILDROOT_SHA256 is transcribed from the +# GPG-clearsigned release manifest (`make buildroot-showsig`) by +# scripts/hash-sync-buildroot.sh -- never from a downloaded tarball. Keep both +# lines exactly this shape: four scripts and renovate.json parse them. BUILDROOT_VERSION ?= 2026.08 BUILDROOT_SHA256 ?= d678e810abf877d04513e03ca2c99f992dd49118b9c2e18d6e25f5f58fa8c5cd -BUILDROOT_URL = https://buildroot.org/downloads/buildroot-$(BUILDROOT_VERSION).tar.gz -BUILDROOT_SIG_URL = $(BUILDROOT_URL).sign ROOT_DIR := $(CURDIR) -WORK_DIR := $(ROOT_DIR)/work -DL_DIR := $(ROOT_DIR)/dl -OUTPUT_DIR := $(ROOT_DIR)/output - -# --- Stage-1 initramfs output (P1.10 / A1) ------------------------------------ -# A SECOND, SEPARATE Buildroot output directory. This is the whole trick of the -# two-stage build (PLAN.md §5, docs/decisions/0002-initramfs.md): stage 1 is a -# different Buildroot *configuration* (static musl BusyBox, cpio) and therefore -# needs a different O=. It must never share $(OUTPUT_DIR) — that would clobber the -# main build's toolchain and target/ with the initramfs's. -# -# It is emphatically NOT BR2_TARGET_ROOTFS_INITRAMFS on the main config: that -# option embeds the whole ~300 MB target rootfs into the kernel (A1). -# -# Since 2026-09-06 stage 1 is a fragment STACK like every other configuration -# here (configs/fragments/stacks.mk: `initramfs-common initramfs-de10nano`), -# not a standalone defconfig -- and it has an aarch64 sibling, -# $(DE25_INITRAMFS_OUTPUT_DIR) below, built from `initramfs-common -# initramfs-de25nano`. The /init, the BusyBox config and the post-build hook -# are shared by both boards under board/mister/common/. -INITRAMFS_OUTPUT_DIR := $(ROOT_DIR)/output-initramfs -INITRAMFS_CPIO := $(INITRAMFS_OUTPUT_DIR)/images/rootfs.cpio -INITRAMFS_INIT := $(ROOT_DIR)/board/mister/common/initramfs-overlay/init - -# --- DE25-Nano stage-1 initramfs (ADR 0029 D11; docs/de25-sdcard.md §2) ----- -# The SAME /init, BusyBox config and hook, built for aarch64 (static musl, the -# DE25's CPU tuning and headers series -- the initramfs-de25nano fragment). -# A sixth Buildroot output dir, for the usual reason: a -# different configuration needs a different O=, and this one's toolchain is a -# different architecture from output-initramfs/'s. -# -# NOT YET EMBEDDED. The shipped DE25 card keeps D11's interim plain-ext4 root -# until a board has booted it, and external.mk's embedding fixup still keys on -# BR2_arm. `make de25-initramfs` builds and verifies the cpio (the same -# applet/binary/parse assertions as the DE10's, run under qemu-aarch64) and -# `scripts/test-initramfs.sh --board de25nano` boots it through all eight -# cases on qemu-system-aarch64 -- so the day the card switches to the -# two-stage layout, the stage-1 half is already proven. See the DE25_OUTPUT_DIR -# header for why `de25` still does not depend on ANY initramfs target. -DE25_INITRAMFS_OUTPUT_DIR := $(ROOT_DIR)/output-initramfs-de25 -DE25_INITRAMFS_CPIO := $(DE25_INITRAMFS_OUTPUT_DIR)/images/rootfs.cpio - -# --- RT / Linux-7.2 "beta" kernel variant (docs/rt-beta-kernel.md) ------------ -# A THIRD Buildroot output dir, same trick as the initramfs stage above: a -# different kernel *configuration* (the mainline 7.2 line + PREEMPT_RT) needs its -# own O=. Deliberately not naming the -rc here: it is only a label at this point -# and configs/mister_rt.fragment is the single place that pins it. -# Since ADR 0021's 2026-07-18 amendment this is a KERNEL-ONLY build, not a -# second full image: the de10nano-kernel fragment stack (common + de10nano + -# kernel-only, configs/fragments/stacks.mk -- the SAME toolchain + kernel -# fragments the shipped image is built from, rootfs-tar only, no packages) -# with configs/mister_rt.fragment layered on at `make rt` time via Buildroot's -# own merge_config.sh. It produces zImage_dtb (ships as zImage_dtb-rt) plus a -# depmod'd module tree, which `rt` copies into $(EXTRA_MODULES_OVERLAY) below -# so the ONE shipped linux.img carries both kernels' modules. -# A future kernel variant `foo` needs only configs/mister_foo.fragment, its own -# foo/foo-clean/... targets mirroring the rt ones (each derives everything from -# the name), and a matrix entry in the CI workflows. -# ⚠ Never yet booted on hardware; expect to iterate. See the doc. -RT_OUTPUT_DIR := $(ROOT_DIR)/output-rt -RT_FRAGMENT := $(ROOT_DIR)/configs/mister_rt.fragment - -# --- Extra-modules overlay: how variant module trees reach linux.img ---------- -# The main defconfig's BR2_ROOTFS_OVERLAY lists this (gitignored, under work/) -# directory SECOND, after the tracked rootfs-overlay. Buildroot rsyncs overlays -# into TARGET_DIR at target-finalize, so whatever module trees are staged here -# (by `make rt` locally, or by CI's build-kernel job artifacts) land in the one -# shipped linux.img next to the main kernel's own tree. Empty directory -> -# byte-identical main image; `all` below guarantees it at least exists, because -# Buildroot fails on a missing overlay path. -# -# That rsync only ever ADDS or overwrites: SYSTEM_RSYNC (work/buildroot/system/ -# system.mk) is `rsync -a --ignore-times` with NO --delete, and output/target/ -# persists across make invocations. So REMOVING a tree from the image takes TWO -# removals -- from this overlay AND from output/target/ -- or the next -# incremental `make all` silently re-ships the copy an earlier run already -# rsynced in. The rt recipe's stale-kver branch and rt-clean both do exactly -# that pair. (CI never hits this: its output/target/ is built from scratch -# every run -- only host caches are restored.) -# -# Each variant records the kver it staged in its own stamp file (a work/ -# SIBLING of the overlay, never inside it — everything inside the overlay ships -# in the image). The stamp is what lets a kernel-version bump remove its OWN -# stale tree without touching a future sibling variant's, and what rt-clean -# uses to remove exactly rt's contribution. -EXTRA_MODULES_OVERLAY := $(WORK_DIR)/extra-modules-overlay -RT_OVERLAY_STAMP := $(WORK_DIR)/extra-modules-overlay.rt-kver - -# --- SD-card installer (P5.3, docs/decisions/0020-sdcard-exfat-reformat-installer.md) --- -# A FOURTH Buildroot output dir, same trick as initramfs/RT above: the installer -# that ships on sdcard.img's FAT32 partition is yet another Buildroot -# *configuration* (static-musl BusyBox cpio, plus target packages — exfatprogs, -# util-linux sfdisk — the initramfs stage doesn't need) and so needs its own O=. -# -# scripts/mk-sdcard.sh builds THIS SAME output dir itself, driving Buildroot -# directly (its own br_make helper, shaped exactly like BR_MAKE_INSTALLER -# below) as step 1/7 of assembling sdcard.img — it does not invoke the -# `installer` target. These paths are defined here anyway so that target (a -# standalone escape hatch for iterating on the installer config/overlay, -# mirroring `initramfs`/`rt`) and `clean`/`distclean` agree with that script on -# where things live. Keep in sync with scripts/mk-sdcard.sh's own -# REPO_ROOT-relative constants if either changes. -INSTALLER_OUTPUT_DIR := $(ROOT_DIR)/output-installer -INSTALLER_CPIO := $(INSTALLER_OUTPUT_DIR)/images/rootfs.cpio -INSTALLER_DEFCONFIG := $(ROOT_DIR)/configs/mister_installer_defconfig - -# scripts/mk-sdcard.sh's OWN scratch dirs — mk-sdcard.sh drives its Buildroot -# invocations itself (its own br_make helper), not any target below — but these are -# still ours to clean up on clean/distclean. NONE of them is a Buildroot O= dir, so -# all three are plain rm -rf'd (never Buildroot-cleaned): -# output-installer-kernel/ - scratch HOLDING dir for mk-sdcard.sh step 2: the -# captured installer zImage_dtb plus the pre-relink -# snapshots of our real zImage_dtb / gzipped linux.img. -# Step 2 now relinks the kernel IN output/ (reusing the -# completed main build, then restoring it) rather than -# building a fourth full Buildroot tree here — a fresh -# from-scratch O= would rebuild the whole toolchain and -# blow the CI job's wall-clock cap. See mk-sdcard.sh's -# build_installer_kernel. -# output-sdcard-stage/ - fetched/staged payload (mk-sdcard.sh's STAGE_DIR). -# output-sdcard-build/ - genimage's inputs/tmp/out working dirs. -INSTALLER_KERNEL_OUTPUT_DIR := $(ROOT_DIR)/output-installer-kernel -SDCARD_STAGE_DIR := $(ROOT_DIR)/output-sdcard-stage -SDCARD_BUILD_DIR := $(ROOT_DIR)/output-sdcard-build -# scripts/check-config-fragments.sh's scratch O= dirs (one per fragment -# stack, config-only, never built). Not a Buildroot-cleanable tree either: -# plain rm -rf'd below, like the three above. -CONFIG_CHECK_DIR := $(ROOT_DIR)/output-config-check - -# --- DE25-Nano developer OS (D2.1, docs/de25-nano-tasks.md) ------------------- -# A FIFTH Buildroot output dir, and by far the biggest departure of the five: -# every directory above builds for the DE10-Nano's armv7 Cyclone V. This one -# builds for a DIFFERENT BOARD — the Terasic DE25-Nano, an Intel/Altera -# Agilex 5 whose HPS is aarch64 (2x Cortex-A76 + 2x Cortex-A55). Different -# architecture, different toolchain, different kernel line (mainline 7.2.3), -# different rootfs. It shares with the main build exactly two things: the -# pinned Buildroot tree and the dl/ download cache. -# -# It follows the same trick as initramfs/rt/installer for the same reason: a -# different Buildroot *configuration* needs a different O=. Sharing -# $(OUTPUT_DIR) would clobber the DE10's armv7 toolchain with an aarch64 one — -# and Buildroot cross-toolchains bake their absolute O= path in, so the two can -# never share a host tree even if you wanted them to (ADR 0021 §3 makes the -# same point about output-rt/). -# -# Its configuration is the de25nano fragment stack (common + de25nano, -# configs/fragments/stacks.mk): it shares exactly the arch-neutral `common` -# layer with the DE10 stacks and nothing else -- no DE10 toolchain, kernel or -# package fragment is in its stack (docs/buildroot-config.md §6, §10). -# -# ALSO UNLIKE `rt` and `all`: `de25` does NOT depend on `initramfs`. That cpio -# is an armv7 BusyBox (the initramfs-de10nano stack), and it exists because the -# DE10's real root is a loop-mounted ext4 image on a FAT partition that U-Boot -# will not load an initrd for (A3, docs/boot-chain.md). Embedding armv7 -# userspace in an aarch64 kernel would produce a kernel that panics in a novel -# and confusing way. Nor does `de25` depend on `de25-initramfs` -- YET: the -# aarch64 stage 1 exists and is QEMU-proven (see DE25_INITRAMFS_OUTPUT_DIR -# above), but the shipped card keeps ADR 0029 D11's interim plain-ext4 root -# until a board has booted it, so the DE25 kernel embeds nothing and -# external.mk's LINUX_KCONFIG_FIXUP_CMDS hook is guarded off for this build; -# see the guard's comment there for the switch. -# -# Scope reminder, because the target name invites the wrong assumption: this is -# a BARE DEVELOPER OS. No MiSTer binaries, no DE10 packages. See ADR 0027 -# Decision 6 and the defconfig's header. -DE25_OUTPUT_DIR := $(ROOT_DIR)/output-de25 - -BR_TARBALL := $(DL_DIR)/buildroot-$(BUILDROOT_VERSION).tar.gz -BR_DIR := $(WORK_DIR)/buildroot -# Two properties this path must have, both learned the hard way: -# -# 1. INSIDE $(BR_DIR), not a $(WORK_DIR) sibling. Make only reruns a file -# target's recipe when the target is missing or stale, so a stamp that -# outlives $(BR_DIR) (someone rm -rf's or mv's the tree away) would keep -# asserting "already present" forever. Living inside ties the stamp's -# lifetime to the tree it attests to. -# -# 2. VERSION-QUALIFIED. The $(BR_STAMP) rule has no prerequisites, so its -# recipe runs exactly once per distinct stamp filename, ever. With a -# constant name, bumping BUILDROOT_VERSION left the old stamp in place and -# Make said "Nothing to be done" — silently building against the OLD -# Buildroot tree and never even checking the new hash. That is precisely -# what P4.6's Renovate bump does, so it would have shipped broken. -# Putting the version in the filename makes a bump a different target, -# which is missing, which forces the re-fetch. +O ?= $(ROOT_DIR)/output +export BR2_DL_DIR ?= $(ROOT_DIR)/dl +BR_DIR := $(ROOT_DIR)/work/buildroot BR_STAMP := $(BR_DIR)/.mister-br2-stamp-$(BUILDROOT_VERSION) +HOSTSHIM := $(ROOT_DIR)/work/.hostshim +BR_MAKE = PATH="$(HOSTSHIM):$$PATH" $(MAKE) -C $(BR_DIR) O=$(O) BR2_EXTERNAL=$(ROOT_DIR) -# --- Host `install` must be GNU install --------------------------------------- -# Buildroot REFUSES to build if /usr/bin/install is uutils coreutils 0.8.0 — -# see work/buildroot/support/dependencies/dependencies.sh:193-200, which pins -# that exact version and links the upstream bug: -# https://github.com/uutils/coreutils/issues/12166 -# Debian/Ubuntu's `coreutils-from-uutils` package installs exactly that as the -# default `install`, and ships GNU's as `gnuinstall`. -# -# Buildroot's own advice is `update-alternatives --install ... gnuinstall 100`, -# which needs root and mutates the developer's system. We do NOT do that. We -# instead build a tiny shim directory containing a single `install` symlink to -# whatever GNU install we can find, and prepend it to PATH for Buildroot only. -# That is self-contained, needs no root, is identical for every developer and -# for CI, and touches nothing outside this repo. It is a no-op on a host whose -# `install` is already GNU. -# -# [P1.10] The shim lives under work/, NOT under $(OUTPUT_DIR). It is a property of -# the *host*, not of any one Buildroot output, and since P1.10 there are two output -# directories that both need it. Keeping it in output/ would mean rebuilding it per -# output dir and losing it to a `make clean` of the main build. -HOSTSHIM_DIR := $(WORK_DIR)/.hostshim -GNU_INSTALL := $(shell if install --version 2>/dev/null | grep -q 'GNU coreutils'; then \ - command -v install; \ - else \ - command -v gnuinstall 2>/dev/null; \ - fi) - -.PHONY: hostshim -hostshim: - @if install --version 2>/dev/null | grep -q 'GNU coreutils'; then \ - exit 0; \ - fi; \ - if [ -z "$(GNU_INSTALL)" ]; then \ - echo "FATAL: your 'install' is not GNU coreutils:" >&2; \ - install --version 2>&1 | head -1 | sed 's/^/ /' >&2; \ - echo "" >&2; \ - echo "Buildroot refuses to build with it (dependencies.sh:193; upstream bug" >&2; \ - echo "https://github.com/uutils/coreutils/issues/12166), and no GNU 'install'" >&2; \ - echo "was found to substitute. Install GNU coreutils, e.g.:" >&2; \ - echo " sudo apt-get install gnu-coreutils # provides /usr/bin/gnuinstall" >&2; \ - exit 1; \ - fi; \ - mkdir -p $(HOSTSHIM_DIR); \ - ln -sf $(GNU_INSTALL) $(HOSTSHIM_DIR)/install; \ - echo "==> host 'install' is not GNU; shimming $(GNU_INSTALL) into PATH for Buildroot" - -# Buildroot invocation shared by every forwarded target. BR2_EXTERNAL is passed -# explicitly here rather than exported: a command-line assignment overrides the -# environment anyway, so an export would just be a redundant second source of -# truth that can drift out of sync with this one. -# -# $(HOSTSHIM_DIR) goes FIRST in PATH so the GNU `install` shim (see above) wins -# over a uutils one. On a host with GNU install the directory is never created -# and this prefix is inert. -BR_MAKE = PATH="$(HOSTSHIM_DIR):$$PATH" \ - $(MAKE) -C $(BR_DIR) O=$(OUTPUT_DIR) BR2_EXTERNAL=$(ROOT_DIR) BR2_DL_DIR=$(DL_DIR) - -# The same, aimed at the stage-1 output directory. Same Buildroot tree, same -# BR2_EXTERNAL, same download cache — only O= and the fragment stack differ. -BR_MAKE_INITRAMFS = PATH="$(HOSTSHIM_DIR):$$PATH" \ - $(MAKE) -C $(BR_DIR) O=$(INITRAMFS_OUTPUT_DIR) BR2_EXTERNAL=$(ROOT_DIR) BR2_DL_DIR=$(DL_DIR) - -# The same, aimed at the DE25's stage-1 output directory. -BR_MAKE_DE25_INITRAMFS = PATH="$(HOSTSHIM_DIR):$$PATH" \ - $(MAKE) -C $(BR_DIR) O=$(DE25_INITRAMFS_OUTPUT_DIR) BR2_EXTERNAL=$(ROOT_DIR) BR2_DL_DIR=$(DL_DIR) - -# The same, aimed at the RT/beta output directory (docs/rt-beta-kernel.md). -BR_MAKE_RT = PATH="$(HOSTSHIM_DIR):$$PATH" \ - $(MAKE) -C $(BR_DIR) O=$(RT_OUTPUT_DIR) BR2_EXTERNAL=$(ROOT_DIR) BR2_DL_DIR=$(DL_DIR) - -# The same, aimed at the SD-card installer output directory. Only used by the -# standalone `installer` target below — scripts/mk-sdcard.sh builds -# $(INSTALLER_OUTPUT_DIR) itself with its own equivalent invocation. -BR_MAKE_INSTALLER = PATH="$(HOSTSHIM_DIR):$$PATH" \ - $(MAKE) -C $(BR_DIR) O=$(INSTALLER_OUTPUT_DIR) BR2_EXTERNAL=$(ROOT_DIR) BR2_DL_DIR=$(DL_DIR) - -# The same, aimed at the DE25-Nano output directory (docs/de25-nano-tasks.md -# D2.1). Byte-for-byte the same shape as the four above — same Buildroot tree, -# same BR2_EXTERNAL, same dl/ cache; only O= and the fragment stack differ. The -# aarch64-ness lives entirely in configs/fragments/de25nano.fragment, not here. -BR_MAKE_DE25 = PATH="$(HOSTSHIM_DIR):$$PATH" \ - $(MAKE) -C $(BR_DIR) O=$(DE25_OUTPUT_DIR) BR2_EXTERNAL=$(ROOT_DIR) BR2_DL_DIR=$(DL_DIR) - -# --- Config fragments (docs/buildroot-config.md §1) --------------------------- -# There is no monolithic defconfig. Every Buildroot configuration in this tree -# is a STACK of fragments under configs/fragments/, listed in merge order by -# configs/fragments/stacks.mk (the single source of truth -- the check scripts -# parse that same file). Generation is exactly the idiom `rt` has always used: -# Buildroot's own support/kconfig/merge_config.sh -m concatenates the fragments -# into /.config (warning on any symbol a later fragment redefines -- there -# must be none within a stack; scripts/check-config-fragments.sh enforces that -# in CI), then `olddefconfig` resolves every unlisted symbol to its Kconfig -# default. That resolves to the byte-identical .config the old -# `make mister__defconfig` produced (proved at the split: only -# BR2_DEFCONFIG, the savedefconfig OUTPUT path, differs). -# -# Consequence worth knowing: `make savedefconfig` now writes output/defconfig -# (Buildroot's default when BR2_DEFCONFIG names no file) instead of clobbering a -# tracked file. Fold a menuconfig experiment back by hand into the right -# fragment -- savedefconfig output is unordered and comment-free, which is why -# the old monolith kept losing its comments. -FRAGMENT_DIR := $(ROOT_DIR)/configs/fragments -include $(FRAGMENT_DIR)/stacks.mk -# $(call stack_files,) -> absolute fragment paths, in merge order. -stack_files = $(addprefix $(FRAGMENT_DIR)/,$(addsuffix .fragment,$(1))) -DE10NANO_STACK := $(call stack_files,$(DE10NANO_FRAGMENTS)) -DE10NANO_KERNEL_STACK := $(call stack_files,$(DE10NANO_KERNEL_FRAGMENTS)) -DE25NANO_STACK := $(call stack_files,$(DE25NANO_FRAGMENTS)) -INITRAMFS_DE10NANO_STACK := $(call stack_files,$(INITRAMFS_DE10NANO_FRAGMENTS)) -INITRAMFS_DE25NANO_STACK := $(call stack_files,$(INITRAMFS_DE25NANO_FRAGMENTS)) - -# $(call merge_fragments,,) -- step 1 of 2; the -# caller follows it with the matching `$(BR_MAKE_*) olddefconfig`. The first -# fragment is merge_config.sh's base file, the rest are merged onto it. -define merge_fragments - @mkdir -p $(1) - cd $(BR_DIR) && KCONFIG_CONFIG=$(1)/.config \ - ./support/kconfig/merge_config.sh -m -O $(1) $(2) -endef - -# NOTE: there is no BR_MAKE_INSTALLER_KERNEL. mk-sdcard.sh's step 2 relink no longer -# builds a fourth Buildroot tree in output-installer-kernel/ — it relinks the kernel -# IN output/ (reusing the completed main build) and restores it. output-installer- -# kernel/ is now just a scratch holding dir, plain rm -rf'd by `clean`/`distclean`. - -# Bare `make` must NOT be `all`. The P1.1 defconfig deliberately sets no arch or -# toolchain, so Buildroot would fall back to its own defaults (BR2_i386 + -# internal toolchain) and a reflexive `make` would spend an hour compiling an -# x86 toolchain and rootfs that nothing in this project wants. P1.2 gives the -# defconfig real content; until then, and arguably after, `help` is the right -# thing to get for free. -.DEFAULT_GOAL := help - -.PHONY: all help buildroot-fetch buildroot-verify buildroot-unpack buildroot-showsig require-tools -.PHONY: clean distclean -.PHONY: initramfs initramfs-clean initramfs-menuconfig initramfs-busybox-menuconfig check-initramfs -.PHONY: initramfs-defconfig de25-initramfs de25-initramfs-clean de25-initramfs-defconfig -.PHONY: de25-initramfs-menuconfig de25-initramfs-busybox-menuconfig de25-initramfs-verify -.PHONY: rt rt-clean rt-menuconfig rt-external-deps rt-legal-info -.PHONY: de25 de25-clean de25-menuconfig de25-linux-menuconfig -.PHONY: installer installer-clean installer-menuconfig installer-busybox-menuconfig -.PHONY: sdcard -.PHONY: zimage-dtb - -# GNU Make always checks whether its own makefiles need remaking, using -# whatever rule matches their name -- including the catch-all `%:` pattern -# rule below. Without this explicit no-op rule, EVERY invocation (and, worse, -# every recursive $(MAKE) call inside the $(BR_STAMP) recipe below) would -# match "Makefile" against `%: $(BR_STAMP)` and try to rebuild $(BR_STAMP) -# again before doing anything else -- which recurses without end the moment -# $(BR_STAMP)'s own recipe invokes $(MAKE) (it does, for buildroot-verify). -# An explicit rule always wins over a pattern rule for the same target name, -# so this simple line is what breaks that cycle. -Makefile: ; - -# The included configs/fragments/stacks.mk is a makefile too, so GNU Make -# would try to remake it through the `%:` catch-all as well -- forwarding a -# target named `/.../configs/fragments/stacks.mk` into Buildroot with -# O=$(OUTPUT_DIR). Same explicit-empty-rule fix as `Makefile: ;` above. -$(FRAGMENT_DIR)/stacks.mk: ; - -# [P1.10] Exactly the same landmine, one step further out. The stage-1 stacks' -# fragment files are prerequisites of $(INITRAMFS_OUTPUT_DIR)/.config and -# $(DE25_INITRAMFS_OUTPUT_DIR)/.config below (unlike the image configs, a -# stage-1 .config IS regenerated when a fragment changes -- see -# $(OUTPUT_DIR)/.config's comment for why the two differ). Each is an existing -# file with no rule of its own, so the catch-all `%: $(BR_STAMP) hostshim` -# pattern rule matched the old standalone defconfig and make dutifully "remade" -# it — by forwarding a target literally named `/…/configs/mister_initramfs_defconfig` -# into Buildroot **with O=$(OUTPUT_DIR)**, i.e. loading the stage-1 config into -# the MAIN build's output directory. Caught with `make -n initramfs`. An -# explicit empty rule beats a pattern rule. -$(sort $(INITRAMFS_DE10NANO_STACK) $(INITRAMFS_DE25NANO_STACK)): ; - -# Exactly the same landmine, for the SD-card installer defconfig (see the -# comment above it, and INSTALLER_OUTPUT_DIR's header comment). -$(INSTALLER_DEFCONFIG): ; +.PHONY: all help hostshim buildroot-unpack buildroot-verify buildroot-showsig +.PHONY: de25 sdcard clean distclean -# `make` with no target builds the full image, same as bare Buildroot. -# -# TWO-STAGE (P1.10 / A1). `initramfs` is a hard prerequisite, not a convenience: -# U-Boot passes `-` for the initrd argument of `bootz` and never loads one (A3), so -# the cpio has to be INSIDE the zImage. external.mk points the kernel's -# CONFIG_INITRAMFS_SOURCE at $(INITRAMFS_CPIO) and refuses to configure the kernel -# if that file is not there — so stage 1 must have run first. Ordering it here is -# what makes a bare `make all` do the right thing. -# -# The mkdir is not decoration: the main defconfig's BR2_ROOTFS_OVERLAY names -# $(EXTRA_MODULES_OVERLAY), and Buildroot HARD-FAILS on a missing overlay path -# at target-finalize — hours into a cold build. An empty dir contributes -# nothing (byte-identical image), so creating it unconditionally is the safe -# default; `make rt` (or CI's kernel-artifact download) is what populates it. -all: initramfs $(BR_STAMP) hostshim | $(OUTPUT_DIR)/.config - @mkdir -p $(EXTRA_MODULES_OVERLAY) +all: $(BR_STAMP) hostshim + @test -f $(O)/.config || { \ + echo "FATAL: $(O)/.config does not exist -- configure first:" >&2; \ + echo " make mister_de10nano_defconfig # DE10-Nano image" >&2; \ + echo " make O=output-de25 mister_de25nano_defconfig # DE25-Nano" >&2; exit 1; } $(BR_MAKE) all - @$(MAKE) --no-print-directory check-initramfs - -# Self-heal a wiped output/ — and NOTHING else. -# -# Buildroot treats .config as build *input*, not output: its `all` refuses to run -# without one (work/buildroot/Makefile:981) and its `clean` deliberately keeps -# it. So `make clean && make all` was always fine, while `rm -rf output && make -# all` died with "Please configure Buildroot first". This rule closes that hole. -# -# The empty prerequisite list is the load-bearing part: with no prerequisites, an -# existing .config is always up to date and this recipe never fires again. Giving -# it the shape stage 1 uses ($(INITRAMFS_OUTPUT_DIR)/.config: ) -# would instead re-generate output/.config from the fragments every time one -# of them looked newer — silently discarding `make menuconfig` edits that had -# not been folded back into a fragment. Stage 1 can afford that; its config is -# generated, not iterated on. Stage 2's is the one people edit. Regenerate -# deliberately with `make de10nano-defconfig` (what CI does, every run). -# -# $(BR_STAMP) is order-only because a parallel `make -j all` gives no ordering -# between all's own prerequisites, so this cannot rely on all's copy of it. -# `hostshim` is order-only here too, so the Buildroot invocation below finds -# the GNU `install` shim under `make -j`. The explicit rule also beats the `%:` -# catch-all at the bottom of this file, same as `Makefile: ;` and -# the stage-1 fragment rule above. -$(OUTPUT_DIR)/.config: | $(BR_STAMP) hostshim - $(call merge_fragments,$(OUTPUT_DIR),$(DE10NANO_STACK)) - $(BR_MAKE) olddefconfig - -# Force-regenerate the DE10-Nano configuration from its fragment stack -- -# the replacement for the old `make mister_de10nano_defconfig`. CI runs this -# unconditionally so a stale output/.config can never mask a fragment change. -.PHONY: de10nano-defconfig -de10nano-defconfig: | $(BR_STAMP) hostshim - @rm -f $(OUTPUT_DIR)/.config - @$(MAKE) --no-print-directory $(OUTPUT_DIR)/.config - -# The three monolithic defconfigs were split into configs/fragments/ (see the -# fragment block above). Anything still asking for them by name gets told -# where to go instead of a confusing Buildroot "no rule" failure. -.PHONY: mister_de10nano_defconfig mister_kernel_defconfig mister_de25nano_defconfig -mister_de10nano_defconfig mister_kernel_defconfig mister_de25nano_defconfig: - @echo "FATAL: configs/$@ no longer exists -- the monolithic defconfigs were split into" >&2 - @echo " configs/fragments/ (docs/buildroot-config.md §1). Use instead:" >&2 - @echo " make de10nano-defconfig # the DE10-Nano image (output/.config)" >&2 - @echo " make de25nano-defconfig # the DE25-Nano developer OS (output-de25/.config)" >&2 - @echo " make rt # the kernel-only base + configs/mister_rt.fragment" >&2 - @exit 1 - -# --- Cleaning ----------------------------------------------------------------- -# Buildroot's vocabulary, kept on purpose: `clean` deletes what the build -# produced but KEEPS .config (work/buildroot/Makefile:1140); `distclean` also -# drops the configuration itself (:1146). The only thing widened is the scope, -# because P1.10 gave this tree two output directories and Buildroot assumes one. -# -# Without an explicit rule here, `clean` fell through the `%:` catch-all and was -# forwarded with O=$(OUTPUT_DIR) only — stage 1 was left fully built. A tree that -# is half-clean is worse than one that is not clean at all, because it looks -# fresh. The `if -d` guards keep `make clean` from being the thing that downloads -# and unpacks Buildroot just to have somewhere to run rm — which is what going -# through the catch-all ($(BR_STAMP) is one of its prerequisites) used to mean. -# -# $(BR_DIR) can vanish independently of the output dirs — it is gitignored, and -# `rm -rf work/` is how you force a re-download. Upstream cannot hit this case -# because upstream's Makefile *is* the Buildroot tree; ours is not, so the check -# is ours to make. Erroring rather than skipping is the point: Buildroot's clean -# is the only thing that knows what to delete and what to keep, so skipping it -# would report success over a still-dirty tree — this bug, again, one layer out. -clean: - @if [ ! -d $(BR_DIR) ] && { [ -d $(OUTPUT_DIR) ] || [ -d $(INITRAMFS_OUTPUT_DIR) ] || [ -d $(DE25_INITRAMFS_OUTPUT_DIR) ] || [ -d $(RT_OUTPUT_DIR) ] || [ -d $(INSTALLER_OUTPUT_DIR) ] || [ -d $(DE25_OUTPUT_DIR) ] || [ -d $(INSTALLER_KERNEL_OUTPUT_DIR) ] || [ -d $(SDCARD_STAGE_DIR) ] || [ -d $(SDCARD_BUILD_DIR) ]; }; then \ - echo "FATAL: $(BR_DIR) is gone, so Buildroot's own 'clean' cannot run," >&2; \ - echo " but an output directory still holds build products. Skipping" >&2; \ - echo " would report success over a dirty tree." >&2; \ - echo "" >&2; \ - echo "Use 'make distclean' to remove all output directories outright." >&2; \ - exit 1; \ - fi - @if [ -d $(OUTPUT_DIR) ]; then $(BR_MAKE) clean; fi - @if [ -d $(INITRAMFS_OUTPUT_DIR) ]; then $(BR_MAKE_INITRAMFS) clean; fi - @if [ -d $(DE25_INITRAMFS_OUTPUT_DIR) ]; then $(BR_MAKE_DE25_INITRAMFS) clean; fi - @if [ -d $(RT_OUTPUT_DIR) ]; then $(BR_MAKE_RT) clean; fi - @if [ -d $(INSTALLER_OUTPUT_DIR) ]; then $(BR_MAKE_INSTALLER) clean; fi - @if [ -d $(DE25_OUTPUT_DIR) ]; then $(BR_MAKE_DE25) clean; fi - @rm -rf $(INSTALLER_KERNEL_OUTPUT_DIR) $(SDCARD_STAGE_DIR) $(SDCARD_BUILD_DIR) $(CONFIG_CHECK_DIR) - @# The extra-modules overlay is a build product (staged module trees), so - @# clean takes it wholesale, stamps included — the next `make rt` restages - @# its tree, and `all` recreates the (empty) dir before Buildroot needs it. - @rm -rf $(EXTRA_MODULES_OVERLAY) $(RT_OVERLAY_STAMP) - -# `rm -rf`, not a forwarded `$(BR_MAKE) distclean`, and deliberately not -# `distclean: clean` the way upstream writes it (:1146). -# -# Upstream removes $(O) itself ONLY when O is the in-tree default (:1147). Ours -# never is, so forwarding distclean would empty the directories but leave -# .config behind — landing in precisely the state that makes `make all` fail. -# Removing both output directories outright is what upstream's distclean *means* -# for an out-of-tree layout, and it makes running `clean` first dead work: there -# is nothing to preserve in a directory that is about to stop existing. -# -# dl/ deliberately survives. Upstream hardcodes `rm -rf $(TOPDIR)/dl` (:1150) and -# never $(DL_DIR) (:203) — a custom BR2_DL_DIR like ours is a shared download -# cache that distclean is not entitled to destroy. `git clean -xfd` is the real -# nothing-but-the-clone hammer; it takes work/ and dl/ with it. -distclean: - rm -rf $(OUTPUT_DIR) $(INITRAMFS_OUTPUT_DIR) $(RT_OUTPUT_DIR) \ - $(INSTALLER_OUTPUT_DIR) $(DE25_OUTPUT_DIR) $(DE25_INITRAMFS_OUTPUT_DIR) \ - $(INSTALLER_KERNEL_OUTPUT_DIR) \ - $(SDCARD_STAGE_DIR) $(SDCARD_BUILD_DIR) $(CONFIG_CHECK_DIR) \ - $(EXTRA_MODULES_OVERLAY) $(RT_OVERLAY_STAMP) - -# --- Stage 1: the initramfs cpio ---------------------------------------------- -# Phony on purpose. Buildroot is the incremental build system here; re-entering it -# is cheap when nothing changed, and it is the only thing that knows that editing -# board/mister/common/initramfs-overlay/init or initramfs-busybox.config means -# the cpio must be regenerated. -initramfs: $(INITRAMFS_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_INITRAMFS) all - @test -f $(INITRAMFS_CPIO) || { \ - echo "FATAL: stage 1 finished but produced no $(INITRAMFS_CPIO)" >&2; exit 1; } - @$(MAKE) --no-print-directory initramfs-verify - @echo "" - @echo "==> stage-1 initramfs: $$(stat -c %s $(INITRAMFS_CPIO)) bytes ($(INITRAMFS_CPIO))" - @echo "" -# The DE25's stage 1: the same recipe aimed at the aarch64 stack. NOT a -# prerequisite of `de25` (see DE25_INITRAMFS_OUTPUT_DIR's header: built and -# proven, not yet embedded). The verify step is the same target with its three -# artifact-locating variables re-pointed -- one set of assertions for both -# boards, so a new applet /init needs cannot be checked on one and not the other. -de25-initramfs: $(DE25_INITRAMFS_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_DE25_INITRAMFS) all - @test -f $(DE25_INITRAMFS_CPIO) || { \ - echo "FATAL: DE25 stage 1 finished but produced no $(DE25_INITRAMFS_CPIO)" >&2; exit 1; } - @$(MAKE) --no-print-directory de25-initramfs-verify - @echo "" - @echo "==> DE25 stage-1 initramfs: $$(stat -c %s $(DE25_INITRAMFS_CPIO)) bytes ($(DE25_INITRAMFS_CPIO))" - @echo " Built and verified; NOT embedded in the DE25 kernel yet (ADR 0029 D11)." - @echo " Boot-test it: scripts/test-initramfs.sh --board de25nano" - @echo "" - -de25-initramfs-verify: - @$(MAKE) --no-print-directory initramfs-verify \ - INITRAMFS_VERIFY_CPIO=$(DE25_INITRAMFS_CPIO) \ - INITRAMFS_VERIFY_BUSYBOX=$(DE25_INITRAMFS_OUTPUT_DIR)/target/bin/busybox \ - INITRAMFS_VERIFY_QEMU=qemu-aarch64 - -# Every command /init actually invokes, asserted against the cpio we just built. -# -# This exists because of a bug that shipped silently and was only caught by booting: -# `CONFIG_ASH_BUILTIN_TEST` is the pre-1.22 spelling of BusyBox's ash `test`/`[` -# builtin (1.37 calls it `CONFIG_ASH_TEST`). kconfig does not warn about unknown -# symbols in an input .config — `olddefconfig` just DROPS them. So the config asked -# for `[`, BusyBox silently built without it, the cpio looked perfectly healthy, and -# /init died on its first `[ -n "$$root_arg" ]` with "line 98: [: not found" — while -# still printing a rescue banner that claimed the command line had no root=. -# -# A wrong applet name is a brick. Check the artifact, not the intent. -INITRAMFS_REQUIRED_APPLETS := sh mount umount losetup switch_root cttyhack setsid \ - sleep mkdir cat ls dmesg tail findfs printf echo test \ - rm sync - -# The one non-applet binary /init runs, and the five exfatprogs ships that it must -# NOT: initramfs-post-build.sh deletes them because every byte here is a byte of -# zImage. Asserted in BOTH directions against the built cpio — a missing fsck.exfat -# makes every requested repair a silent no-op, and a resurrected mkfs.exfat puts a -# card-reformatter one typo away from the boot path. See ADR 0026. -INITRAMFS_REQUIRED_BINS := usr/sbin/fsck.exfat -INITRAMFS_FORBIDDEN_BINS := usr/sbin/dump.exfat usr/sbin/exfat2img usr/sbin/exfatlabel \ - usr/sbin/mkfs.exfat usr/sbin/tune.exfat - -# What initramfs-verify checks, and with which user-mode emulator it parses -# /init. Defaults are the DE10's; de25-initramfs-verify overrides all three. -INITRAMFS_VERIFY_CPIO ?= $(INITRAMFS_CPIO) -INITRAMFS_VERIFY_BUSYBOX ?= $(INITRAMFS_OUTPUT_DIR)/target/bin/busybox -INITRAMFS_VERIFY_QEMU ?= qemu-arm -.PHONY: initramfs-verify -initramfs-verify: - @rc=0; \ - applets=$$(cpio -t --quiet < $(INITRAMFS_VERIFY_CPIO)); \ - for a in $(INITRAMFS_REQUIRED_APPLETS); do \ - echo "$$applets" | grep -qE "^(bin|sbin|usr/bin|usr/sbin)/$$a$$" || { \ - echo "FATAL: /init needs '$$a' but it is not in the cpio." >&2; \ - echo " Check its CONFIG_ symbol really exists in this BusyBox version —" >&2; \ - echo " kconfig silently discards unknown symbols. See the header of" >&2; \ - echo " board/mister/common/initramfs-busybox.config." >&2; \ - rc=1; }; \ - done; \ - for b in $(INITRAMFS_REQUIRED_BINS); do \ - echo "$$applets" | grep -qx "$$b" || { \ - echo "FATAL: /init needs '$$b' but it is not in the cpio." >&2; \ - echo " Is BR2_PACKAGE_EXFATPROGS still set in" >&2; \ - echo " configs/fragments/initramfs-common.fragment, and did the package move its" >&2; \ - echo " install path? See ADR 0026." >&2; \ - rc=1; }; \ - done; \ - for b in $(INITRAMFS_FORBIDDEN_BINS); do \ - echo "$$applets" | grep -qx "$$b" && { \ - echo "FATAL: '$$b' is in the cpio and must not be." >&2; \ - echo " board/mister/common/initramfs-post-build.sh is meant to delete it" >&2; \ - echo " (476 KB of zImage for tools stage 1 cannot invoke). Did the" >&2; \ - echo " post-build hook run? See ADR 0026." >&2; \ - rc=1; }; \ - done; \ - echo "$$applets" | grep -qx 'init' || { \ - echo "FATAL: /init is not in the cpio (the overlay did not apply)." >&2; rc=1; }; \ - echo "$$applets" | grep -qx 'dev/console' || { \ - echo "FATAL: /dev/console is not in the cpio — /init would have no stdio and the" >&2; \ - echo " rescue shell would be unreachable. Is device creation set to STATIC?" >&2; rc=1; }; \ - if command -v $(INITRAMFS_VERIFY_QEMU) >/dev/null 2>&1; then \ - $(INITRAMFS_VERIFY_QEMU) $(INITRAMFS_VERIFY_BUSYBOX) ash -n $(INITRAMFS_INIT) || { \ - echo "FATAL: the BusyBox ash we just built cannot even PARSE /init." >&2; \ - echo " Usually a shell FEATURE that allnoconfig left off (e.g." >&2; \ - echo " CONFIG_FEATURE_SH_MATH for \$$((arith))). shellcheck cannot see this:" >&2; \ - echo " it checks the language, this checks the interpreter we ship." >&2; rc=1; }; \ - else \ - echo "WARN: $(INITRAMFS_VERIFY_QEMU) not installed; skipping the ash -n parse check of /init." >&2; \ - fi; \ - [ $$rc -eq 0 ] && echo "==> initramfs-verify OK ($$(basename $$(dirname $$(dirname $(INITRAMFS_VERIFY_CPIO))))): $(words $(INITRAMFS_REQUIRED_APPLETS)) applets + $(words $(INITRAMFS_REQUIRED_BINS)) binary + $(words $(INITRAMFS_FORBIDDEN_BINS)) trimmed + /init + /dev/console + ash parses /init"; \ - exit $$rc - -# Stage-1 configs are generated from their fragment stacks by the same -# merge_config.sh + olddefconfig idiom as every other configuration here (see -# the "Config fragments" block above). UNLIKE the image configs, the stack's -# fragment files ARE prerequisites: a stage-1 config is generated, never -# iterated on with menuconfig, so regenerating it whenever a fragment is newer -# is the right default (the same behaviour the old standalone defconfig had). -# The empty rule for the fragment files, above, keeps the `%:` catch-all off -# them. $(BR_STAMP) and hostshim are order-only for the reasons given at -# $(OUTPUT_DIR)/.config. -$(INITRAMFS_OUTPUT_DIR)/.config: $(INITRAMFS_DE10NANO_STACK) | $(BR_STAMP) hostshim - $(call merge_fragments,$(INITRAMFS_OUTPUT_DIR),$(INITRAMFS_DE10NANO_STACK)) - $(BR_MAKE_INITRAMFS) olddefconfig - -$(DE25_INITRAMFS_OUTPUT_DIR)/.config: $(INITRAMFS_DE25NANO_STACK) | $(BR_STAMP) hostshim - $(call merge_fragments,$(DE25_INITRAMFS_OUTPUT_DIR),$(INITRAMFS_DE25NANO_STACK)) - $(BR_MAKE_DE25_INITRAMFS) olddefconfig - -# Force-regenerate either stage-1 configuration, mirroring de10nano-defconfig / -# de25nano-defconfig (the file prerequisites above make this mostly redundant, -# but a stale .config left by an interrupted merge does not look newer than -# anything, and this is the deliberate way out). -initramfs-defconfig: | $(BR_STAMP) hostshim - @rm -f $(INITRAMFS_OUTPUT_DIR)/.config - @$(MAKE) --no-print-directory $(INITRAMFS_OUTPUT_DIR)/.config - -de25-initramfs-defconfig: | $(BR_STAMP) hostshim - @rm -f $(DE25_INITRAMFS_OUTPUT_DIR)/.config - @$(MAKE) --no-print-directory $(DE25_INITRAMFS_OUTPUT_DIR)/.config - -initramfs-clean: - rm -rf $(INITRAMFS_OUTPUT_DIR) - -de25-initramfs-clean: - rm -rf $(DE25_INITRAMFS_OUTPUT_DIR) - -# --- RT / Linux-7.2 beta kernel (docs/rt-beta-kernel.md) ---------------------- -# Generates the variant .config by layering configs/mister_rt.fragment on the -# KERNEL-ONLY base stack (common + de10nano + kernel-only fragments, -# $(DE10NANO_KERNEL_STACK)) with Buildroot's own -# merge_config.sh, then builds it into its own output-rt/ (shared -# toolchain sources/dl/ccache; the main output/ is untouched). Produces -# output-rt/images/zImage_dtb — the RT kernel, shipped as zImage_dtb-rt and -# selected on-device by a one-line u-boot.txt edit — plus a depmod'd module -# tree that the `rt` recipe stages into $(EXTRA_MODULES_OVERLAY) so the one -# shipped linux.img carries it. -# Order-only $(BR_STAMP), no file prerequisites — mirrors $(OUTPUT_DIR)/.config -# above (and for the same reason: a defconfig/fragment listed as a normal -# prerequisite is caught by the catch-all target-forwarding rule and would -# re-run against O=$(OUTPUT_DIR)). Re-generate after editing the fragment with -# `make rt-clean && make rt` (same manual step the main config's design implies). -# The rt fragment is the ONE place a later fragment legitimately redefines -# earlier symbols (kernel version + patch dir); scripts/check-config-fragments.sh -# allowlists exactly those. -$(RT_OUTPUT_DIR)/.config: | $(BR_STAMP) hostshim - $(call merge_fragments,$(RT_OUTPUT_DIR),$(DE10NANO_KERNEL_STACK) $(RT_FRAGMENT)) - $(BR_MAKE_RT) olddefconfig - -# `initramfs` is a hard prerequisite for the same reason it is on `all`: -# external.mk's LINUX_KCONFIG_FIXUP_CMDS hook keys on BR2_LINUX_KERNEL=y (any -# O=, this one included) and embeds the stage-1 cpio into the kernel — U-Boot -# never loads an initrd (A3), so a variant zImage without it would panic on -# the FAT root at boot, and the fixup itself hard-fails if the cpio is absent. -# -# The PREEMPT_RT assert below binds to THE kernel tree, never "the first glob -# match": `linux-[0-9]*` (not `linux-*`) so linux-firmware-*/linux-headers-*/ -# linux-pam-* siblings can't match, and MORE than one kernel tree is FATAL — a -# stale sibling (kernel version bumped in the fragment without `make rt-clean`) -# sorts first often enough that picking one blindly would validate the OLD -# kernel's .config and false-pass the one guard proving the RT kernel is RT. -# The module-tree glob below is uniqueness-guarded for the same reason. -rt: initramfs $(RT_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_RT) all - @test -f $(RT_OUTPUT_DIR)/images/zImage_dtb || { \ - echo "FATAL: rt build finished but produced no $(RT_OUTPUT_DIR)/images/zImage_dtb" >&2; exit 1; } - @set -- $$(ls -d $(RT_OUTPUT_DIR)/build/linux-[0-9]*/ 2>/dev/null); \ - if [ $$# -eq 0 ]; then \ - echo "FATAL: rt build finished but no kernel tree exists under" >&2; \ - echo " $(RT_OUTPUT_DIR)/build/linux-[0-9]*/ -- cannot prove the kernel is RT." >&2; exit 1; \ - elif [ $$# -gt 1 ]; then \ - echo "FATAL: $$# kernel trees under $(RT_OUTPUT_DIR)/build/ -- cannot tell which one" >&2; \ - echo " this build produced:" >&2; \ - printf ' %s\n' "$$@" >&2; \ - echo " A stale sibling appears when the fragment's kernel version is bumped" >&2; \ - echo " without discarding the old tree; validating its .config could label a" >&2; \ - echo " non-RT kernel zImage_dtb-rt. Run 'make rt-clean && make rt'." >&2; exit 1; \ - fi; \ - cfg="$$1.config"; \ - if [ ! -f "$$cfg" ]; then \ - echo "FATAL: rt build finished but $$cfg" >&2; \ - echo " does not exist -- cannot prove the kernel is RT." >&2; exit 1; \ - fi; \ - grep -qx 'CONFIG_PREEMPT_RT=y' "$$cfg" || { \ - echo "FATAL: the built RT kernel is NOT RT: CONFIG_PREEMPT_RT=y is absent from" >&2; \ - echo " $$cfg" >&2; \ - echo " merge_config.sh only WARNS when a fragment symbol is dropped, and" >&2; \ - echo " olddefconfig silently discards symbols whose dependencies fail -- so" >&2; \ - echo " without this check a plain 7.2 kernel would ship labeled zImage_dtb-rt." >&2; \ - echo " Two fragment layers are in play and a reviewer has already confused" >&2; \ - echo " them: board/mister/de10nano/linux-rt.fragment is the KERNEL-config" >&2; \ - echo " layer where CONFIG_PREEMPT_RT lives, wired in via the BUILDROOT-config" >&2; \ - echo " layer configs/mister_rt.fragment. Check the kernel-config layer against" >&2; \ - echo " this kernel version's Kconfig (docs/rt-beta-kernel.md §1)." >&2; exit 1; } - @# Stage the depmod'd module tree into the extra-modules overlay so the next - @# `make all` folds it into linux.img. The stamp records which kver rt owns - @# in the overlay: on a kernel-version bump the OLD tree is removed by name, - @# from the overlay AND from output/target/ (the overlay rsync never deletes - @# -- see the EXTRA_MODULES_OVERLAY header -- so an overlay-only removal - @# would leave an incremental `make all` shipping THREE module trees). A - @# future sibling variant's tree, under its own stamp, is never touched. - @set -e; \ - set -- $$(ls -d $(RT_OUTPUT_DIR)/target/usr/lib/modules/*/ 2>/dev/null); \ - if [ $$# -ne 1 ]; then \ - echo "FATAL: expected exactly one module tree under" >&2; \ - echo " $(RT_OUTPUT_DIR)/target/usr/lib/modules/ but found $$#." >&2; \ - echo " Zero means depmod/target-finalize never ran (is BR2_TARGET_ROOTFS_TAR" >&2; \ - echo " still set in configs/fragments/kernel-only.fragment?); more than one is the" >&2; \ - echo " stale-sibling hazard described above. Run 'make rt-clean && make rt'." >&2; exit 1; \ - fi; \ - kver=$$(basename "$$1"); \ - test -s "$$1/modules.alias" || { \ - echo "FATAL: $$1/modules.alias is missing or empty -- depmod did not run at" >&2; \ - echo " target-finalize, so this tree cannot autoload modules on device." >&2; exit 1; }; \ - if [ -f $(RT_OVERLAY_STAMP) ]; then \ - old=$$(cat $(RT_OVERLAY_STAMP)); \ - if [ -n "$$old" ] && [ "$$old" != "$$kver" ]; then \ - rm -rf "$(EXTRA_MODULES_OVERLAY)/usr/lib/modules/$$old" \ - "$(OUTPUT_DIR)/target/usr/lib/modules/$$old"; \ - echo "==> removed rt's stale $$old module tree (overlay + output/target)"; \ - fi; \ - fi; \ - mkdir -p $(EXTRA_MODULES_OVERLAY)/usr/lib/modules; \ - rm -rf "$(EXTRA_MODULES_OVERLAY)/usr/lib/modules/$$kver"; \ - cp -a "$$1" "$(EXTRA_MODULES_OVERLAY)/usr/lib/modules/$$kver"; \ - echo "$$kver" > $(RT_OVERLAY_STAMP); \ - echo ""; \ - echo "==> RT kernel: $(RT_OUTPUT_DIR)/images/zImage_dtb (ship as zImage_dtb-rt — docs/rt-beta-kernel.md)"; \ - echo "==> RT modules: $$kver staged into $(EXTRA_MODULES_OVERLAY)/usr/lib/modules/"; \ - echo " (folded into linux.img by the next 'make all'; 'make rt-clean' removes them)"; \ - echo "" - -# Edit the RT kernel .config interactively (writes back to output-rt/.config). -rt-menuconfig: $(RT_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_RT) linux-menuconfig - -# Buildroot's own `external-deps` / `legal-info`, run against the RT config -# (now the kernel-only one — same target names, much smaller package graph). -# Explicit rules rather than the `%:` catch-all at the bottom, because the -# catch-all forwards with O=$(OUTPUT_DIR) — i.e. against the MAIN build. Same -# reason `rt`/`rt-menuconfig` exist; same rt-* naming precedent. CI leans on -# both: rt-external-deps is the dl/-completeness oracle for the RT variant's -# download cache (it runs with -B upstream, so it ignores stamps), and -# rt-legal-info produces the kernel-source SBOM/GPL bundle for release assets. -rt-external-deps: $(RT_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_RT) external-deps - -rt-legal-info: $(RT_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_RT) legal-info - -# Removes rt's overlay contribution too (by the kver its stamp recorded), AND -# the same tree from output/target/: Buildroot's overlay rsync never deletes -# (see the EXTRA_MODULES_OVERLAY header), so once a `make all` has rsynced the -# tree into output/target/ an overlay-only removal cannot un-ship it -- every -# later incremental `make all` would quietly carry it forever. With both -# removals, "rt-clean then make all" really yields a main-only image. Both rms -# are harmless when their path is absent (fresh checkout, no output/ yet). -# The [ -n "$$kver" ] guard matters doubly now: an empty stamp would otherwise -# turn the rm into `rm -rf .../usr/lib/modules/` -- every variant's tree in -# the overlay, and the MAIN kernel's tree in output/target/. -rt-clean: - @if [ -f $(RT_OVERLAY_STAMP) ]; then \ - kver=$$(cat $(RT_OVERLAY_STAMP)); \ - if [ -n "$$kver" ]; then \ - rm -rf "$(EXTRA_MODULES_OVERLAY)/usr/lib/modules/$$kver" \ - "$(OUTPUT_DIR)/target/usr/lib/modules/$$kver"; \ - echo "==> removed rt's $$kver module tree (overlay + output/target)"; \ - fi; \ - rm -f $(RT_OVERLAY_STAMP); \ - fi - rm -rf $(RT_OUTPUT_DIR) - -# --- DE25-Nano developer OS (D2.1, docs/de25-nano-tasks.md) ------------------- -# Generates output-de25/.config from the de25nano fragment stack. Order-only -# $(BR_STAMP) and NO file prerequisite on the fragments — same shape, same two -# reasons, as $(OUTPUT_DIR)/.config and $(RT_OUTPUT_DIR)/.config above: a -# fragment listed as a normal prerequisite gets caught by the `%:` catch-all -# target-forwarding rule at the bottom of this file and would be "remade" with -# O=$(OUTPUT_DIR) (i.e. loaded into the DE10's output dir — here that would -# mean loading an AARCH64 config over the armv7 build, which is about as bad as -# this class of bug gets), and with no prerequisites an existing .config is -# always up to date, so `make de25-menuconfig` edits are not silently -# discarded by the next `make de25`. -# -# Re-generate after editing a fragment with `make de25nano-defconfig` (or -# `make de25-clean && make de25`), the same deliberate step the main and rt -# configs imply. -# -# `hostshim` is an order-only prerequisite HERE, not only on `de25`: under -# `make -j de25` the sibling prerequisites of `de25` run concurrently, so the -# config recipe (which invokes Buildroot, whose dependency check needs the -# shim's `install` on PATH) could otherwise start before the shim exists. -$(DE25_OUTPUT_DIR)/.config: | $(BR_STAMP) hostshim - $(call merge_fragments,$(DE25_OUTPUT_DIR),$(DE25NANO_STACK)) - $(BR_MAKE_DE25) olddefconfig - -# Force-regenerate the DE25 configuration -- the replacement for the old -# `make mister_de25nano_defconfig`; mirrors de10nano-defconfig above. -.PHONY: de25nano-defconfig -de25nano-defconfig: | $(BR_STAMP) hostshim - @rm -f $(DE25_OUTPUT_DIR)/.config - @$(MAKE) --no-print-directory $(DE25_OUTPUT_DIR)/.config - -# Deliberately NOT `de25: initramfs ...` — see DE25_OUTPUT_DIR's header for why -# the stage-1 cpio has no business in an aarch64 kernel. -# -# The post-build assertions are the DE25's equivalent of `rt`'s -# CONFIG_PREEMPT_RT check and `initramfs`'s cpio check: Buildroot exits 0 on -# plenty of configurations that produce no bootable artifact, and on a board -# with no hardware validation yet the build must say so at the end rather than -# leave someone to discover it at a dead serial console. -# -# The .dtb is asserted by GLOB rather than by name on purpose. The name is -# owned by the defconfig (BR2_LINUX_KERNEL_CUSTOM_DTS_PATH names the board -# file, board/mister/de25nano/socfpga_agilex5_de25nano.dts; it was mainline's -# socdk placeholder until D2.3 landed). A hardcoded filename here would fail -# the build on the day the DTS is renamed or a second variant is added, for a -# reason that has nothing to do with what went wrong. Buildroot -# installs the dtb into images/ under its BASENAME (linux/linux.mk:491-497, -# `notdir` unless BR2_LINUX_KERNEL_DTB_KEEP_DIRNAME), so a flat glob sees it -# either way. Zero dtbs IS a failure: BR2_LINUX_KERNEL_DTS_SUPPORT is on, so an -# empty images/*.dtb means the DTS silently did not build. -de25: $(DE25_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_DE25) all - @test -f $(DE25_OUTPUT_DIR)/images/Image || { \ - echo "FATAL: de25 build finished but produced no $(DE25_OUTPUT_DIR)/images/Image" >&2; \ - echo " (BR2_LINUX_KERNEL_IMAGE=y selects the uncompressed aarch64 'Image'" >&2; \ - echo " target -- if the defconfig was changed to Image.gz, change this" >&2; \ - echo " assertion in the same commit.)" >&2; exit 1; } - @set -- $$(ls $(DE25_OUTPUT_DIR)/images/*.dtb 2>/dev/null); \ - if [ $$# -eq 0 ]; then \ - echo "FATAL: de25 build finished but installed no device tree blob into" >&2; \ - echo " $(DE25_OUTPUT_DIR)/images/ -- BR2_LINUX_KERNEL_DTS_SUPPORT is set," >&2; \ - echo " so this means the DTS named by BR2_LINUX_KERNEL_INTREE_DTS_NAME /" >&2; \ - echo " BR2_LINUX_KERNEL_CUSTOM_DTS_PATH did not build." >&2; exit 1; \ - fi; \ - echo ""; \ - echo "==> DE25 kernel: $(DE25_OUTPUT_DIR)/images/Image ($$(stat -L -c %s $(DE25_OUTPUT_DIR)/images/Image) bytes)"; \ - for d in "$$@"; do echo "==> DE25 dtb: $$d ($$(stat -L -c %s $$d) bytes)"; done; \ - test -f $(DE25_OUTPUT_DIR)/images/rootfs.ext4 || { \ - echo "FATAL: de25 build finished but produced no $(DE25_OUTPUT_DIR)/images/rootfs.ext4" >&2; \ - echo " (BR2_TARGET_ROOTFS_EXT2 + _EXT2_4 select it -- a config that emits no" >&2; \ - echo " rootfs is not a green build, whatever the kernel did.)" >&2; exit 1; }; \ - echo "==> DE25 rootfs: $(DE25_OUTPUT_DIR)/images/rootfs.ext4 ($$(stat -L -c %s $(DE25_OUTPUT_DIR)/images/rootfs.ext4) bytes)"; \ - if [ "$${DE25_ALLOW_NO_UBOOT:-0}" = 1 ] && [ ! -f $(DE25_OUTPUT_DIR)/images/u-boot.itb ]; then \ - echo "==> DE25 bl31/FIT: SKIPPED (DE25_ALLOW_NO_UBOOT=1 and no u-boot.itb was built)"; \ - else \ - test -f $(DE25_OUTPUT_DIR)/images/bl31.bin || { \ - echo "FATAL: de25 build finished but produced no $(DE25_OUTPUT_DIR)/images/bl31.bin" >&2; \ - echo " (BR2_TARGET_ARM_TRUSTED_FIRMWARE_BL31 + _IMAGES=\"bl31.bin\" select it.)" >&2; \ - echo " BL31 is what goes INSIDE u-boot.itb as the 'atf' image, so a missing" >&2; \ - echo " bl31.bin means the FIT below is either absent or built around a" >&2; \ - echo " binman-faked zero blob -- which boots nothing and says nothing." >&2; exit 1; }; \ - echo "==> DE25 bl31: $(DE25_OUTPUT_DIR)/images/bl31.bin ($$(stat -L -c %s $(DE25_OUTPUT_DIR)/images/bl31.bin) bytes)"; \ - test -f $(DE25_OUTPUT_DIR)/images/u-boot.itb || { \ - echo "FATAL: de25 build finished but produced no $(DE25_OUTPUT_DIR)/images/u-boot.itb" >&2; \ - echo " This is THE artifact of the bootloader half of the build: the factory" >&2; \ - echo " SPL in QSPI looks for a file of exactly that name on FAT partition 1" >&2; \ - echo " (SPL_FS_LOAD_PAYLOAD_NAME under SPL_LOAD_FIT, boot partition 1)." >&2; \ - echo " The usual cause is CONFIG_BINMAN having gone off: it is selected only" >&2; \ - echo " as 'select BINMAN if SPL_ATF' and it has no prompt, so anything that" >&2; \ - echo " turns CONFIG_SPL off takes the FIT with it, silently and with a green" >&2; \ - echo " U-Boot build. See board/mister/de25nano/uboot.fragment, SPL block." >&2; exit 1; }; \ - echo "==> DE25 FIT: $(DE25_OUTPUT_DIR)/images/u-boot.itb ($$(stat -L -c %s $(DE25_OUTPUT_DIR)/images/u-boot.itb) bytes)"; \ - echo " Verify its shape against the factory SPL contract with:"; \ - echo " $(DE25_OUTPUT_DIR)/host/bin/dumpimage -l $(DE25_OUTPUT_DIR)/images/u-boot.itb"; \ - echo " Bare developer OS -- no MiSTer binaries."; \ - echo ""; \ - fi - @if [ -f $(DE25_OUTPUT_DIR)/images/sdcard-de25.img ]; then \ - echo "==> DE25 card: $(DE25_OUTPUT_DIR)/images/sdcard-de25.img ($$(stat -L -c %s $(DE25_OUTPUT_DIR)/images/sdcard-de25.img) bytes)"; \ - echo " dd it to a card; docs/de25-sdcard.md."; \ - echo ""; \ - elif [ "$${DE25_ALLOW_NO_UBOOT:-0}" = 1 ] && [ ! -f $(DE25_OUTPUT_DIR)/images/u-boot.itb ]; then \ - echo "==> DE25 card: SKIPPED (DE25_ALLOW_NO_UBOOT=1 and no u-boot.itb) -- nothing"; \ - echo " this build produced can boot a board."; \ - echo ""; \ - else \ - echo "FATAL: de25 build finished but produced no $(DE25_OUTPUT_DIR)/images/sdcard-de25.img" >&2; \ - echo " (BR2_ROOTFS_POST_IMAGE_SCRIPT runs board/mister/de25nano/post-image.sh," >&2; \ - echo " which assembles the card and hands it to scripts/check-sdcard-de25.sh." >&2; \ - echo " A build that emits no card is not a green build.)" >&2; exit 1; \ - fi - -# Escape hatches for iterating without hand-editing the checked-in fragments. -# Both write to output-de25/; fold the result back into -# configs/fragments/de25nano.fragment by hand (a `savedefconfig` of -# output-de25/ is unordered, comment-free and NOT tracked -- -# docs/buildroot-config.md §1), into board/mister/de25nano/linux.config, or -- -# carefully, it is SHARED with the DE10 and must stay a no-op there -# (scripts/check-kernel-fragment-noop.sh) -- into -# board/mister/common/linux-mister.fragment. -# -# de25-linux-menuconfig exists as its own target for the same reason -# rt-menuconfig does: the `%:` catch-all would forward a bare -# `make linux-menuconfig` with O=$(OUTPUT_DIR), i.e. against the DE10. -de25-menuconfig: $(DE25_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_DE25) menuconfig - -de25-linux-menuconfig: $(DE25_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_DE25) linux-menuconfig - -# Plain rm -rf, like initramfs-clean/installer-clean and unlike rt-clean: this -# build stages nothing into the extra-modules overlay and contributes nothing -# to output/, so there is no second removal to pair with. -de25-clean: - rm -rf $(DE25_OUTPUT_DIR) - -# --- SD-card installer (P5.3, docs/decisions/0020-sdcard-exfat-reformat-installer.md) --- -# Builds ONLY the installer initramfs cpio, standalone. scripts/mk-sdcard.sh -# builds this exact output dir itself as step 1/7 of `make sdcard` (see -# INSTALLER_OUTPUT_DIR's header comment above) — this target is the escape -# hatch for iterating on configs/mister_installer_defconfig or -# board/mister/de10nano/installer-overlay/ without running the whole sdcard -# pipeline, mirroring `initramfs` above. -$(INSTALLER_OUTPUT_DIR)/.config: $(INSTALLER_DEFCONFIG) | $(BR_STAMP) - @mkdir -p $(INSTALLER_OUTPUT_DIR) - $(BR_MAKE_INSTALLER) mister_installer_defconfig - -installer: $(INSTALLER_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_INSTALLER) all - @test -f $(INSTALLER_CPIO) || { \ - echo "FATAL: installer build finished but produced no $(INSTALLER_CPIO)" >&2; exit 1; } - @echo "" - @echo "==> installer cpio: $$(stat -c %s $(INSTALLER_CPIO)) bytes ($(INSTALLER_CPIO))" - @echo "" - -installer-menuconfig: $(INSTALLER_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_INSTALLER) menuconfig - -installer-busybox-menuconfig: $(INSTALLER_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_INSTALLER) busybox-menuconfig - -installer-clean: - rm -rf $(INSTALLER_OUTPUT_DIR) - -# Escape hatches for iterating on stage 1 without hand-editing the checked-in -# configs. They write to output-initramfs/ (or output-initramfs-de25/); -# remember to fold the result back into the initramfs-common / initramfs- -# fragment under configs/fragments/ -# or into board/mister/common/initramfs-busybox.config by hand -- and note that -# the NEXT `make initramfs` regenerates the .config from the fragments if one -# of them is newer (a stage-1 config is generated, not iterated on). -initramfs-menuconfig: $(INITRAMFS_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_INITRAMFS) menuconfig - -initramfs-busybox-menuconfig: $(INITRAMFS_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_INITRAMFS) busybox-menuconfig - -de25-initramfs-menuconfig: $(DE25_INITRAMFS_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_DE25_INITRAMFS) menuconfig - -de25-initramfs-busybox-menuconfig: $(DE25_INITRAMFS_OUTPUT_DIR)/.config hostshim - $(BR_MAKE_DE25_INITRAMFS) busybox-menuconfig +# The pinned tree: fetched + SHA-256-verified + unpacked once per version (the +# stamp carries the version, so a bump is a new target and re-fetches). +$(BR_STAMP): + scripts/fetch-buildroot.sh $(BUILDROOT_VERSION) $(BUILDROOT_SHA256) $(BR2_DL_DIR) $(BR_DIR) + @touch $@ +buildroot-unpack: $(BR_STAMP) +buildroot-verify: + scripts/fetch-buildroot.sh --verify-only $(BUILDROOT_VERSION) $(BUILDROOT_SHA256) $(BR2_DL_DIR) +buildroot-showsig: + scripts/fetch-buildroot.sh --showsig $(BUILDROOT_VERSION) -# --- The assertion that stops a silent brick ---------------------------------- -# docs/boot-chain.md §8, I1 and I2. The failure this guards against is not loud: a -# kernel built with CONFIG_INITRAMFS_SOURCE="" boots perfectly, runs the kernel's -# own default_cpio_list rootfs, finds no /init, calls prepare_namespace(), tries to -# mount root=/dev/mmcblk0p1 (a FAT partition) as a root filesystem, and panics — -# with a message that points at the disk, not at the build. Fail at build time -# instead. Also run standalone: `make check-initramfs`. -check-initramfs: - @cfg=$$(ls -d $(OUTPUT_DIR)/build/linux-*/ 2>/dev/null | head -1)".config"; \ - if [ ! -f "$$cfg" ]; then \ - echo "==> check-initramfs: no kernel build in $(OUTPUT_DIR) yet — nothing to check."; \ - echo " (P1.3 owns turning BR2_LINUX_KERNEL on in the main defconfig.)"; \ - exit 0; \ - fi; \ - rc=0; \ - grep -qx 'CONFIG_BLK_DEV_INITRD=y' "$$cfg" || { \ - echo "FAIL (I1): CONFIG_BLK_DEV_INITRD is not y in $$cfg" >&2; rc=1; }; \ - grep -q '^CONFIG_INITRAMFS_SOURCE=".\+"' "$$cfg" || { \ - echo "FAIL (I2): CONFIG_INITRAMFS_SOURCE is empty in $$cfg — the kernel has NO" >&2; \ - echo " initramfs. It will panic on a FAT root at boot." >&2; rc=1; }; \ - [ $$rc -eq 0 ] && echo "==> check-initramfs OK: $$(grep '^CONFIG_INITRAMFS_SOURCE=' $$cfg)"; \ - exit $$rc +# GNU `install` shim for hosts whose install is uutils (no-op elsewhere). +hostshim: + @scripts/hostshim.sh $(HOSTSHIM) -# --- zImage_dtb (P1.11 / A3) ---------------------------------------------------- -# The REAL hook is BR2_ROOTFS_POST_IMAGE_SCRIPT in configs/fragments/de10nano.fragment -# (board/mister/de10nano/post-image.sh), which Buildroot runs automatically at the -# end of every `$(BR_MAKE) all` and which already fails the build on a contract -# violation -- so `make all` needs no extra step here, unlike check-initramfs above -# (nothing else asserts THAT one). -# -# This target exists for standalone use: iterating on post-image.sh / linux.config -# without a full `make all`, or (until P1.3's Buildroot-level kernel wiring lands) -# pointing it at any pre-built zImage+DTB pair via ZIMAGE_DTB_BINARIES_DIR=, e.g. a -# scratch dir populated from a raw kbuild tree such as work/k-final: -# make zimage-dtb ZIMAGE_DTB_BINARIES_DIR=/path/to/scratch/images -# (post-image.sh also searches BINARIES_DIR/../build/.../arch/arm/boot/ if the -# image is not directly in BINARIES_DIR -- see its own header.) -ZIMAGE_DTB_BINARIES_DIR ?= $(OUTPUT_DIR)/images -zimage-dtb: - @mkdir -p $(ZIMAGE_DTB_BINARIES_DIR) - $(ROOT_DIR)/board/mister/de10nano/post-image.sh $(ZIMAGE_DTB_BINARIES_DIR) +# The DE25-Nano builds in its own output tree; this is `make O=output-de25`. +de25: $(BR_STAMP) hostshim + $(MAKE) O=$(ROOT_DIR)/output-de25 all -# --- Full SD-card image (P5.3, docs/decisions/0020-sdcard-exfat-reformat-installer.md) --- -# Runs scripts/mk-sdcard.sh, the orchestrator that builds the installer cpio + -# relinked installer kernel, fetches/stages the mr-fusion-parity payload, and -# assembles + xz's the dd/Etcher-writable output/images/sdcard.img(.xz) (or -# sdcard-full.img(.xz) when SDCARD_CORES=1). See that script's own header for -# its seven steps — it drives Buildroot directly for the installer pieces and -# does NOT go through the `installer` target above. -# -# Requires a COMPLETED `make rt` THEN `make all` first — the ORDER matters: -# mk-sdcard.sh snapshots output/images/linux.img as-built, and only a `make -# all` that runs AFTER `make rt` has folded the RT module tree (staged in the -# extra-modules overlay) into that image. Built the other way round, the card -# would stage zImage_dtb-rt next to a linux.img with no matching modules — -# docs/rt-beta-kernel.md §5's silent broken-peripherals failure. mk-sdcard.sh -# reads output/images/{linux.img,zImage_dtb} (the real, Downloader-shipped -# outputs) plus output-rt/images/zImage_dtb (shipped on the card as -# zImage_dtb-rt so one flashable card carries both kernels — override the -# source with MISTER_RT_ZIMAGE=), fails loudly, by name, if any is missing, -# and cross-checks linux.img against the overlay's staged kver(s) so an -# out-of-order build dies there instead of shipping. -# Deliberately NOT made an `all`/`rt`-dependent prerequisite here — those are -# multi-hour builds, and a script that already checks its own prerequisites -# should not have that check duplicated (and silently re-triggered) at the -# Make level. Mirrors `rt`/`initramfs` in every other respect: a phony target, -# hostshim ensured first, SDCARD_CORES passed straight through from the -# environment/command line. -SDCARD_CORES ?= 0 +# SD-card installer image (ADR 0020): a shell orchestrator, run after `make all`. sdcard: hostshim SDCARD_CORES=$(SDCARD_CORES) $(ROOT_DIR)/scripts/mk-sdcard.sh -# Deliberately does NOT depend on $(BR_STAMP): `make help` on a fresh clone (or -# with no network) must print something useful rather than trying to fetch a -# tarball first. Buildroot's own target list is behind `make br-help`, which -# does need the tree. -help: - @echo "MiSTer BR2_EXTERNAL wrapper (TASKS.md P1.1)" - @echo "" - @echo " make de10nano-defconfig - (re)generate output/.config from the DE10-Nano" - @echo " fragment stack (configs/fragments/, stacks.mk)" - @echo " make menuconfig - interactive Buildroot config" - @echo " make linux-menuconfig - interactive kernel config" - @echo " make savedefconfig - save current config to output/defconfig (fold" - @echo " it back into configs/fragments/ by hand)" - @echo " make olddefconfig - non-interactively resolve config to defaults" - @echo " make list-defconfigs - list built-in and external defconfigs" - @echo " (only the installer one remains)" - @echo " make buildroot-verify - download (if needed) + SHA-256-verify the" - @echo " pinned Buildroot tarball, without unpacking" - @echo " make buildroot-showsig - print upstream's GPG-signed release manifest" - @echo " (the ONLY valid source for BUILDROOT_SHA256)" - @echo " make br-help - Buildroot's own target list" - @echo " make all - build the full image (runs 'initramfs' first)" - @echo "" - @echo "Cleaning (Buildroot's meanings, applied to ALL output dirs):" - @echo " make clean - delete everything the build produced," - @echo " KEEPING all .config files" - @echo " make distclean - rm -rf output/, output-initramfs/, output-rt/," - @echo " output-installer/, output-de25/," - @echo " output-initramfs-de25/, the sdcard" - @echo " staging dirs and" - @echo " the extra-modules overlay, .config included;" - @echo " dl/ is kept (it is a shared cache —" - @echo " 'git clean -xfd' takes it)" - @echo "" - @echo "Two-stage initramfs (P1.10):" - @echo " make initramfs - build ONLY the stage-1 cpio and print its size" - @echo " make initramfs-menuconfig - Buildroot menuconfig for the stage-1 config" - @echo " make initramfs-busybox-menuconfig - BusyBox menuconfig for the stage-1 BusyBox" - @echo " make initramfs-clean - rm -rf output-initramfs/" - @echo " make check-initramfs - assert the built kernel really embeds the cpio" - @echo " make de25-initramfs - the SAME stage 1 built for aarch64 into" - @echo " output-initramfs-de25/ and verified (built and" - @echo " QEMU-proven; not embedded in the DE25 kernel yet)" - @echo " make de25-initramfs-clean - rm -rf output-initramfs-de25/" - @echo "" - @echo "RT / Linux-7.2 beta kernel (docs/rt-beta-kernel.md):" - @echo " make rt - kernel-only build of the PREEMPT_RT variant into" - @echo " output-rt/ (asserts CONFIG_PREEMPT_RT=y), then" - @echo " stage its module tree into the extra-modules" - @echo " overlay so the next 'make all' ships it in" - @echo " linux.img" - @echo " make rt-menuconfig - kernel menuconfig for the RT variant" - @echo " make rt-external-deps - list every download the RT config needs (CI's" - @echo " dl/-completeness oracle)" - @echo " make rt-legal-info - legal-info (SBOM + kernel sources) for the RT" - @echo " variant" - @echo " make rt-clean - rm -rf output-rt/ + remove rt's module tree" - @echo " from the extra-modules overlay AND output/target" - @echo " (Buildroot's overlay rsync never deletes)" - @echo "" - @echo "DE25-Nano developer OS (aarch64 / Agilex 5 -- docs/de25-nano-tasks.md D2.1):" - @echo " make de25 - build the DE25-Nano image into output-de25/" - @echo " (aarch64 toolchain + mainline 7.2.3 kernel +" - @echo " minimal BusyBox ext4 rootfs + TF-A/U-Boot FIT +" - @echo " the SD-card image; asserts images/Image, a .dtb," - @echo " bl31.bin, u-boot.itb and sdcard-de25.img exist)." - @echo " BARE DEVELOPER OS: no MiSTer binaries. Does NOT" - @echo " run 'initramfs' (armv7) nor 'de25-initramfs'" - @echo " (built + QEMU-proven, not embedded yet: D11)." - @echo " make de25nano-defconfig - (re)generate output-de25/.config from its" - @echo " fragment stack (common + de25nano)" - @echo " make de25-menuconfig - Buildroot menuconfig for the DE25 config" - @echo " make de25-linux-menuconfig - kernel menuconfig for the DE25 kernel" - @echo " make de25-clean - rm -rf output-de25/" - @echo "" - @echo "zImage_dtb assembly (P1.11):" - @echo " make zimage-dtb - cat zImage+DTB and run scripts/check-zimage-dtb.sh" - @echo " (runs automatically at the end of 'make all' via" - @echo " BR2_ROOTFS_POST_IMAGE_SCRIPT; override the source" - @echo " dir with ZIMAGE_DTB_BINARIES_DIR=)" - @echo "" - @echo "SD-card installer image (P5.3, ADR 0020):" - @echo " make sdcard - after 'make all' (the card ships no variant" - @echo " kernel, so 'make rt' is optional; if you do" - @echo " build rt, do it FIRST so 'all' folds its" - @echo " modules into linux.img), run" - @echo " scripts/mk-sdcard.sh to produce" - @echo " output/images/sdcard.img(.xz)" - @echo " (SDCARD_CORES=1 for sdcard-full.img(.xz))" - @echo " make installer - build ONLY the installer stage-1 cpio and print" - @echo " its size (escape hatch; mk-sdcard.sh builds this" - @echo " same output-installer/ itself)" - @echo " make installer-menuconfig - Buildroot menuconfig for the installer config" - @echo " make installer-busybox-menuconfig - BusyBox menuconfig for the installer BusyBox" - @echo " make installer-clean - rm -rf output-installer/" +# Buildroot's own meanings: clean keeps .config, distclean removes the tree. +# dl/ is a shared download cache and survives both; `git clean -xfd` takes it. +clean: $(BR_STAMP) + @for o in $(O) $(ROOT_DIR)/output-de25 $(ROOT_DIR)/output-installer; do \ + [ -f $$o/.config ] && $(MAKE) -C $(BR_DIR) O=$$o BR2_EXTERNAL=$(ROOT_DIR) clean; done; true + rm -rf $(ROOT_DIR)/output-installer-kernel $(ROOT_DIR)/output-sdcard-stage $(ROOT_DIR)/output-sdcard-build $(ROOT_DIR)/output-config-check +distclean: + rm -rf $(O) $(ROOT_DIR)/output-de25 $(ROOT_DIR)/output-installer $(ROOT_DIR)/output-installer-kernel \ + $(ROOT_DIR)/output-sdcard-stage $(ROOT_DIR)/output-sdcard-build $(ROOT_DIR)/output-config-check + +help: $(BR_STAMP) hostshim + @echo "MiSTer Buildroot external (Buildroot $(BUILDROOT_VERSION), BR2_EXTERNAL=$(ROOT_DIR), O=$(O))" + @echo " make mister_de10nano_defconfig && make the DE10-Nano image (output/)" + @echo " make O=output-de25 mister_de25nano_defconfig && make O=output-de25 the DE25-Nano (or: make de25)" + @echo " make sdcard installer card image, after make all" + @echo " make buildroot-unpack | buildroot-verify | buildroot-showsig" + @echo "Everything else is Buildroot's own (below), forwarded with O= and BR2_EXTERNAL set." @echo "" - @echo "Pinned Buildroot: $(BUILDROOT_VERSION) (BR2_EXTERNAL=$(ROOT_DIR))" - @echo "Any other target is forwarded verbatim into Buildroot's own Makefile." - -br-help: $(BR_STAMP) hostshim - $(BR_MAKE) help - -# Print upstream's clearsigned release manifest, which carries the authoritative -# SHA256 line. Use this — not `sha256sum` of a tarball you just downloaded — -# whenever BUILDROOT_VERSION is bumped. -buildroot-showsig: - @echo "==> $(BUILDROOT_SIG_URL)" - @curl -fsSL $(BUILDROOT_SIG_URL) || { \ - echo "FATAL: could not fetch the release signature." >&2; exit 1; } - -# Fail fast and by name, the way scripts/inventory/common.sh's mrl_require does, -# rather than dying deep inside a recipe with "curl: command not found". -require-tools: - @for t in curl tar sha256sum; do \ - command -v $$t >/dev/null 2>&1 || { \ - echo "FATAL: required tool '$$t' not found in PATH." >&2; exit 1; }; \ - done - -# --- Download, verify, unpack Buildroot --------------------------------------- + @$(BR_MAKE) help -# Plain file-based rule: only fetches if $(BR_TARBALL) isn't already on disk. -# Download to .tmp and rename only on success, so an interrupted transfer can -# never leave a truncated tarball parked at the real path. -$(BR_TARBALL): | require-tools - @mkdir -p $(DL_DIR) - @echo "==> Downloading Buildroot $(BUILDROOT_VERSION) from $(BUILDROOT_URL)" - @curl -fSL --retry 3 -o $@.tmp $(BUILDROOT_URL) - @mv $@.tmp $@ - -# Downloads (if needed) and checks the tarball against the pinned hash. -# Standalone and directly invokable so the verification path can be exercised -# (and its failure mode demonstrated) without touching work/buildroot. -buildroot-fetch: $(BR_TARBALL) - -buildroot-verify: $(BR_TARBALL) - @echo "==> Verifying SHA-256 of $(BR_TARBALL)" - @echo "$(BUILDROOT_SHA256) $(BR_TARBALL)" | sha256sum -c - >/dev/null 2>&1 || { \ - echo "" >&2; \ - echo "FATAL: SHA-256 mismatch for $(BR_TARBALL)" >&2; \ - echo " expected: $(BUILDROOT_SHA256)" >&2; \ - echo " actual: $$(sha256sum $(BR_TARBALL) | cut -d' ' -f1)" >&2; \ - echo "" >&2; \ - echo "Refusing to unpack a Buildroot tarball that does not match the pinned hash." >&2; \ - echo "" >&2; \ - echo "The cached tarball is corrupt, truncated, or not what upstream published." >&2; \ - echo "To recover, DELETE IT and let it re-download:" >&2; \ - echo " rm -f $(BR_TARBALL) && make buildroot-verify" >&2; \ - echo "" >&2; \ - echo "Do NOT 'fix' this by pasting the actual hash above into BUILDROOT_SHA256." >&2; \ - echo "That defeats the entire check and would bless a bad tarball. A new hash is" >&2; \ - echo "legitimate ONLY when it comes from upstream's GPG-signed release manifest:" >&2; \ - echo " make buildroot-showsig BUILDROOT_VERSION=" >&2; \ - exit 1; \ - } - @echo "==> SHA-256 OK ($(BUILDROOT_SHA256))" - -# The stamp is the idempotency gate: if work/buildroot/ already holds the -# pinned version (e.g. pre-seeded, as it is in this repo today) this never -# touches the network. Otherwise it downloads, verifies, and unpacks. -$(BR_STAMP): - @mkdir -p $(WORK_DIR) - @set -e; \ - if [ -f $(BR_DIR)/Makefile ] && grep -qx 'export BR2_VERSION := $(BUILDROOT_VERSION)' $(BR_DIR)/Makefile 2>/dev/null; then \ - echo "==> Buildroot $(BUILDROOT_VERSION) already present at $(BR_DIR); skipping download/unpack"; \ - else \ - $(MAKE) --no-print-directory buildroot-verify; \ - echo "==> Unpacking Buildroot $(BUILDROOT_VERSION) to $(BR_DIR)"; \ - rm -rf $(BR_DIR); \ - mkdir -p $(BR_DIR); \ - tar -C $(BR_DIR) --strip-components=1 -xf $(BR_TARBALL); \ - fi - @touch $@ - -buildroot-unpack: $(BR_STAMP) +# GNU make would otherwise try to remake this file through the catch-all. +Makefile: ; -# --- Forward everything else into Buildroot ------------------------------------ -# make menuconfig, make linux-menuconfig, make savedefconfig, make -# mister_installer_defconfig (Buildroot's own %_defconfig rule finds it under -# this tree's configs/, since BR2_EXTERNAL is set above), etc. +# Every other goal is Buildroot's: menuconfig, linux-menuconfig, savedefconfig, +# legal-info, external-deps, -rebuild, list-defconfigs, ... %: $(BR_STAMP) hostshim $(BR_MAKE) $@ diff --git a/README.md b/README.md index 9bd27a19..33f2cde5 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ executed separately from this rootfs-side re-measurement. **On version drift, since this table cites documents that can lag it.** The ground truth for "ours" is always the build pins — `BUILDROOT_VERSION` in the `Makefile` and -the DE10-Nano fragment stack under `configs/fragments/` — plus whatever Buildroot's own `.mk` files resolve +`configs/mister_de10nano_defconfig` and the profiles it enables under `package/mister-*/` — plus whatever Buildroot's own `.mk` files resolve to at that pin. The documents below are **dated analyses**, not a live mirror of those pins: a Renovate bump or a Buildroot line bump moves a package without rewriting the prose that reasoned about it. Where a document is behind the pin it now says so at the @@ -174,7 +174,7 @@ Validated on **one real DE10-Nano**, booting CI-built artifacts: | Bluetooth — firmware load + controller pairing | ✅ Confirmed | | Wi-Fi — **WPA3/SAE (PMF required)** 5 GHz auto-connect via mainline `rtw88` | ✅ Confirmed | | Downloader over HTTPS | ✅ Confirmed | -| **`PREEMPT_RT` kernel boots and runs MiSTer** | ✅ Confirmed on **7.2-rc4** (2026-07-20) and **7.2-rc7** (2026-08-14). The pin has since moved to **7.2 final**, which builds green (`make rt`, 2026-08-17) but has **not been booted** — boot is a per-version claim | +| **`PREEMPT_RT` kernel boots and runs MiSTer** | ✅ Confirmed on **7.2-rc4** (2026-07-20) and **7.2-rc7** (2026-08-14). The pin has since moved to **7.2 final**, which builds green (`make linux-rt`, 2026-08-17) but has **not been booted** — boot is a per-version claim | | Samba, MIDI | ⚠️ Build/CI-verified only — **not** exercised on hardware | | RT latency measurement | ⏳ Not yet taken | @@ -328,7 +328,7 @@ Stock forked Linux 5.15.1 in November 2021 and **never took a single subsequent stable release** before replacing it, on 2026-09-07, with 6.18.38 — pinned at that one point release in exactly the same way, so the pattern is the fork's, not 5.15's. This project tracks **6.18 LTS** — the exact patch level is -`BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE` in `configs/fragments/de10nano.fragment`, +`BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE` in `configs/mister_de10nano_defconfig`, and it is deliberately not repeated in prose here because stable `.y` releases land weekly. Pinned by version *and* SHA-256 against kernel.org, with Renovate opening a PR on every `.y` bump. @@ -637,7 +637,7 @@ shipped **byte-identical to stock's**, fetched by hash. `board/mister/de10nano/patches/bluez5_utils/` was deleted outright; and Buildroot **retired the 7.0 kernel-headers series**, which silently collapsed the DE25 toolchain from glibc to uClibc until the headers pin was moved to 7.1 (see - [`buildroot-config`](docs/buildroot-config.md) §6.2 and the fragment's own comment). + [`buildroot-config`](docs/buildroot-config.md) §6.2). The defconfig and `Makefile` pins are the ground truth; the prose is a dated reading of it. For the kernel this is handled by not writing the number down: narrative prose says "6.18 LTS", and `BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE` in the defconfig is the only @@ -650,21 +650,17 @@ shipped **byte-identical to stock's**, fetched by hash. ### Repository layout ``` -Makefile wrapper: fetches + hash-verifies Buildroot, forwards targets -Config.in / external.mk BR2_EXTERNAL definition for the 16 in-tree packages -configs/fragments/ stacks.mk (which fragments form which config) - common.fragment (policy shared by every board + variant) - de10nano.fragment (DE10 arch/ABI, headers, kernel stanza) - de10nano-image.fragment (the shipped image: hooks, ext4, packages) - kernel-only.fragment (kernel-only base, shared by variants) - de25nano.fragment (DE25-Nano developer OS, aarch64) - initramfs-common.fragment (stage-1 cpio: everything but the arch) - initramfs-de10nano.fragment / initramfs-de25nano.fragment - (stage-1 arch/ABI + headers, per board) - golden.sha256 (resolved-config hashes CI asserts) -configs/ mister_rt.fragment (PREEMPT_RT / 7.x delta) +Makefile thin wrapper (~100 lines): fetches + hash-verifies Buildroot, forwards everything else +Config.in / external.mk BR2_EXTERNAL definition for the 18 in-tree packages +configs/ mister_de10nano_defconfig (the DE10-Nano image -- Buildroot's own minimal form) + mister_de25nano_defconfig (the DE25-Nano developer OS, aarch64) mister_installer_defconfig (SD-card installer cpio) -> docs/buildroot-config.md has the rationale for every line +package/mister-userspace/ \ Kconfig PROFILES (ADR 0030): one symbol each that selects +package/mister-firmware/ > a documented package set, so both boards share it. This +package/mister-drivers/ / is the one departure from a plain Buildroot defconfig. +linux/ Config.ext.in + linux-ext-mister-initramfs.mk: the kernel + extension that embeds package/mister-initramfs's cpio (ADR 0002/0030) board/mister/de10nano/ linux.config minimal kernel defconfig (an absent CONFIG_X is NOT "off") linux-patches/ 37 carried patches: 36 MiSTer + 1 mainline backport (0047) @@ -688,13 +684,14 @@ RT must be a separately compiled kernel image. `PREEMPT_RT` for 32-bit ARM merge mainline in **Linux 7.1**, which means on 7.2 it is a plain kconfig option with **no out-of-tree RT patch to carry**. -The design ([ADR 0021](docs/decisions/0021-rt-kernel-first-class-ci.md)): `make rt` runs a -**kernel-only** Buildroot build into `output-rt/`, hard-asserting `CONFIG_PREEMPT_RT=y` in -the result, then stages its depmod'd module tree into an overlay that the next `make all` -folds into the **one shipped `linux.img`**. You get `zImage_dtb` and `zImage_dtb-rt` as -separate boot images, both of whose modules live in the same rootfs, selected on-device -via `u-boot.txt`. CI builds the variant on **every gated run**, so a PR that breaks -`make rt` goes red instead of rotting silently. +The design ([ADR 0021](docs/decisions/0021-rt-kernel-first-class-ci.md), as amended by +[ADR 0030](docs/decisions/0030-makefile-toward-vanilla-buildroot.md)): the RT kernel is +`package/linux-rt`, a **second kernel package inside the one build** (the same +`board/mister/de10nano/linux.config` plus `linux-rt.fragment`, the beta patch series, the same +embedded stage-1 initramfs). The package hard-asserts `CONFIG_PREEMPT_RT=y` in the configured +kernel, installs its module tree into the **one shipped `linux.img`** next to the main kernel's, +and emits `zImage_dtb-rt` and `linux-rt.config` into `output/images/`. One `make` produces both +kernels; there is no separate tree, overlay or ordering rule any more. `zImage_dtb-rt` is a **manual download** from the Release page — it is deliberately not on the `sdcard.img` installer payload and has no `db.json` entry, so no device is ever pushed @@ -792,35 +789,59 @@ inventoried against real mr-fusion output in ## Building it yourself +This is a plain Buildroot br2-external. The wrapper `Makefile` fetches and hash-verifies the +pinned Buildroot into `work/buildroot` and forwards everything else to it with `BR2_EXTERNAL` +and `O=` set, so the commands are the ones any Buildroot project uses: + ```sh -make # prints help — deliberately NOT a build -make de10nano-defconfig # generate output/.config from the fragment stack -make all # build (first run bootstraps a cross-toolchain — hours, not minutes) +make mister_de10nano_defconfig # configure the DE10-Nano image into output/ +make # build it (first run bootstraps a cross-toolchain — hours, not minutes) +make linux-menuconfig # or: menuconfig, linux-rt-menuconfig, legal-info, -rebuild, help ... +make O=output-de25 mister_de25nano_defconfig && make O=output-de25 # the DE25-Nano (or: make de25) +make sdcard # after make all: the SD-card installer image ``` -Two things that will bite you otherwise: +`make` produces `output/images/linux.img`, `zImage_dtb`, `zImage_dtb-rt` (the PREEMPT_RT +variant is a package of the same build) and `mister-initramfs.cpio` (the stage-1 initramfs, also +a package, embedded in both kernels). + +**The one thing that is not plain Buildroot:** package selection. `configs/mister_de10nano_defconfig` +does not list two hundred packages; it enables three Kconfig **profiles** — +`BR2_PACKAGE_MISTER_USERSPACE`, `_FIRMWARE`, `_DRIVERS` — whose `select` lists live in +`package/mister-*/Config.in`, grouped and commented the way [`docs/buildroot-config.md`](docs/buildroot-config.md) +§5 documents them. That is what lets the DE25-Nano share the userspace by enabling the same +symbols. "Why is package X in my image?" → `package/mister-userspace/Config.in`. + +Things that will bite you otherwise: -- **`make` on its own prints help rather than building.** A reflexive bare `make` in a - Buildroot tree with no config starts a full **x86** toolchain build that nothing here - wants. Use `make all` — it runs the stage-1 initramfs build first, then the image. - **Do not pass `-j`.** Buildroot's top level is not parallel-safe; it parallelises each - package internally, defaulting to your CPU count. CI runs a bare `make all`. + package internally, defaulting to your CPU count. CI runs a bare `make`. +- **The config is generated once and then left alone.** `make` never regenerates + `output/.config` (so `menuconfig` edits survive), and `make clean` keeps it. After a `git + pull` that moves the Buildroot pin (`BUILDROOT_VERSION` in the Makefile), or after a + `make clean`, run `make mister_de10nano_defconfig` again before building; a config written on + the previous pin stops Buildroot at an interactive Kconfig prompt. A pin move is best followed + by `make distclean`. +- **Edit the defconfig, then keep it canonical.** `configs/mister_*_defconfig` are Buildroot's + own `savedefconfig` form; `scripts/check-defconfigs.sh` (CI's lint) asserts each one loads, + reproduces itself, and that every profile `select` really lands — a `select` of a kconfig + `choice` member is ignored silently, which is why e.g. `BR2_PACKAGE_ZLIB_NG` stays in the + defconfig rather than in a profile. ### Useful targets | Target | What it does | |---|---| -| `make all` | The shipped image: `linux.img` + `zImage_dtb` | -| `make rt` | Kernel-only `PREEMPT_RT` build → `zImage_dtb-rt` + module overlay | -| `make sdcard` | Full `sdcard.img(.xz)` — run **after** `make all`. The card carries no variant kernel, so `make rt` is not required first; if you *do* build RT, run it before `make all` so its modules land in the image | -| `make initramfs` | Stage-1 cpio only, and print its size | -| `make de25-initramfs` | The same stage 1 built for aarch64 (`output-initramfs-de25/`), verified; boot-test it with `scripts/test-initramfs.sh --board de25nano` | -| `make menuconfig` / `linux-menuconfig` | Interactive Buildroot / kernel config | -| `make savedefconfig` | Write the config back to the defconfig (**always** do this after editing) | -| `make buildroot-verify` | Download + SHA-256-verify the pinned Buildroot tarball | -| `make buildroot-showsig` | Print upstream's GPG-signed manifest — the *only* valid hash source | -| `make legal-info` | Generate the SBOM | -| `make clean` / `distclean` | Buildroot's own meanings, applied across every output dir (`dl/` is kept — it's a shared cache) | +| `make` / `make all` | The shipped image: `linux.img`, `zImage_dtb`, `zImage_dtb-rt`, `mister-initramfs.cpio` | +| `make mister__defconfig` | Load a board configuration (Buildroot's own `_defconfig`) | +| `make linux-rt` | Rebuild only the `PREEMPT_RT` kernel package | +| `make mister-initramfs` | Rebuild only the stage-1 cpio (then `make linux-rebuild all` to re-embed it) | +| `make sdcard` | Full `sdcard.img(.xz)` — run **after** `make all` | +| `make menuconfig` / `linux-menuconfig` / `linux-rt-menuconfig` | Interactive Buildroot / kernel config | +| `make savedefconfig` | Write the config back to `configs/mister__defconfig` (**always** do this after editing) | +| `make buildroot-verify` / `buildroot-showsig` | Verify the pinned Buildroot tarball / print upstream's GPG-signed manifest — the *only* valid hash source | +| `make legal-info` | Generate the SBOM (covers both kernels and the stage-1 packages) | +| `make clean` / `distclean` | Buildroot's own meanings, per `O=`; `dl/` is kept (a shared cache) | ### Host requirements diff --git a/board/mister/common/initramfs-post-build.sh b/board/mister/common/initramfs-post-build.sh deleted file mode 100755 index 1de33549..00000000 --- a/board/mister/common/initramfs-post-build.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh -# -# initramfs-post-build.sh [args...] -# -# Stage-1 (initramfs) post-build hook. Runs after the cpio's target tree is -# assembled and before the cpio is generated (BR2_ROOTFS_POST_BUILD_SCRIPT in -# configs/fragments/initramfs-common.fragment). Reproducible: no timestamps, no -# randomness, no network -- it only deletes files (A9). -# -# WHY THIS EXISTS -- exfatprogs ships six binaries and /init calls one. -# -# BR2_PACKAGE_EXFATPROGS has no per-binary sub-options (its Config.in offers -# nothing but `depends on BR2_USE_WCHAR`), unlike dosfstools, whose .mk wraps -# each of FATLABEL/FSCK_FAT/MKFS_FAT in its own install guard. So the only way -# to take fsck.exfat without the other five is to delete them afterwards. -# -# This is not housekeeping. Every byte in this tree is a byte of zImage: the -# cpio is embedded via CONFIG_INITRAMFS_SOURCE and shares the 16 MiB U-Boot load -# budget that scripts/check-zimage-dtb.sh enforces. The five unused binaries are -# static musl ARM executables of 87-104 KB each once stripped -- 476,876 bytes -# measured on this toolchain, more than the entire rest of the cpio put together -# -- to ship five tools that nothing in stage 1 can invoke. (fsck.exfat, the one -# we keep, is 116,564; the whole cpio is 422,400 with it in.) Stage 1 has no -# shell user: it runs /init -# and switch_roots. mkfs.exfat in particular has no business being one `sh` -# typo away from the boot path of a device whose data partition is the thing it -# would reformat. (The full set does ship in the ROOTFS, where a user with a -# shell can reach it -- BR2_PACKAGE_EXFATPROGS in configs/fragments/de10nano-image.fragment.) -# -# KEEP THIS LIST IN STEP with what the initramfs /init actually invokes. The -# Makefile's `initramfs-verify` target asserts both directions against the built -# cpio -- fsck.exfat present, the deleted five absent -- so a drift here fails -# the build rather than silently shipping a bigger zImage or, worse, silently -# removing something /init needs. - -set -e - -TARGET_DIR="${1:?initramfs-post-build.sh: target dir argument missing}" - -# Everything exfatprogs installs EXCEPT fsck.exfat. Named individually rather -# than globbed so that a new binary in a future exfatprogs release is NOT -# silently deleted -- it shows up as unexpected cpio content in -# `initramfs-verify` and gets a deliberate decision. -for tool in dump.exfat exfat2img exfatlabel mkfs.exfat tune.exfat; do - rm -f "${TARGET_DIR}/usr/sbin/${tool}" "${TARGET_DIR}/sbin/${tool}" -done - -# fsck.exfat is the whole point of pulling the package in; if it is missing the -# repair path would be a silent no-op on every boot that requested it. -# -# Tests the EXACT path /init invokes ($FSCK_EXFAT, hardcoded absolute because the -# kernel hands /init no PATH) -- not "either usr/sbin or sbin". Accepting both -# would let this guard pass on a future exfatprogs that installs to /sbin while -# every requested repair silently became a no-op, which is the precise failure -# it exists to catch. Keep the two in step if either ever moves. -[ -x "${TARGET_DIR}/usr/sbin/fsck.exfat" ] || { - echo "FATAL: initramfs-post-build.sh: no ${TARGET_DIR}/usr/sbin/fsck.exfat." >&2 - echo " BR2_PACKAGE_EXFATPROGS is set in configs/fragments/initramfs-common.fragment," >&2 - echo " so the package moved its install path. The initramfs /init hardcodes" >&2 - echo " FSCK_EXFAT=/usr/sbin/fsck.exfat; update both together. See ADR 0026." >&2 - exit 1 -} diff --git a/board/mister/de10nano/patches/linux-rt b/board/mister/de10nano/patches/linux-rt new file mode 120000 index 00000000..39cc2456 --- /dev/null +++ b/board/mister/de10nano/patches/linux-rt @@ -0,0 +1 @@ +../linux-patches-beta \ No newline at end of file diff --git a/board/mister/de10nano/patches/linux/linux.hash b/board/mister/de10nano/patches/linux/linux.hash index a687542c..e3888e81 100644 --- a/board/mister/de10nano/patches/linux/linux.hash +++ b/board/mister/de10nano/patches/linux/linux.hash @@ -38,56 +38,8 @@ # the intended behaviour. sha256 d2fc041dab4e11d9645e3ba53be058faa52b8ce28a8a97c889bb2cacee170461 linux-6.18.50.tar.xz -# WHERE THE RT / BETA KERNEL HASH COMES FROM -- as of 2026-08-17, the SAME -# signed-manifest rule as the stable pin above. This entry belongs to the RT -# beta variant (configs/mister_rt.fragment, docs/rt-beta-kernel.md); it is a -# SECOND pin in this one file, on a different upstream line, and the two must -# never be confused for each other. -# -# THIS BLOCK USED TO DOCUMENT A TOFU HASH. It no longer does, and the change is -# an upgrade, not a relaxation. While the pin was an -rc, linux/linux.mk fetched -# a cgit-generated snapshot (linux-.tar.GZ from git.kernel.org/torvalds/t) -# for which kernel.org publishes NO signature of any kind -- sha256sums.asc -# covers releases only -- so the value could only ever be Trust-On-First-Use -# from a locally inspected download. 7.2 released on 2026-08-16; the pin moved -# to the plain release, the artifact became an ordinary linux-7.2.tar.XZ off the -# kernel.org mirror, and that file IS covered by the signed manifest: -# -# https://cdn.kernel.org/pub/linux/kernel/v7.x/sha256sums.asc -# -# Transcribed from that manifest, whose clearsign signature was VERIFIED (not -# merely fetched over HTTPS) on 2026-08-17: -# -# gpg: Signature made Sun Aug 16 23:35:10 2026 -# gpg: Good signature from "Kernel.org checksum autosigner " -# Primary key fingerprint: B886 8C80 BA62 A1FF FAF5 FDA9 632D 3A06 589D A6B1 -# -# Stated precisely, so nobody over-reads it: that is a valid signature by the -# kernel.org autosigner key, with the key itself trusted on first fetch from a -# keyserver rather than through a web of trust ("[unknown]" in gpg's output). -# It is strictly stronger than the TOFU it replaced, and is the same trust level -# the 6.18 pin above has always had. A pristine linux-7.2.tar.xz was downloaded -# and did hash to the value below (160,068,116 bytes; its top-level Makefile -# reads VERSION=7 PATCHLEVEL=2 SUBLEVEL=0 EXTRAVERSION=) -- that download -# CORROBORATES the signed value, it is not the source of it. Do not ever -# reverse those two roles; a locally-computed sha256sum as the SOURCE is -# circular and certifies nothing, exactly as the stable-pin rule above says. -# -# NOTE the deliberate spelling asymmetry, which reads like a typo and is not: -# the tarball is two-component (linux-7.2.tar.xz -- kernel.org publishes no -# linux-7.2.0 tarball), while the kernel it builds calls itself 7.2.0 and -# installs its modules under usr/lib/modules/7.2.0/. -# -# Still true, and still the reason a missing line here is fatal rather than a -# warning: BR2_DOWNLOAD_FORCE_CHECK_HASHES (kept, per G5) EMPTIES Buildroot's -# BR_NO_CHECK_HASH_FOR exemption list (package/pkg-download.mk:119), so a build -# with no line for the pinned version fails closed at the kernel download with -# "No hash found for linux-...". -# -# IF THIS PIN EVER GOES BACK TO AN -rc, this block's rule reverts with it: no -# signed manifest exists for a cgit snapshot, the filename becomes .tar.gz, and -# the value must be hand-written TOFU from an inspected local download. That is -# also the one case scripts/hash-sync-kernel.sh refuses to automate -- it -# declines any value containing "-rc" and leaves this line alone, so the build -# fails closed rather than blessing a snapshot nobody looked at. -sha256 01710ee01737dac492f1bae52becd057e08d20d11589089aa06accff415c28dd linux-7.2.4.tar.xz +# The RT / beta kernel's hash is NOT here any more: since ADR 0030 Phase C the +# variant is package/linux-rt and its tarball hash lives in +# package/linux-rt/linux-rt.hash (same rule: transcribed from kernel.org's +# signed v7.x manifest, never from a downloaded tarball; the -rc TOFU caveat +# documented there applies if that pin ever returns to an -rc). diff --git a/configs/fragments/common.fragment b/configs/fragments/common.fragment deleted file mode 100644 index 6e72b5f0..00000000 --- a/configs/fragments/common.fragment +++ /dev/null @@ -1,27 +0,0 @@ -# common.fragment — Buildroot policy shared by EVERY board and every kernel -# variant in this tree, including the kernel-only stack. Layered first; a -# later fragment must never redefine anything here -# (scripts/check-config-fragments.sh fails the build if one does). -# Rationale for every line, and why some "obviously shared" symbols are NOT -# here: docs/buildroot-config.md §2 and §10. - -# --- Toolchain: C++ (docs/buildroot-config.md §2.1) --- -BR2_TOOLCHAIN_BUILDROOT_CXX=y - -# --- Download integrity (docs/buildroot-config.md §2.2) --- -BR2_DOWNLOAD_FORCE_CHECK_HASHES=y - -# --- Kernel: pinned custom version, DTS support (docs/buildroot-config.md §2.3) --- -BR2_LINUX_KERNEL=y -BR2_LINUX_KERNEL_CUSTOM_VERSION=y -BR2_LINUX_KERNEL_DTS_SUPPORT=y - -# --- Reproducibility (docs/buildroot-config.md §2.4) --- -# WARNING: not cosmetic for the kernel-only stack either — linux.mk gates the -# KBUILD_BUILD_* stamps on it; without it a release re-run mints a different -# zImage_dtb-. Does NOT pin mke2fs's UUID/seed (§5.2 does, per image). -BR2_REPRODUCIBLE=y - -# --- Merged /usr (docs/buildroot-config.md §2.5) --- -# WARNING: load-bearing — Buildroot validates BR2_ROOTFS_OVERLAY's shape against it. -BR2_ROOTFS_MERGED_USR=y diff --git a/configs/fragments/de10nano-image.fragment b/configs/fragments/de10nano-image.fragment deleted file mode 100644 index 6fad0b2c..00000000 --- a/configs/fragments/de10nano-image.fragment +++ /dev/null @@ -1,418 +0,0 @@ -# de10nano-image.fragment — everything that makes the DE10-Nano stack the -# SHIPPED MiSTer image rather than a kernel-only build: board hooks, the -# ext4 linux.img contract, the full package set, and system configuration. -# Layered on common + de10nano (configs/fragments/stacks.mk). -# -# NOTHING in this file may touch the toolchain or the kernel stanza — those -# live in de10nano.fragment so the kernel-only stack shares them by -# construction (scripts/check-kernel-defconfig-sync.sh fails if a toolchain/ -# kernel family symbol appears here). Package selection is by design invisible -# to CI's toolchain-cache fingerprint (docs/ci.md#toolchain-fingerprint). -# -# The package list is docs/package-manifest.md §6 applied verbatim, plus the -# additions each section's doc entry records. Rationale for every line, with -# citations: docs/buildroot-config.md §5. Section numbers below refer to it. - -# --- Board hooks: post-build script, rootfs overlays (§5.1) --- -# WARNING: the SECOND overlay entry (work/extra-modules-overlay) is where -# kernel variants stage their module trees; `make all` mkdir -p's it because -# Buildroot hard-fails on a missing overlay path. Adding/changing this line -# busts the CI toolchain cache once (it is not BR2_PACKAGE_/BR2_LINUX_KERNEL). -BR2_ROOTFS_POST_BUILD_SCRIPT="../../board/mister/de10nano/post-build.sh" -BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/rootfs-overlay $(BR2_EXTERNAL_MISTER_PATH)/work/extra-modules-overlay" - -# --- Image generation: ext4 linux.img, reproducible (§5.2) --- -# WARNING: MKFS_OPTIONS pins the feature set, UUID, hash seed and block size -# explicitly — mke2fs defaults drift across e2fsprogs versions and the UUID/ -# seed are random otherwise. scripts/check-linux-img.sh asserts this contract. -# INODE_SIZE is an int symbol: no trailing comment allowed on that line. -BR2_TARGET_ROOTFS_EXT2=y -BR2_TARGET_ROOTFS_EXT2_4=y -BR2_TARGET_ROOTFS_EXT2_LABEL="rootfs" -BR2_TARGET_ROOTFS_EXT2_SIZE="512M" -BR2_TARGET_ROOTFS_EXT2_INODE_SIZE=256 -BR2_TARGET_ROOTFS_EXT2_MKFS_OPTIONS="-U 71916572-439f-448e-b8d8-12b0a032fa56 -E hash_seed=9afc615c-c310-4e03-ada9-613522e83ae6 -b 4096 -O has_journal,ext_attr,resize_inode,dir_index,filetype,extent,64bit,flex_bg,sparse_super,large_file,huge_file,dir_nlink,extra_isize,metadata_csum,^metadata_csum_seed,^orphan_file" - -################################################################################ -# P2.1 — Full package set (§5.3 for the preamble: manifest provenance, the -# imlib2 loader exception, BR2_ENABLE_LOCALE deliberately absent) -################################################################################ - -# --- compression (§5.4) --- -# WARNING: ZLIB_NG (zlib-ng in ZLIB_COMPAT mode) is the concrete zlib provider; -# MINIZIP is minizip-ng, MINIZIP_ZLIB is the classic zlib-contrib one — both. -BR2_PACKAGE_ZLIB=y -BR2_PACKAGE_ZLIB_NG=y -BR2_PACKAGE_BZIP2=y -BR2_PACKAGE_XZ=y -BR2_PACKAGE_LZO=y -BR2_PACKAGE_ZSTD=y -BR2_PACKAGE_MINIZIP=y -BR2_PACKAGE_MINIZIP_ZLIB=y - -# --- Main_MiSTer shared libs (§5.5, docs/main-shared-libs.md) --- -BR2_PACKAGE_LZMA_SDK=y -BR2_PACKAGE_LIBCHDR=y - -# --- graphics / fonts (§5.6) --- -# WARNING: the IMLIB2_* loaders are dlopen'd plugins — without them menu.png/ -# menu.jpg backgrounds silently fail to load with no DT_NEEDED signal. -BR2_PACKAGE_FREETYPE=y -BR2_PACKAGE_LIBPNG=y -BR2_PACKAGE_JPEG=y -BR2_PACKAGE_JPEG_TURBO=y -BR2_PACKAGE_TIFF=y -BR2_PACKAGE_GIFLIB=y -BR2_PACKAGE_IMLIB2=y -BR2_PACKAGE_IMLIB2_JPEG=y -BR2_PACKAGE_IMLIB2_PNG=y -BR2_PACKAGE_IMLIB2_GIF=y -BR2_PACKAGE_IMLIB2_TIFF=y -BR2_PACKAGE_IMLIB2_ID3=y -BR2_PACKAGE_LIBXKBCOMMON=y -BR2_PACKAGE_SDL2=y - -# --- audio (§5.7) --- -BR2_PACKAGE_ALSA_LIB=y -BR2_PACKAGE_LIBAO=y -BR2_PACKAGE_LIBVORBIS=y -BR2_PACKAGE_LIBOGG=y -BR2_PACKAGE_MPG123=y -BR2_PACKAGE_LIBID3TAG=y -BR2_PACKAGE_LIBMODPLUG=y -BR2_PACKAGE_FLUIDSYNTH=y -BR2_PACKAGE_FLUIDSYNTH_ALSA_LIB=y - -# --- MIDI / MT-32 (P3.8) + ALSA CLI tools (P3.15) (§5.8, docs/midi-mt32-parity.md) --- -BR2_PACKAGE_MUNT=y -BR2_PACKAGE_MIDILINK=y -BR2_PACKAGE_ALSA_UTILS=y -BR2_PACKAGE_ALSA_UTILS_ACONNECT=y -BR2_PACKAGE_ALSA_UTILS_AMIDI=y -BR2_PACKAGE_ALSA_UTILS_APLAYMIDI=y -BR2_PACKAGE_ALSA_UTILS_ARECORDMIDI=y -BR2_PACKAGE_ALSA_UTILS_ASEQDUMP=y -BR2_PACKAGE_ALSA_UTILS_ASEQNET=y -BR2_PACKAGE_ALSA_UTILS_ALSACTL=y -BR2_PACKAGE_ALSA_UTILS_ALSALOOP=y -BR2_PACKAGE_ALSA_UTILS_ALSAMIXER=y -BR2_PACKAGE_ALSA_UTILS_ALSATPLG=y -BR2_PACKAGE_ALSA_UTILS_ALSAUCM=y -BR2_PACKAGE_ALSA_UTILS_AMIXER=y -BR2_PACKAGE_ALSA_UTILS_APLAY=y -BR2_PACKAGE_ALSA_UTILS_BAT=y -BR2_PACKAGE_ALSA_UTILS_IECSET=y -BR2_PACKAGE_ALSA_UTILS_SPEAKER_TEST=y - -# --- crypto / TLS (§5.9) --- -# nettle/gmp/libtasn1/libgpg-error/libffi arrive transitively — do not set. -BR2_PACKAGE_OPENSSL=y -BR2_PACKAGE_LIBOPENSSL=y -BR2_PACKAGE_GNUTLS=y -BR2_PACKAGE_LIBGCRYPT=y -BR2_PACKAGE_LIBSSH2=y -BR2_PACKAGE_CA_CERTIFICATES=y - -# --- networking / D-Bus / GLib (§5.10) --- -# GNU wget (issue #130): the BusyBox applet is disabled in busybox.fragment. -BR2_PACKAGE_LIBCURL=y -BR2_PACKAGE_LIBCURL_CURL=y -BR2_PACKAGE_LIBCURL_OPENSSL=y -BR2_PACKAGE_WGET=y -BR2_PACKAGE_DBUS=y -BR2_PACKAGE_DBUS_CPP=y -BR2_PACKAGE_DBUS_GLIB=y -BR2_PACKAGE_LIBEVENT=y -BR2_PACKAGE_LIBNL=y -BR2_PACKAGE_IPTABLES=y -BR2_PACKAGE_LIBGLIB2=y -BR2_PACKAGE_GOBJECT_INTROSPECTION=y - -# --- util-linux / e2fsprogs / disk & fs tools (§5.11, docs/util-linux-parity.md) --- -# WARNING: each util-linux lib sub-option defaults to n — list them or the -# SONAME is not built. `raw` is deliberately absent (unbuildable on >=5.14). -BR2_PACKAGE_UTIL_LINUX=y -BR2_PACKAGE_UTIL_LINUX_LIBBLKID=y -BR2_PACKAGE_UTIL_LINUX_LIBFDISK=y -BR2_PACKAGE_UTIL_LINUX_LIBMOUNT=y -BR2_PACKAGE_UTIL_LINUX_LIBSMARTCOLS=y -BR2_PACKAGE_UTIL_LINUX_LIBUUID=y -BR2_PACKAGE_UTIL_LINUX_BINARIES=y -BR2_PACKAGE_UTIL_LINUX_MOUNT=y -BR2_PACKAGE_UTIL_LINUX_MOUNTPOINT=y -BR2_PACKAGE_UTIL_LINUX_AGETTY=y -BR2_PACKAGE_UTIL_LINUX_HWCLOCK=y -BR2_PACKAGE_UTIL_LINUX_FSCK=y -BR2_PACKAGE_UTIL_LINUX_PARTX=y -BR2_PACKAGE_UTIL_LINUX_SCHEDUTILS=y -BR2_PACKAGE_UTIL_LINUX_IRQTOP=y -BR2_PACKAGE_UTIL_LINUX_KILL=y -BR2_PACKAGE_UTIL_LINUX_MORE=y -BR2_PACKAGE_UTIL_LINUX_NEWGRP=y -BR2_PACKAGE_UTIL_LINUX_NOLOGIN=y -BR2_PACKAGE_UTIL_LINUX_RENAME=y -BR2_PACKAGE_UTIL_LINUX_SETTERM=y -BR2_PACKAGE_UTIL_LINUX_SWITCH_ROOT=y -BR2_PACKAGE_E2FSPROGS=y -BR2_PACKAGE_PARTED=y -BR2_PACKAGE_NTFS_3G=y -BR2_PACKAGE_NTFS_3G_NTFSPROGS=y -BR2_PACKAGE_KMOD=y -BR2_PACKAGE_INOTIFY_TOOLS=y -BR2_PACKAGE_JQ=y -BR2_PACKAGE_EXPAT=y -BR2_PACKAGE_POPT=y -BR2_PACKAGE_READLINE=y -BR2_PACKAGE_NCURSES=y -# WARNING: NCURSES_WCHAR is an ABI-contract fix (wide libncursesw.so.6, what -# stock ships); narrow -> wide is a clean-rebuild change. -BR2_PACKAGE_NCURSES_WCHAR=y -BR2_PACKAGE_SLANG=y -BR2_PACKAGE_NEWT=y -BR2_PACKAGE_GPM=y -BR2_PACKAGE_LIBARCHIVE=y -BR2_PACKAGE_LIBFUSE=y - -# --- USB / input (§5.12, docs/usb-automount-parity.md) --- -BR2_PACKAGE_LIBUSB=y -BR2_PACKAGE_LIBUSB_COMPAT=y -BR2_PACKAGE_LIBEVDEV=y -BR2_PACKAGE_LIBINPUT=y -BR2_PACKAGE_MTDEV=y -BR2_PACKAGE_USBMOUNT=y - -# --- Bluetooth (§5.13) --- -# WARNING: DEPRECATED depends on CLIENT || TOOLS — silently dropped without them. -BR2_PACKAGE_BLUEZ5_UTILS=y -BR2_PACKAGE_BLUEZ5_UTILS_CLIENT=y -BR2_PACKAGE_BLUEZ5_UTILS_TOOLS=y -BR2_PACKAGE_BLUEZ5_UTILS_DEPRECATED=y -BR2_PACKAGE_BLUEZ5_UTILS_PLUGINS_SIXAXIS=y - -# --- PAM / capabilities (§5.14) --- -BR2_PACKAGE_LINUX_PAM=y -BR2_PACKAGE_LIBCAP=y -BR2_PACKAGE_LIBCAP_NG=y - -# --- misc small libraries / tools (§5.15) --- -# WARNING: BUSYBOX_SHOW_OTHERS gates I2C_TOOLS and LSOF; the EUDEV device- -# creation choice gates EUDEV, LIBINPUT and BLUEZ5 SIXAXIS — kconfig drops all -# of them silently without these lines. -BR2_PACKAGE_DTC=y -BR2_PACKAGE_DTC_PROGRAMS=y -BR2_PACKAGE_SUDO=y -BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y -BR2_PACKAGE_I2C_TOOLS=y -BR2_PACKAGE_JIMTCL=y -BR2_PACKAGE_LIBLOCKFILE=y -BR2_PACKAGE_LIBXML2=y -BR2_PACKAGE_FILE=y -BR2_PACKAGE_MEMTOOL=y -BR2_PACKAGE_PCRE2=y -BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y -BR2_PACKAGE_EUDEV=y - -# --- lftp (§5.16) --- -BR2_PACKAGE_LFTP=y - -# --- Python (A6 / P3.9) + btctl runtime (§5.17, docs/python-compat.md) --- -# WARNING: SSL + ZLIB are hard blockers for Downloader_MiSTer. -BR2_PACKAGE_PYTHON3=y -BR2_PACKAGE_PYTHON3_SSL=y -BR2_PACKAGE_PYTHON3_ZLIB=y -BR2_PACKAGE_PYTHON3_BZIP2=y -BR2_PACKAGE_PYTHON3_XZ=y -BR2_PACKAGE_PYTHON3_PYEXPAT=y -BR2_PACKAGE_PYTHON3_READLINE=y -BR2_PACKAGE_PYTHON3_CURSES=y -BR2_PACKAGE_DBUS_PYTHON=y -BR2_PACKAGE_PYTHON_GOBJECT=y - -# --- Samba: standalone file server only (§5.18) --- -BR2_PACKAGE_SAMBA4=y - -# --- daemons / user-facing binaries (§5.19, docs/ssh-ftp-parity.md, docs/wifi-parity.md) --- -# WARNING: OPENSSH_SANDBOX must stay off — CONFIG_SECCOMP=n in our kernel and -# openssh >= 10.4 makes a failed seccomp setup FATAL for every connection. -# Configure-time flag: `make openssh-dirclean` before rebuilding after a change. -BR2_PACKAGE_OPENSSH=y -# BR2_PACKAGE_OPENSSH_SANDBOX is not set -BR2_PACKAGE_PROFTPD=y -BR2_PACKAGE_WPA_SUPPLICANT=y -BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y -BR2_PACKAGE_WPA_SUPPLICANT_WEXT=y -BR2_PACKAGE_WPA_SUPPLICANT_DEBUG_SYSLOG=y -BR2_PACKAGE_WPA_SUPPLICANT_WPA3=y -BR2_PACKAGE_WPA_SUPPLICANT_CLI=y -BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y -BR2_PACKAGE_BASH=y -# WARNING: BR2_SYSTEM_BIN_SH_BASH depends on BR2_PACKAGE_BUSYBOX_SHOW_OTHERS -# (§5.15 above); without it kconfig drops this line silently and /bin/sh falls -# back to BusyBox ash. Stock parity: Buildroot's skeleton finalize hook makes -# /bin/sh -> bash AND sets root's login shell to /bin/bash from this one symbol -# (issue #144; docs §5.19). -BR2_SYSTEM_BIN_SH_BASH=y -BR2_PACKAGE_DIALOG=y -BR2_PACKAGE_WIRELESS_TOOLS=y -BR2_PACKAGE_WIRELESS_TOOLS_IWCONFIG=y -BR2_PACKAGE_IW=y -BR2_PACKAGE_IPROUTE2=y - -# --- editors, ifupdown, BusyBox config fragment, dhcpcd, ntp, cifs (§5.20) --- -BR2_PACKAGE_JOE=y -BR2_PACKAGE_NANO=y -BR2_PACKAGE_IFUPDOWN=y -BR2_PACKAGE_BUSYBOX_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/busybox.fragment" -BR2_PACKAGE_DHCPCD=y -BR2_PACKAGE_NTP=y -BR2_PACKAGE_CIFS_UTILS=y - -# --- Midnight Commander (T3, §5.21) --- -BR2_PACKAGE_MC=y - -# --- NFS client userland (ADR 0022, §5.22) --- -# WARNING: RPC_NFSD is `default y` upstream and its LINUX_CONFIG_FIXUPS would -# flip CONFIG_NFSD on in our kernel — the not-set line is load-bearing. -BR2_PACKAGE_NFS_UTILS=y -BR2_PACKAGE_NFS_UTILS_NFSV4=y -# BR2_PACKAGE_NFS_UTILS_RPC_NFSD is not set -# BR2_PACKAGE_LVM2_STANDARD_INSTALL is not set - -# --- rsync, BusyBox (§5.23) --- -BR2_PACKAGE_RSYNC=y -BR2_PACKAGE_BUSYBOX=y - -# --- USB WiFi: mainline-first out-of-tree driver policy (§5.24, docs/wifi-parity.md) --- -# TWO out-of-tree USB WiFi drivers are on, and only these two. Both are for -# chips mainline cannot drive over USB at all; every other chip in this image -# is driven in-kernel, and enabling a fork alongside would bind-fight on the -# same USB IDs. -# -# The six `is not set` lines that used to live here (RTL8812AU, -# RTL8821AU_MORROWNR, RTL8188EU_AIRCRACK_NG, RTL8188FU, RTL8821CU_MORROWNR, -# RTL88X2BU) are gone because the packages themselves are gone -- mainline had -# caught up on all of them and they only generated Renovate noise. Removed -# 2026-09-10; see Config.in and docs/wifi-parity.md §11. -BR2_PACKAGE_RTL8852CU_MORROWNR=y -# AIC8800: Wi-Fi 6 + BT, driver AND ~6.6 MiB of firmware. DE10-only on -# purpose -- it is not in image-common (which both boards' image stacks pull -# in) because the module has only been built and verified for 32-bit ARM. The -# DE25 is aarch64 and would be building it untested. See docs/wifi-parity.md -# §10 for what a DE25 enablement would have to show first. -BR2_PACKAGE_AIC8800=y - -# --- xone: Xbox One/Series accessory driver + dongle firmware (P3.2, ADR 0003, §5.25) --- -BR2_PACKAGE_XONE=y -BR2_PACKAGE_XOW_FIRMWARE=y - -# --- dualsensectl (§5.26, docs/dualsense-tooling.md) --- -# NOTE: pulls BR2_TOOLCHAIN_GLIBC_GCONV_LIBS_COPY on via hidapi — deliberate -# (stock ships gconv); scripts/ci-tests.sh asserts the modules are present. -BR2_PACKAGE_DUALSENSECTL=y - -# --- ltunify: Logitech Unifying pairing (§5.27, docs/logitech-pairing.md) --- -BR2_PACKAGE_LTUNIFY=y - -# --- /lib/firmware population: MOVED to image-common.fragment (§12.1) — the -# blob set is shared by BOTH boards' image stacks (§10, §12) — a note, no config --- - -# --- explicitly NOT carried forward: manifest §5 Drop list (§5.29) — a note, no config --- - -# --- kmod: target tools (§5.30; the HOST xz half is in de10nano.fragment) --- -BR2_PACKAGE_KMOD_TOOLS=y - -################################################################################ -# T5 — utility binaries stock ships (2026-07-27). Preamble, rejected list -# (perl, vim, screen, gdb, ltrace, unrar): §5.31. -################################################################################ - -# --- T5: process / file / syscall inspection (§5.32) --- -BR2_PACKAGE_HTOP=y -BR2_PACKAGE_STRACE=y -BR2_PACKAGE_LSOF=y - -# --- T5: USB / input / joystick & force-feedback (§5.33) --- -BR2_PACKAGE_USBUTILS=y -BR2_PACKAGE_EVTEST=y -BR2_PACKAGE_LINUXCONSOLETOOLS=y -BR2_PACKAGE_LINUXCONSOLETOOLS_JOYSTICK=y -BR2_PACKAGE_LINUXCONSOLETOOLS_FORCEFEEDBACK=y - -# --- T5: filesystem tools, FAT/exFAT (§5.34) --- -# WARNING: dosfstools' three programs each default to n — all three needed. -BR2_PACKAGE_DOSFSTOOLS=y -BR2_PACKAGE_DOSFSTOOLS_FATLABEL=y -BR2_PACKAGE_DOSFSTOOLS_FSCK_FAT=y -BR2_PACKAGE_DOSFSTOOLS_MKFS_FAT=y -BR2_PACKAGE_EXFATPROGS=y - -# --- T5: serial / terminal (§5.35) --- -BR2_PACKAGE_PICOCOM=y -BR2_PACKAGE_LRZSZ=y -BR2_PACKAGE_TMUX=y - -# --- T5: network diagnostics (§5.36) --- -BR2_PACKAGE_ETHTOOL=y -BR2_PACKAGE_SOCAT=y -BR2_PACKAGE_TCPDUMP=y -BR2_PACKAGE_IPERF3=y - -# --- T5: archival — package/7zip (OURS), not upstream p7zip (ADR 0023, §5.37) --- -BR2_PACKAGE_7ZIP=y -BR2_PACKAGE_ZIP=y -BR2_PACKAGE_LZOP=y - -# --- Off-device backup: azcopy — packaged, NOT enabled, size only (§5.38, docs/azcopy.md) --- -# BR2_PACKAGE_AZCOPY is not set - -# --- T5: hardware buses (§5.39) --- -BR2_PACKAGE_SPI_TOOLS=y - -# --- T5: Bluetooth CLI (§5.40) --- -BR2_PACKAGE_BLUEZ_TOOLS=y - -# --- T5: console / keyboard (§5.41) --- -BR2_PACKAGE_KBD=y - -################################################################################ -# >>> DEBUG TOOLING — TEMPORARY, REMOVE AS ONE BLOCK <<< (§5.42, docs/debug-tooling.md) -# TO REVERT: delete this block (banner to banner) and the matching -# CONFIG_COREDUMP block in board/mister/de10nano/linux.config, then -# make de10nano-defconfig && make all -# WARNING: do not add numactl/mpfr lines here — they arrive by select and must -# disappear with this block. GDB_SERVER must stay explicit next to GDB_DEBUGGER. -# strace is NOT in this block any more: T5 (§5.32) made it permanent, and a -# second BR2_PACKAGE_STRACE=y line here would be a redefinition -# check-config-fragments.sh rejects. -################################################################################ -BR2_PACKAGE_GDB=y -BR2_PACKAGE_GDB_SERVER=y -BR2_PACKAGE_GDB_DEBUGGER=y -BR2_PACKAGE_LINUX_TOOLS_PERF=y -BR2_PACKAGE_LINUX_TOOLS_PERF_NEEDS_HOST_PYTHON3=y -BR2_PACKAGE_RT_TESTS=y -################################################################################ -# >>> END DEBUG TOOLING <<< -################################################################################ - -################################################################################ -# System configuration (§5.43) — the System configuration menu, NOT the -# toolchain menu (so no from-scratch-rebuild hazard). Merged /usr lives in -# common.fragment. -################################################################################ - -# --- root password: empty = passwordless root, matching stock (§5.43, ADR 0015) --- -BR2_TARGET_GENERIC_ROOT_PASSWD="" - -# --- locale data (§5.44) --- -# WARNING: BR2_ENABLE_LOCALE (toolchain menu, already y) only compiles locale -# SUPPORT; this line GENERATES the data — empty shipped no /usr/lib/locale. -BR2_GENERATE_LOCALE="en_US.UTF-8" - -# --- timezone / tzdata (§5.45) --- -# WARNING: BR2_TARGET_LOCALTIME installs /etc/localtime as a symlink into -# zoneinfo — the rootfs-overlay overwrites it to point at the FAT data -# partition, which is the only thing that survives a reflash (ADR 0025). -BR2_TARGET_TZ_INFO=y -BR2_TARGET_TZ_ZONELIST="default" -BR2_TARGET_LOCALTIME="Etc/UTC" diff --git a/configs/fragments/de10nano.fragment b/configs/fragments/de10nano.fragment deleted file mode 100644 index 8225756a..00000000 --- a/configs/fragments/de10nano.fragment +++ /dev/null @@ -1,43 +0,0 @@ -# de10nano.fragment — the DE10-Nano BOARD layer: arch/ABI, toolchain headers -# series, and the kernel stanza. Shared by the full image stack -# (+ de10nano-image) and the kernel-only stack (+ kernel-only) — see -# configs/fragments/stacks.mk. Everything a kernel variant must agree with -# the shipped image on lives HERE and nowhere else. -# Rationale for every line: docs/buildroot-config.md §3. - -# --- Arch / ABI: armv7-a Cortex-A9, NEON + VFPv3, EABIhf (docs/buildroot-config.md §3.1) --- -BR2_arm=y -BR2_cortex_a9=y -BR2_ARM_ENABLE_NEON=y -BR2_ARM_ENABLE_VFP=y -BR2_ARM_FPU_NEON=y - -# --- Kernel headers SERIES (docs/buildroot-config.md §3.2) --- -# WARNING: do NOT "fix" this to BR2_KERNEL_HEADERS_AS_KERNEL — that silently -# drops glibc's --enable-kernel floor to 2.6. Re-diff include/uapi on ANY -# kernel or Buildroot bump (a Buildroot bump moves the series' point release). -BR2_KERNEL_HEADERS_6_18=y - -# --- Global patch dir = the kernel-tarball hash registry (docs/buildroot-config.md §3.3) --- -# WARNING: load-bearing even with no packages — it is where Buildroot finds -# patches/linux/linux.hash, the ONLY thing that hash-verifies the pinned -# kernel tarball; kernel-only variants need it too. -BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/patches" - -# --- Kernel stanza (docs/buildroot-config.md §3.4) --- -# Renovate bumps the version line (renovate.json, kernel-longterm-6.18); -# the tarball hash follows via .github/workflows/renovate-hash-sync.yml. -BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.50" -BR2_LINUX_KERNEL_PATCH="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/linux-patches" -BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y -BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/linux.config" -BR2_LINUX_KERNEL_LZ4=y -BR2_LINUX_KERNEL_ZIMAGE=y -BR2_LINUX_KERNEL_INTREE_DTS_NAME="intel/socfpga/socfpga_cyclone5_de10nano" - -# --- Host kmod with xz: build-time depmod must read .ko.xz (docs/buildroot-config.md §3.5) --- -BR2_PACKAGE_HOST_KMOD_XZ=y - -# --- Post-image: zImage_dtb assembly + contract check (docs/buildroot-config.md §3.6) --- -# Path is relative to work/buildroot/ (post-image scripts run from there). -BR2_ROOTFS_POST_IMAGE_SCRIPT="../../board/mister/de10nano/post-image.sh" diff --git a/configs/fragments/de25nano.fragment b/configs/fragments/de25nano.fragment deleted file mode 100644 index b926e30e..00000000 --- a/configs/fragments/de25nano.fragment +++ /dev/null @@ -1,152 +0,0 @@ -# de25nano.fragment — D2.1: a BARE DEVELOPER OS for the Terasic DE25-Nano -# (Intel/Altera Agilex 5, HPS = 2x Cortex-A76 + 2x Cortex-A55, aarch64). -# NO MiSTer packages, NO DE10 packages — that is the accepted release scope -# (ADR 0027 Decision 6, ADR 0029, docs/de25-nano-tasks.md D2.7), not a gap. -# The ONE package set this board shares with the DE10 image is the /lib/firmware -# blob set, and it is NOT listed here: the stack is `common de25nano -# image-common` (configs/fragments/stacks.mk, DE25NANO_FRAGMENTS) and -# image-common.fragment carries that selection once for both boards (owner -# decision 2026-09-03, docs/buildroot-config.md §12; the shared kernel fragment -# below already builds the Wi-Fi/Bluetooth drivers that ask for those blobs). -# No BR2_ symbol here is shared with the DE10 stacks except through those two -# shared layers. Two FILES are shared by path — the kernel-tarball hash registry -# (§6.3) and the MiSTer kernel-config fragment (§6.5) — each says so at its line. -# Rationale for every line: docs/buildroot-config.md §6. - -# --- Architecture & toolchain (docs/buildroot-config.md §6.2) --- -# WARNING: BR2_cortex_a76_a55 is the big.LITTLE tuning tuple — do NOT -# "simplify" it to BR2_cortex_a76. No NEON/VFP knobs exist on AArch64. -BR2_aarch64=y -BR2_cortex_a76_a55=y -# WARNING: headers SERIES pin, same trap as the DE10's (§3.2). 7_1 is the -# newest series Buildroot 2026.08 offers below our 7.2 kernel; re-check on -# every Buildroot bump and move to a 7.2 series the day one exists. -# -# WAS 7_0 UNTIL THE 2026.08 BUMP, and the way it broke is the reason this -# WARNING exists. Buildroot 2026.08 REMOVED the 7.0 series outright -- it is -# now a Config.in.legacy stub ("kernel headers version 7.0.x are no longer -# supported", selecting BR2_LEGACY). A retired symbol does not error out at -# merge time: `BR2_KERNEL_HEADERS_7_0=y` still SET fine, so -# check-config-fragments' (b) "every fragment symbol survives" assertion still -# passed with 0 dropped -- the literal line really was in the resolved config. -# What silently collapsed was everything downstream of it: the headers choice -# fell back to BR2_KERNEL_HEADERS_AS_KERNEL, and with it the libc choice fell -# from glibc to uClibc. The GOLDEN HASH is what caught it, which is exactly the -# backstop it exists to be. If you ever see BR2_TOOLCHAIN_USES_UCLIBC in a -# resolved DE25 config, look here first. -BR2_KERNEL_HEADERS_7_1=y - -# --- Download integrity (docs/buildroot-config.md §6.3) --- -# WARNING: patches/linux/linux.hash here is a SYMLINK to the DE10's hash -# registry — bumping the kernel below means editing that de10nano file. -BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/patches" - -# --- Kernel: mainline 7.2.3 (docs/buildroot-config.md §6.4) --- -# WARNING: do NOT point PATCH at the DE10's linux-patches/ — 4 of the 40 differ -# in content between the DE10's main and beta series alone, and none has been -# compile-tested on aarch64/7.2; this directory takes only what D0.3 triaged. -BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="7.2.3" -BR2_LINUX_KERNEL_PATCH="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/linux-patches" - -# --- Kernel config = pinned minimal base + shared MiSTer fragment; Image; board DTS (docs/buildroot-config.md §6.5) --- -# WARNING: USE_CUSTOM_CONFIG, not USE_DEFCONFIG (that one would build -# `defconfig_defconfig`). No stage-1 initramfs on this board by design. -# WARNING: the wave-1 arm64-`defconfig` base is stated OFF, not just dropped, so -# the change of shape is visible here rather than inferable from an absence. -# WARNING: the fragment file is SHARED WITH THE DE10 BY PATH and must stay a -# no-op against the DE10's resolved config — scripts/check-kernel-fragment-noop.sh. -# BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG is not set -BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y -BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/linux.config" -BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/common/linux-mister.fragment" -# WARNING: the shared fragment sets CONFIG_MODULE_COMPRESS_XZ, so build-time -# depmod needs host kmod built with xz or it silently ships an EMPTY -# modules.dep (0 lines; found on the first wave-2 card). Same trap as the -# DE10 -- docs/buildroot-config.md §3.5. -BR2_PACKAGE_HOST_KMOD_XZ=y -BR2_LINUX_KERNEL_IMAGE=y -BR2_LINUX_KERNEL_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/socfpga_agilex5_de25nano.dts" - -# --- Root filesystem: plain ext4, 256 MiB (docs/buildroot-config.md §6.6) --- -# MEASURED 2026-09-03, with image-common's ~52 MiB of firmware installed: -# 85.6 MiB used of 256 MiB (33%), 170 MiB free. No bump needed; the headroom is -# the point of the number, so it is not trimmed to fit either. -BR2_TARGET_ROOTFS_EXT2=y -BR2_TARGET_ROOTFS_EXT2_4=y -BR2_TARGET_ROOTFS_EXT2_LABEL="rootfs" -BR2_TARGET_ROOTFS_EXT2_SIZE="256M" - -# --- System configuration (docs/buildroot-config.md §6.7) --- -# WARNING: the console is HPS uart1 = ttyS0 at 115200 8N1; wrong values here -# make the board look dead. -BR2_TARGET_GENERIC_GETTY_PORT="ttyS0" -BR2_TARGET_GENERIC_GETTY_BAUDRATE_115200=y -BR2_TARGET_GENERIC_HOSTNAME="de25" -BR2_TARGET_GENERIC_ISSUE="Welcome to MiSTer DE25-Nano (developer OS)" -# Empty = passwordless root; on this board the only way in (no SSH keys yet). -BR2_TARGET_GENERIC_ROOT_PASSWD="" - -# --- Packages: none beyond the shared firmware set (docs/buildroot-config.md §6.8) --- -# The /lib/firmware blobs come from image-common.fragment (§12); nothing else -# is enabled here, and adding something needs a task that authorises it. -# WARNING: the day BR2_PACKAGE_OPENSSH=y is added here it must be added -# TOGETHER WITH `# BR2_PACKAGE_OPENSSH_SANDBOX is not set` — this board's -# linux.config has no CONFIG_SECCOMP, and openssh's sandbox is `default y`, -# which yields an sshd that listens and kills every connection preauth -# (docs/buildroot-config.md §6.8, docs/de25-kernel-config.md). - -# --- Bootloader: ATF BL31 + mainline U-Boot -> u-boot.itb (docs/buildroot-config.md §6.9) --- -# WARNING: TF-A v2.15.0 and U-Boot 2026.07 are CUSTOM versions because -# Buildroot 2026.05.2 offers neither an Agilex 5 TF-A platform nor a new enough -# U-Boot. BUILD_SYSTEM_KCONFIG is NOT optional on a custom version — it -# defaults to KCONFIG only under BR2_TARGET_UBOOT_LATEST_VERSION. -BR2_TARGET_ARM_TRUSTED_FIRMWARE=y -BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y -BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE="v2.15.0" -BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="agilex5" -BR2_TARGET_ARM_TRUSTED_FIRMWARE_BL31=y -BR2_TARGET_ARM_TRUSTED_FIRMWARE_IMAGES="bl31.bin" -BR2_TARGET_UBOOT=y -BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y -BR2_TARGET_UBOOT_CUSTOM_VERSION=y -BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2026.07" -BR2_TARGET_UBOOT_USE_DEFCONFIG=y -BR2_TARGET_UBOOT_BOARD_DEFCONFIG="socfpga_agilex5" -# WARNING: the whole U-Boot delta — including the traps that keep a QSPI write -# structurally impossible (CONFIG_ENV_IS_IN_UBI off) and the factory SPL's -# bloblist out of our dram_init (CONFIG_HANDOFF / CONFIG_BLOBLIST off) — lives -# in uboot.fragment, line by line. Read it before touching this stanza. -BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/uboot.fragment" -# WARNING: both files travel together — U-Boot auto-includes the -u-boot.dtsi -# BY NAME, and the U-Boot board file shares a basename with the KERNEL board -# file, which is why they live in uboot-dts/ and not beside it. -BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/uboot-dts/socfpga_agilex5_de25nano.dts $(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/uboot-dts/socfpga_agilex5_de25nano-u-boot.dtsi" -BR2_TARGET_UBOOT_NEEDS_ATF_BL31=y -BR2_TARGET_UBOOT_NEEDS_ATF_BL31_BIN=y -BR2_TARGET_UBOOT_USE_BINMAN=y -BR2_TARGET_UBOOT_NEEDS_OPENSSL=y -# WARNING: NO SPL IS SHIPPED (no BR2_TARGET_UBOOT_SPL). The FSBL is the factory -# U-Boot SPL in QSPI and is NEVER touched — posture 1, brick-class. The SPL is -# nevertheless COMPILED, because `select BINMAN if SPL_ATF` is the only thing -# that turns BINMAN on and BINMAN is what produces u-boot.itb. -BR2_TARGET_UBOOT_FORMAT_ITB=y -# FORMAT_BIN is `default y`; off so images/ holds only what goes on the card. -# BR2_TARGET_UBOOT_FORMAT_BIN is not set - -# --- Host tools: dumpimage/mkimage, WITH FIT support (docs/buildroot-config.md §6.10) --- -# WARNING: FIT_SUPPORT is NOT `default y`, and without it `dumpimage -l -# u-boot.itb` prints nothing and exits 0 — a verification step that always -# passes. Found the hard way on the first build. -BR2_PACKAGE_HOST_UBOOT_TOOLS=y -BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y - -# --- SD-card image: p1 FAT32 + p2 ext4, assembled by post-image.sh (docs/buildroot-config.md §6.11) --- -# WARNING: host-genimage pulls in NEITHER mtools NOR dosfstools, and genimage's -# vfat handler shells out to `mcopy`/`mkdosfs` by name — without these two the -# card build fails inside genimage, not at configure time. -BR2_PACKAGE_HOST_GENIMAGE=y -BR2_PACKAGE_HOST_MTOOLS=y -BR2_PACKAGE_HOST_DOSFSTOOLS=y -# WARNING: fails the build when images/u-boot.itb is missing, BY DESIGN; -# DE25_ALLOW_NO_UBOOT=1 in the environment downgrades it to a loud skip. -BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/post-image.sh" diff --git a/configs/fragments/golden.sha256 b/configs/fragments/golden.sha256 deleted file mode 100644 index db554e5c..00000000 --- a/configs/fragments/golden.sha256 +++ /dev/null @@ -1,16 +0,0 @@ -# configs/fragments/golden.sha256 — sha256 of each stack's NORMALISED resolved -# .config for the pinned Buildroot version (scripts/check-config-fragments.sh -# (d); docs/buildroot-config.md §11). Regenerate ONLY with -# scripts/check-config-fragments.sh --update-golden -# and say in the commit message what changed and why. Columns: -# -2026.08 de10nano 9e37484a5c419b546cf8739ca1b2f2dcc181317f7af4eed5493c54d03c223e83 -2026.08 de10nano-kernel b69db3e12782bfede48587acbb9549a0f2ef794acb6b8a41d5c95bc112a91104 -2026.08 de25nano 68cc9ed6191e9539098c8307a6f470830c70a8f640ef37e05379c1b96e6b6e88 -2026.08 initramfs-de10nano 0dd82cead720b3ef2a9ce7d0359bced7c49494d5e9e5d278b515ddb071a743c6 -2026.08 initramfs-de25nano cd36760dde544017258c4ce964785361fc367f1b024d645ec90e58e66d6ff14a -2026.08 rt 103e68329df556920a06b736bcbafcad3913ce3ce49ef75f448df2797465ad95 -2026.05.2 de10nano 251ae321011945e690a32f2fbb704b619681fd26d06acf578f7691e76286f992 -2026.05.2 de10nano-kernel 5b372abe43c46c4eb5f3c88d51e48ff2eb6fa713b3c02f0f337c39d0f111dc69 -2026.05.2 de25nano 714728e0bd12e3fb6f86a0b932c204a1acae642a9aba3d0770501bc6b3d7952a -2026.05.2 rt e34a522a56eb088ac84b1e6db7350a22f12293d0d84086dbf1f405f68a58b7e5 diff --git a/configs/fragments/image-common.fragment b/configs/fragments/image-common.fragment deleted file mode 100644 index 37bb1ab6..00000000 --- a/configs/fragments/image-common.fragment +++ /dev/null @@ -1,61 +0,0 @@ -# image-common.fragment — the package set every board's SHIPPED IMAGE gets, -# whatever its architecture. Arch-neutral by construction: nothing here may -# name a CPU, an ABI, a board directory, a MiSTer binary or an out-of-tree -# driver for hardware only one board can host. -# -# In the IMAGE stack of every board (configs/fragments/stacks.mk: -# DE10NANO_FRAGMENTS and DE25NANO_FRAGMENTS) and in the kernel-only stack of -# none of them — that is the whole point of the fragment, and the reason it is -# not `common`: `common` IS in the kernel-only stack, so a package line there -# would spend a ~557 MiB fetch and ~52 MiB of install, on every kernel leg, on -# blobs that land in a rootfs.tar which ships nothing but modules and is then -# thrown away — and would move that stack's dl-cache key, which hashes -# common.fragment (docs/buildroot-config.md §10, its rule 6 and the firmware -# row; the toolchain fingerprint is the one key a BR2_PACKAGE_ line cannot -# move — it denies that prefix). It is equally not per-board: parity between -# the boards is exactly what this fragment makes structural, not remembered. -# -# THIS IS THE HOME FOR THE SHARED PACKAGE SET AS THE DE25 GROWS. A package -# both images want moves de10nano-image.fragment -> here, in a commit that -# shows the de10nano golden hash did NOT move (the resolved config is the -# same, only differently filed) and the de25nano one did. What must NOT come -# here: anything DE10-specific, and anything the DE25's bare-developer-OS -# scope has not taken (ADR 0027 Decision 6 / ADR 0029 — §10 rule 5 still -# applies; an owner decision per package, not a refactor's side effect). -# -# Rationale for every line: docs/buildroot-config.md §12. - -# --- /lib/firmware population (P3.3, §12.1, docs/firmware-parity.md) --- -# WARNING: changing linux-firmware SUB-options on an incremental build installs -# nothing (Buildroot stamping) — `make linux-firmware-dirclean` first. -BR2_PACKAGE_LINUX_FIRMWARE=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7610E=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7650=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT76X2E=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7921=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7925=y -BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT2XX=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_81XX=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_88XX_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW88=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW89=y -BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_9271=y -BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_7010=y -BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_9170=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7921_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7922_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7925_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_QUALCOMM_6174A_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_6004=y -BR2_PACKAGE_LINUX_FIRMWARE_REDPINE_RS9113=y -BR2_PACKAGE_LINUX_FIRMWARE_REDPINE_RS9116=y -BR2_PACKAGE_LINUX_FIRMWARE_AR3011=y -BR2_PACKAGE_LINUX_FIRMWARE_AR3012_USB=y -BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XX=y -BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XXX=y -BR2_PACKAGE_WIRELESS_REGDB=y -BR2_PACKAGE_LINUX_FIRMWARE_EXTRA=y -BR2_PACKAGE_BCM20702_FIRMWARE=y diff --git a/configs/fragments/initramfs-common.fragment b/configs/fragments/initramfs-common.fragment deleted file mode 100644 index cf7a0c6a..00000000 --- a/configs/fragments/initramfs-common.fragment +++ /dev/null @@ -1,41 +0,0 @@ -# initramfs-common.fragment — STAGE 1 of the two-stage build, the part every -# board shares (TASKS.md P1.10 / A1, PLAN.md §5, docs/decisions/0002-initramfs.md). -# Builds ONE artifact per board: output-initramfs*/images/rootfs.cpio, a few -# hundred KB of static musl BusyBox plus the arch-neutral /init in -# board/mister/common/initramfs-overlay, which external.mk embeds into the -# board's kernel. The arch/ABI and headers-series lines are the ONLY -# per-board part and live in initramfs-.fragment; the stacks are -# `initramfs-common initramfs-` (configs/fragments/stacks.mk). -# Rationale for every line: docs/buildroot-config.md §8. -# -# WARNING: NEVER set BR2_TARGET_ROOTFS_INITRAMFS in a board's IMAGE stack to -# do this — that embeds the entire target rootfs into the kernel (trap A1). - -# --- Toolchain: musl, static-only (§8.2). The headers series is per-board. --- -BR2_TOOLCHAIN_BUILDROOT_MUSL=y -BR2_STATIC_LIBS=y - -# --- No init system: the kernel execs /init from the cpio (§8.3) --- -BR2_INIT_NONE=y - -# --- Device nodes: dynamic/devtmpfs (§8.4) --- -# WARNING: STATIC would leave /dev/console out of the cpio (no stdio for /init). -BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_DEVTMPFS=y - -# --- BusyBox: our own minimal config; /init via the overlay (§8.5) --- -# Both under board/mister/common: one /init, one BusyBox config, every board. -BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/common/initramfs-busybox.config" -BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/common/initramfs-overlay" - -# --- fsck.exfat for the on-demand repair path, ADR 0026 (§8.6) --- -BR2_PACKAGE_EXFATPROGS=y -BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/common/initramfs-post-build.sh" - -# --- Output: a cpio, uncompressed (§8.7) --- -BR2_TARGET_ROOTFS_CPIO=y -# BR2_TARGET_ROOTFS_TAR is not set - -# --- Reproducibility, A9 (§8.8) --- -# Restated here rather than taken from common.fragment: `common` carries -# BR2_LINUX_KERNEL=y, and a stage-1 stack must build no kernel. -BR2_REPRODUCIBLE=y diff --git a/configs/fragments/initramfs-de10nano.fragment b/configs/fragments/initramfs-de10nano.fragment deleted file mode 100644 index b03096d3..00000000 --- a/configs/fragments/initramfs-de10nano.fragment +++ /dev/null @@ -1,19 +0,0 @@ -# initramfs-de10nano.fragment — the DE10-Nano's arch/ABI + headers-series -# lines for the stage-1 initramfs stack (`initramfs-common initramfs-de10nano`, -# configs/fragments/stacks.mk). Rationale: docs/buildroot-config.md §8.1, §8.2. -# -# WARNING: these values must match de10nano.fragment's (§3.1, §3.2) — the cpio -# runs on the same silicon the kernel it is embedded in was built for. -# scripts/check-config-fragments.sh (f) asserts the two files agree, symbol by -# symbol, so a CPU-tuning or headers-series change in one and not the other -# fails CI instead of shipping a mismatched stage 1. - -# --- Arch/ABI: same silicon as the main build (§8.1) --- -BR2_arm=y -BR2_cortex_a9=y -BR2_ARM_ENABLE_NEON=y -BR2_ARM_ENABLE_VFP=y -BR2_ARM_FPU_NEON=y - -# --- Kernel headers SERIES (§8.2 -> §3.2) --- -BR2_KERNEL_HEADERS_6_18=y diff --git a/configs/fragments/initramfs-de25nano.fragment b/configs/fragments/initramfs-de25nano.fragment deleted file mode 100644 index 843f0fa6..00000000 --- a/configs/fragments/initramfs-de25nano.fragment +++ /dev/null @@ -1,19 +0,0 @@ -# initramfs-de25nano.fragment — the DE25-Nano's arch/ABI + headers-series -# lines for the stage-1 initramfs stack (`initramfs-common initramfs-de25nano`, -# configs/fragments/stacks.mk). Rationale: docs/buildroot-config.md §8.1, §8.2. -# -# WARNING: these values must match de25nano.fragment's (§6.2) — same -# check-config-fragments (f) lockstep as the DE10's file. No NEON/VFP knobs -# exist on AArch64, which is why this file is three lines to the DE10's six. -# The cpio this stack builds is NOT yet embedded in the DE25 kernel: the -# shipped card keeps ADR 0029 D11's interim plain-ext4 shape until hardware, -# and external.mk's embedding fixup still keys on BR2_arm. What this stack -# gives is the aarch64 stage 1 built, verified and QEMU-proven ahead of the -# switch (docs/de25-sdcard.md §2). - -# --- Arch/ABI: same silicon as the DE25 image build (§8.1 -> §6.2) --- -BR2_aarch64=y -BR2_cortex_a76_a55=y - -# --- Kernel headers SERIES (§8.2 -> §6.2) --- -BR2_KERNEL_HEADERS_7_1=y diff --git a/configs/fragments/kernel-only.fragment b/configs/fragments/kernel-only.fragment deleted file mode 100644 index 22ebcd03..00000000 --- a/configs/fragments/kernel-only.fragment +++ /dev/null @@ -1,17 +0,0 @@ -# kernel-only.fragment — turns a board stack into the KERNEL-ONLY base a -# kernel variant (`make rt`, CI's build-kernel legs) builds against: no init, -# no shell, no BusyBox, rootfs-tar only. Layered on common + de10nano -# (configs/fragments/stacks.mk, DE10NANO_KERNEL_FRAGMENTS); a variant's own -# configs/mister_.fragment is merged on top of that by the Makefile. -# This is NOT a second image. Rationale: docs/buildroot-config.md §4. - -# --- No init, no shell, no BusyBox (docs/buildroot-config.md §4.1) --- -# WARNING: all three lines are needed; BusyBox is `default y` on its own. -BR2_INIT_NONE=y -BR2_SYSTEM_BIN_SH_NONE=y -# BR2_PACKAGE_BUSYBOX is not set - -# --- Rootfs: tar, and ONLY tar (docs/buildroot-config.md §4.2) --- -# WARNING: drop this and depmod never runs — the module tree ships without -# modules.dep/modules.alias. The tar is also CI's module-transport artifact. -BR2_TARGET_ROOTFS_TAR=y diff --git a/configs/fragments/stacks.mk b/configs/fragments/stacks.mk deleted file mode 100644 index 20b9f7be..00000000 --- a/configs/fragments/stacks.mk +++ /dev/null @@ -1,38 +0,0 @@ -# configs/fragments/stacks.mk — the ONE place that says which fragments make -# up which Buildroot configuration. Included by the top-level Makefile and -# parsed (as plain `NAME := words` lines) by scripts/check-config-fragments.sh -# and scripts/check-kernel-defconfig-sync.sh. Keep it to that shape: one -# `_FRAGMENTS := ...` line per stack, names without the -# `.fragment` suffix, in merge order (later fragments layer on earlier ones). -# -# See docs/buildroot-config.md §1 for the mechanism and §10 for why each -# symbol lives where it does. -# -# The de10nano and de10nano-kernel stacks share `common` and `de10nano` BY -# CONSTRUCTION — that is what keeps the kernel-only base (used by `make rt` -# and every CI kernel leg) in lockstep with the shipped image without a -# mirrored copy. scripts/check-kernel-defconfig-sync.sh asserts this. -# -# `image-common` is the second sharing axis, at right angles to the first: it -# is in the IMAGE stack of every board and in the kernel-only stack of NONE, -# so a package both images want is selected once instead of mirrored per -# board — and the kernel-only base keeps its no-packages shape (§10 rule 4: -# `common` is in the kernel-only stack's fingerprint text, `image-common` is -# not). Merge order within a stack is free here: no symbol may be defined -# twice in one stack (scripts/check-config-fragments.sh (a)), so the board -# layer and the shared image layer never race. -DE10NANO_FRAGMENTS := common de10nano image-common de10nano-image -DE10NANO_KERNEL_FRAGMENTS := common de10nano kernel-only -DE25NANO_FRAGMENTS := common de25nano image-common -# -# The stage-1 initramfs stacks. `initramfs-common` is the third sharing axis: -# it is in NO image stack and NO kernel-only stack — a stage-1 stack builds a -# static musl BusyBox cpio and no kernel (it deliberately does not include -# `common`, which carries BR2_LINUX_KERNEL=y). Per board, only the arch/ABI + -# headers-series lines differ, and scripts/check-config-fragments.sh (f) -# asserts each initramfs- fragment agrees symbol-for-symbol with that -# board's .fragment. Output dirs: output-initramfs/ (DE10, embedded in -# every DE10 kernel) and output-initramfs-de25/ (DE25, built and QEMU-proven, -# not yet embedded — ADR 0029 D11). -INITRAMFS_DE10NANO_FRAGMENTS := initramfs-common initramfs-de10nano -INITRAMFS_DE25NANO_FRAGMENTS := initramfs-common initramfs-de25nano diff --git a/configs/mister_de10nano_defconfig b/configs/mister_de10nano_defconfig new file mode 100644 index 00000000..b5f98c75 --- /dev/null +++ b/configs/mister_de10nano_defconfig @@ -0,0 +1,65 @@ +# MiSTer DE10-Nano image -- the shipped linux.img + zImage_dtb (and zImage_dtb-rt). +# +# Load with `make mister_de10nano_defconfig`, build with `make`. This file is +# Buildroot's own minimal form (`make savedefconfig` reproduces it; scripts/ +# check-defconfigs.sh asserts that), so a diff here is the real change. The +# rationale for every line is docs/buildroot-config.md (section numbers there). +# +# ONE DEPARTURE FROM A PLAIN BUILDROOT DEFCONFIG: the package sets are Kconfig +# PROFILES -- BR2_PACKAGE_MISTER_USERSPACE / _FIRMWARE / _DRIVERS at the bottom +# each select a documented list (package/mister-*/Config.in), so the DE25-Nano +# shares them by selecting the same symbols. "Why is package X in my image?" +# -> package/mister-userspace/Config.in. +# +# Decisions that leave no line because they are Buildroot's default, recorded +# here so they are not "missing": passwordless root (BR2_TARGET_GENERIC_ROOT_PASSWD +# is "", matching stock, ADR 0015); azcopy is packaged but NOT enabled +# (docs/azcopy.md); zImage is the arm default image. +# +# Pins Renovate manages in THIS file: the 6.18.y kernel +# (BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE, hash in board/mister/de10nano/patches/ +# linux/linux.hash) and the 7.2.y RT kernel (BR2_PACKAGE_LINUX_RT_VERSION, hash +# in package/linux-rt/linux-rt.hash). +BR2_arm=y +BR2_cortex_a9=y +BR2_ARM_ENABLE_NEON=y +BR2_ARM_ENABLE_VFP=y +BR2_ARM_FPU_NEON=y +BR2_KERNEL_HEADERS_6_18=y +BR2_TOOLCHAIN_BUILDROOT_CXX=y +BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/patches" +BR2_DOWNLOAD_FORCE_CHECK_HASHES=y +BR2_REPRODUCIBLE=y +BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y +BR2_ROOTFS_MERGED_USR=y +BR2_SYSTEM_BIN_SH_BASH=y +BR2_GENERATE_LOCALE="en_US.UTF-8" +BR2_TARGET_TZ_INFO=y +BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/rootfs-overlay" +BR2_ROOTFS_POST_BUILD_SCRIPT="../../board/mister/de10nano/post-build.sh" +BR2_ROOTFS_POST_IMAGE_SCRIPT="../../board/mister/de10nano/post-image.sh" +BR2_LINUX_KERNEL=y +BR2_LINUX_KERNEL_CUSTOM_VERSION=y +BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.50" +BR2_LINUX_KERNEL_PATCH="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/linux-patches" +BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y +BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/linux.config" +BR2_LINUX_KERNEL_LZ4=y +BR2_LINUX_KERNEL_DTS_SUPPORT=y +BR2_LINUX_KERNEL_INTREE_DTS_NAME="intel/socfpga/socfpga_cyclone5_de10nano" +BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS=y +BR2_PACKAGE_BUSYBOX_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/busybox.fragment" +# BR2_PACKAGE_NFS_UTILS_RPC_NFSD is not set +# BR2_PACKAGE_LVM2_STANDARD_INSTALL is not set +BR2_PACKAGE_ZLIB_NG=y +# BR2_PACKAGE_OPENSSH_SANDBOX is not set +BR2_TARGET_ROOTFS_EXT2=y +BR2_TARGET_ROOTFS_EXT2_4=y +BR2_TARGET_ROOTFS_EXT2_SIZE="512M" +BR2_TARGET_ROOTFS_EXT2_MKFS_OPTIONS="-U 71916572-439f-448e-b8d8-12b0a032fa56 -E hash_seed=9afc615c-c310-4e03-ada9-613522e83ae6 -b 4096 -O has_journal,ext_attr,resize_inode,dir_index,filetype,extent,64bit,flex_bg,sparse_super,large_file,huge_file,dir_nlink,extra_isize,metadata_csum,^metadata_csum_seed,^orphan_file" +BR2_PACKAGE_HOST_KMOD_XZ=y +BR2_PACKAGE_MISTER_FIRMWARE=y +BR2_PACKAGE_MISTER_DRIVERS=y +BR2_PACKAGE_MISTER_USERSPACE=y +BR2_PACKAGE_LINUX_RT=y +BR2_PACKAGE_LINUX_RT_VERSION="7.2.4" diff --git a/configs/mister_de25nano_defconfig b/configs/mister_de25nano_defconfig new file mode 100644 index 00000000..bd9eb6c7 --- /dev/null +++ b/configs/mister_de25nano_defconfig @@ -0,0 +1,65 @@ +# MiSTer DE25-Nano developer OS (aarch64 / Agilex 5) -- ADR 0027, ADR 0029. +# +# Load with `make O=output-de25 mister_de25nano_defconfig`, build with +# `make O=output-de25` (or `make de25`). Buildroot's own minimal form +# (scripts/check-defconfigs.sh asserts it); rationale per line in +# docs/buildroot-config.md §6. +# +# BARE DEVELOPER OS: no MiSTer binaries, no DE10 userspace (rule 5 in +# docs/buildroot-config.md -- the DE10 profiles BR2_PACKAGE_MISTER_USERSPACE / +# _DRIVERS are adopted here only by owner decision). It shares the firmware +# profile (BR2_PACKAGE_MISTER_FIRMWARE) with the DE10 and nothing else. No +# stage-1 initramfs yet (ADR 0029 D11): the one-line switch is enabling the +# linux extension BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS here. +# +# Passwordless root (BR2_TARGET_GENERIC_ROOT_PASSWD "") is Buildroot's default +# and so leaves no line here; it is deliberate (ADR 0015). +BR2_aarch64=y +BR2_cortex_a76_a55=y +BR2_KERNEL_HEADERS_7_1=y +BR2_TOOLCHAIN_BUILDROOT_CXX=y +BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/patches" +BR2_DOWNLOAD_FORCE_CHECK_HASHES=y +BR2_REPRODUCIBLE=y +BR2_TARGET_GENERIC_HOSTNAME="de25" +BR2_TARGET_GENERIC_ISSUE="Welcome to MiSTer DE25-Nano (developer OS)" +BR2_ROOTFS_MERGED_USR=y +BR2_TARGET_GENERIC_GETTY_PORT="ttyS0" +BR2_TARGET_GENERIC_GETTY_BAUDRATE_115200=y +BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/post-image.sh" +BR2_LINUX_KERNEL=y +BR2_LINUX_KERNEL_CUSTOM_VERSION=y +BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="7.2.3" +BR2_LINUX_KERNEL_PATCH="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/linux-patches" +BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y +BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/linux.config" +BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/common/linux-mister.fragment" +BR2_LINUX_KERNEL_DTS_SUPPORT=y +BR2_LINUX_KERNEL_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/socfpga_agilex5_de25nano.dts" +BR2_TARGET_ROOTFS_EXT2=y +BR2_TARGET_ROOTFS_EXT2_4=y +BR2_TARGET_ROOTFS_EXT2_SIZE="256M" +BR2_TARGET_ARM_TRUSTED_FIRMWARE=y +BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y +BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE="v2.15.0" +BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="agilex5" +BR2_TARGET_ARM_TRUSTED_FIRMWARE_IMAGES="bl31.bin" +BR2_TARGET_UBOOT=y +BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y +BR2_TARGET_UBOOT_CUSTOM_VERSION=y +BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2026.07" +BR2_TARGET_UBOOT_BOARD_DEFCONFIG="socfpga_agilex5" +BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/uboot.fragment" +BR2_TARGET_UBOOT_NEEDS_OPENSSL=y +BR2_TARGET_UBOOT_NEEDS_ATF_BL31=y +BR2_TARGET_UBOOT_USE_BINMAN=y +# BR2_TARGET_UBOOT_FORMAT_BIN is not set +BR2_TARGET_UBOOT_FORMAT_ITB=y +BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/uboot-dts/socfpga_agilex5_de25nano.dts $(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/uboot-dts/socfpga_agilex5_de25nano-u-boot.dtsi" +BR2_PACKAGE_HOST_DOSFSTOOLS=y +BR2_PACKAGE_HOST_GENIMAGE=y +BR2_PACKAGE_HOST_KMOD_XZ=y +BR2_PACKAGE_HOST_MTOOLS=y +BR2_PACKAGE_HOST_UBOOT_TOOLS=y +BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y +BR2_PACKAGE_MISTER_FIRMWARE=y diff --git a/configs/mister_installer_defconfig b/configs/mister_installer_defconfig index d7870bb6..a20e1f20 100644 --- a/configs/mister_installer_defconfig +++ b/configs/mister_installer_defconfig @@ -27,7 +27,10 @@ BR2_INIT_NONE=y # --- Device nodes: dynamic/devtmpfs (§8.4) --- # WARNING: STATIC would leave /dev/console out of the cpio (no stdio for /init). -BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_DEVTMPFS=y +# (BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_DEVTMPFS is Buildroot's default and so +# leaves no line here -- it is load-bearing all the same: fs/cpio only mknods +# /dev/console in the non-static branch. scripts/check-defconfigs.sh keeps this +# file canonical, which is why the explicit line is gone.) # --- Target packages: the installer-only additions on top of BusyBox (§9) --- # mkfs.exfat (ADR 0020 §2 step 3); sfdisk + blkid via util-linux's one diff --git a/configs/mister_rt.fragment b/configs/mister_rt.fragment deleted file mode 100644 index 6a53fc00..00000000 --- a/configs/mister_rt.fragment +++ /dev/null @@ -1,28 +0,0 @@ -# mister_rt.fragment — the RT / Linux-7.2 "beta" kernel variant: the -# BUILDROOT-config layer, merged on the de10nano-kernel fragment stack -# (common + de10nano + kernel-only, configs/fragments/stacks.mk) by `make rt`. -# Everything not listed here is inherited from that stack unchanged. -# Rationale, status and the boot/verification history: docs/buildroot-config.md §7 -# and docs/rt-beta-kernel.md. -# -# WARNING: the pinned 7.2.y release has NOT been booted on hardware; every -# version bump re-opens that question. `make rt-clean` is MANDATORY before -# `make rt` on a bump. The kernel-config (CONFIG_*) layer, where -# CONFIG_PREEMPT_RT actually lives, is board/mister/de10nano/linux-rt.fragment. - -# --- The 7.2 kernel: the ONE allowlisted override of the base stack's version (§7.1) --- -# WARNING: coupled to board/mister/de10nano/patches/linux/linux.hash — bump -# both in one commit (Renovate + renovate-hash-sync.yml do this for a .y bump). -# This pin is a signed-manifest release, strictly stronger than the TOFU hash -# the old -rc pins had: do NOT reintroduce a TOFU value here without moving -# back to an -rc (the sync script refuses -rc values; only a hand pin can). -BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="7.2.4" - -# --- Beta patch set: the series-file-driven subset of linux-patches/ (§7.2) --- -# WARNING: the series deliberately DROPS 0047 (already in 7.2; at -F0 its hunk -# FAILS against pristine v7.2 — "Hunk #1 FAILED at 786") and carries four -# re-anchored copies (0001/0015/0030/0037); see the series header. -BR2_LINUX_KERNEL_PATCH="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/linux-patches-beta" - -# --- RT + 7.x kernel-config delta, layered on the shared linux.config (§7.3) --- -BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/linux-rt.fragment" diff --git a/docs/abi-contract.md b/docs/abi-contract.md index aa7210b8..1860417a 100644 --- a/docs/abi-contract.md +++ b/docs/abi-contract.md @@ -268,7 +268,7 @@ is the point of the project. **Not a hazard, but write it down — `libz.so.1`'s *provider* is not classic zlib.** Buildroot models zlib as a **virtual package** with a Kconfig `choice` (`package/zlib/Config.in`): `BR2_PACKAGE_LIBZLIB` is upstream's default, `BR2_PACKAGE_ZLIB_NG` -is the other arm. This image selects **zlib-ng 2.3.3** (`configs/fragments/de10nano-image.fragment`, +is the other arm. This image selects **zlib-ng 2.3.3** (`configs/mister_de10nano_defconfig`, compression block, where the blast-radius measurement is recorded). That choice is invisible to every row above: diff --git a/docs/azcopy.md b/docs/azcopy.md index 9f322b7b..5bf57c4c 100644 --- a/docs/azcopy.md +++ b/docs/azcopy.md @@ -20,7 +20,7 @@ this tree authors one. It is also **the first and only Go package in the tree**, has consequences of its own (§5). > **The default image does not contain azcopy.** The package builds and is fully -> wired, but `configs/fragments/de10nano-image.fragment` leaves `BR2_PACKAGE_AZCOPY` unset, +> wired, but `configs/mister_de10nano_defconfig` leaves `BR2_PACKAGE_AZCOPY` unset, > for the size reason in §1. To get azcopy onto a MiSTer today you either flip that > line and rebuild, or drop the released binary onto `/media/fat` yourself — which is > exactly how every test in §4 was run. @@ -29,7 +29,7 @@ has consequences of its own (§5). ## 1. Size and cost — read this first -**The package is present but NOT enabled** in `configs/fragments/de10nano-image.fragment`, and +**The package is present but NOT enabled** in `configs/mister_de10nano_defconfig`, and size is the only reason. At 39.1 MiB installed it would be the second-largest package in the image after samba4, spending about a fifth of the free space `linux.img` has left, for a tool most users will never run. It works — §4 is a transcript of it working @@ -235,7 +235,7 @@ all of it is fetched on a cold build, and all of it is inside the hash. ### Turning it on, and turning it back off -Uncomment `BR2_PACKAGE_AZCOPY` in `configs/fragments/de10nano-image.fragment`. Turning it off +Uncomment `BR2_PACKAGE_AZCOPY` in `configs/mister_de10nano_defconfig`. Turning it off again is deleting that line: nothing in the image depends on azcopy — no init script starts it, no other package links it, no parity test asserts it. `BR2_PACKAGE_CA_CERTIFICATES` and diff --git a/docs/buildroot-config.md b/docs/buildroot-config.md index 42dc93fd..bd432aa2 100644 --- a/docs/buildroot-config.md +++ b/docs/buildroot-config.md @@ -37,6 +37,22 @@ every one of them for a cosmetic gain. Read §12 straight after §5. --- +> **Layout change, 2026-09-11 (ADR 0030 Phase D).** The fragment stacks this document describes +> in §1 and §11 are gone. Each board is one committed Buildroot defconfig — +> `configs/mister_de10nano_defconfig`, `configs/mister_de25nano_defconfig` — in Buildroot's own +> `savedefconfig` form, loaded with `make _defconfig`. The shared package sets are Kconfig +> **profiles**: `package/mister-userspace/Config.in` (the DE10 userspace, §5's list with §5's +> section headings as comments), `package/mister-firmware/Config.in` (§12's firmware set, shared +> by both boards) and `package/mister-drivers/Config.in` (the out-of-tree drivers, §5.24/§5.25). +> The two boards agree on the old `common` layer's seven symbols by assertion +> (`scripts/check-defconfigs.sh`, which also asserts every defconfig loads, is canonical, and that +> every profile `select` really lands — a `select` of a kconfig `choice` member such as the zlib +> provider is silently ignored, so those lines live in the defconfig). The resolved configurations +> were proved identical to the fragment stacks' at the switch, plus only the profile symbols. +> **The per-line rationale below is unchanged and still the reference**; only where a line lives +> moved: §2-§4 → the defconfigs, §5 → `mister-userspace`, §6 → `mister_de25nano_defconfig`, +> §12 → `mister-firmware`. §1, §7, §8, §11 are historical. + ## 1. Layout and mechanism ``` @@ -92,7 +108,14 @@ produced — the only difference is `BR2_DEFCONFIG`, which is where - `output/.config` is generated once and then never touched by `make all` (no file prerequisites on the rule, so a `menuconfig` edit is not silently discarded — the Makefile's own comment explains). Regenerate deliberately - with `make de10nano-defconfig` / `make de25nano-defconfig` / `make rt-clean`. + with `make mister_de10nano_defconfig` / `make O=output-de25 mister_de25nano_defconfig` + (`make linux-rt-dirclean` after a change to the RT kernel version). Two + things leave a stale config behind that nothing regenerates for you: `make + clean` keeps every `.config` (Buildroot's definition), and a Buildroot pin + move retires or adds Kconfig symbols under it. A config written on the + previous pin then stops the next build at an interactive Kconfig prompt + ("Toolchain type", "Kernel Headers") — regenerate first, or `make distclean` + after a pin move. - A symbol belongs in **exactly one** fragment of a stack. A symbol set in `common` and overridden per board should have been board-only in the first place; `scripts/check-config-fragments.sh` fails on any redefinition (the @@ -431,6 +454,10 @@ hard-links `rootfs.ext2` to `linux.img` for the image (§5.2). ## 4. `kernel-only.fragment` +> **Superseded 2026-09-11 (ADR 0030 Phase C).** The fragment and the `de10nano-kernel` stack are +> gone: kernel variants are packages of the image configuration (`package/linux-rt`), so there +> is nothing to hold in lockstep. Kept for the record. + Turns a board stack into the shared KERNEL-ONLY base that kernel variants (`make rt`, and any future sibling; CI's `build-kernel` legs) build against (`docs/rt-beta-kernel.md`, ADR 0021 as amended 2026-07-18). @@ -2672,6 +2699,12 @@ DE10's is (§10): both boards set it, to different scripts. Without ## 7. `mister_rt.fragment` +> **Superseded 2026-09-11 (ADR 0030 Phase C).** The fragment is gone. The RT variant's +> Buildroot-side selection is two lines in `de10nano-image.fragment` (`BR2_PACKAGE_LINUX_RT=y`, +> `BR2_PACKAGE_LINUX_RT_VERSION="7.2.4"`); its kernel-config layer +> (`board/mister/de10nano/linux-rt.fragment`) and patch dir are unchanged and consumed by +> `package/linux-rt/linux-rt.mk`. Kept for the record. + The RT / Linux-7.2 "beta" kernel variant — the BUILDROOT-config layer of the variant, layered on the kernel-only stack (`common` + `de10nano` + `kernel-only`, §4) at build time by `make rt` (Buildroot's @@ -2819,6 +2852,17 @@ fragment, for the `linux-update-defconfig` reason in §3.4). ## 8. The stage-1 initramfs stacks +> **Superseded 2026-09-11 (ADR 0030).** There are no stage-1 stacks any more. The cpio is +> `package/mister-initramfs` — a static glibc BusyBox (`mister-initramfs-busybox`, a +> kconfig-package over `board/mister/common/initramfs-busybox.config`) plus a static +> `fsck.exfat` (`mister-initramfs-exfatprogs`), built by the *main* configuration with the main +> toolchain, verified by `package/mister-initramfs/verify.sh` inside the package build, and +> embedded by the linux extension `BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS` +> (`linux/linux-ext-mister-initramfs.mk`), which the `de10nano` fragment sets. The musl-vs-glibc +> size trade is measured in ADR 0030 §3.1. Everything below describes the retired layout and is +> kept for the record; §8.4 (`/dev/console`), §8.6 (the exfatprogs trim) and §8.7 (compression) +> still hold as *requirements*, now enforced by the package and the extension. + STAGE 1 of the two-stage build (TASKS.md P1.10 / A1, PLAN.md §5, `docs/decisions/0002-initramfs.md`). Since 2026-09-06 a fragment stack per board, not a standalone defconfig — `initramfs-common` carries everything diff --git a/docs/ci.md b/docs/ci.md index d159e4c0..238e3185 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -8,9 +8,9 @@ imperative ("MUST", "NEVER", a trap warning) plus the run ID that makes it credible, and this document keeps the narrative, the measurements, and the "we tried X and it failed" reasoning behind it. -Read top-to-bottom once: orientation, then the shared build recipe, then -caching (the biggest trap cluster), then each workflow, then cross-cutting -conventions, then the incident index. +Start with "The pipeline today" just below — it is the whole current shape on +one screen. The historical design notes after it are the reasoning and incident +history behind the pieces that survived, read when a section is linked to. This file lives in `docs/` alongside two documents that cover adjacent but distinct ground and are deliberately not folded in here: `docs/renovate.md` @@ -24,6 +24,43 @@ or policy document rather than restating it. --- +## The pipeline today (2026-09-11, after ADR 0030) + +Nine workflows, two composite actions, one Buildroot recipe. A build is +`make mister_de10nano_defconfig && make`, and every check CI runs is a script you can run locally. + +| Workflow | Runs on | What it does | +|---|---|---| +| `build.yml` | push to master, PRs | `gate` (skip doc-only changes) → `lint-config` (kernel patch headers, `scripts/check-defconfigs.sh`) → `build` (the action below, then `scripts/ci-tests.sh` via `verify-image`) → `status` | +| `lint.yml` | push, PRs | actionlint on the workflows, shellcheck on every script and on the composite actions' `run:` bodies | +| `release.yml` | `v*` tags | the same build, then `scripts/mk-release.sh` (stage assets, fetch + verify the pinned stock archive, assemble `release_YYYYMMDD.7z` and round-trip it under the pinned ARM `7za`, `SHA256SUMS`) and `scripts/mk-sdcard.sh`; then a draft release with provenance and the SBOM to the dependency graph. Runs locally: `MISTER_VERSION=… scripts/mk-release.sh` with the `STOCK_*` pins in the environment | +| `reproducibility.yml` | manual | two independent builds of one commit, hashes compared | +| `renovate-hash-sync.yml` | Renovate PRs | refresh the companion hash of whatever pin the PR bumped (each case is one `scripts/hash-sync-*.sh`) | +| `renovate-validate.yml` | push, PRs | `renovate.json` validates | +| `publish-db.yml` | published release | regenerate + publish `db.json` to Pages | +| `cache-prune.yml` | closed PRs, weekly | delete a closed PR's Actions caches | +| `fork-sync.yml` | weekly | backport queue against the upstream kernel fork | + +**The build action** (`.github/actions/buildroot-build`, ~200 lines) is `make mister_de10nano_defconfig && make` +with four caches: the Buildroot tarball, `dl/` (keyed on the defconfig), the cross toolchain (keyed on the +workspace path plus the defconfig's toolchain lines), and ccache. Two rules keep them honest: `dl/` is saved only +when `make external-deps` says it is complete, and the toolchain is restored only when `dl/` was. The comment +block at the top of the action says why. + +**What a maintainer needs to know:** the RT kernel and the stage-1 initramfs are packages of the one build +(`package/linux-rt`, `package/mister-initramfs`), so there is one output tree, one legal-info bundle and one +`linux.img`; there is no kernel matrix, no module-merge step and no variant caches any more. + +--- + +## Historical design notes (pre-ADR 0030) + +Everything below describes the pipeline as it was before 2026-09-11 — the kernel-variant matrix, the +kernel-only builds, seven caches, the fragment stacks — and is kept because ADRs and docs link into +these sections by anchor and because the reasoning behind the surviving pieces (cache coupling, dl/ +completeness, the doc-only gate, the stock-payload verification) is recorded here. Where a section +describes something retired, its Part banner says so. + ## Part I — Orientation @@ -132,6 +169,17 @@ distro does not leak into the target output. ## Part II — Variants and the kernel-only build +> **Superseded 2026-09-11 (ADR 0030 Phase C).** The kernel-variant matrix (`build-kernel`), +> the `kernel-leg` and `merge-kernel-modules` actions, the variant caches and +> `scripts/list-kernel-variants.sh` are gone. The RT kernel is `package/linux-rt` inside the +> one `make all`, so `build.yml` is `gate → lint-config → build → status` and `release.yml` +> stages `zImage_dtb-rt` and `linux-rt.config` straight from `output/images/`; its patches and +> licences are in the single `legal-info.tar.gz`. `.github/actions/buildroot-build`'s +> `variant` input errors on anything but `main`. This Part is kept for the record. The +> fragment-stack lint (`check-config-fragments.sh`, golden hashes) is likewise replaced by +> `scripts/check-defconfigs.sh` over the committed `configs/mister_*_defconfig` files (ADR 0030 +> Phase D). + ### Variants: main vs kernel-only diff --git a/docs/db-json-versioning.md b/docs/db-json-versioning.md index 3848ee13..6c686f8e 100644 --- a/docs/db-json-versioning.md +++ b/docs/db-json-versioning.md @@ -27,7 +27,7 @@ if current_linux_version == linux['version'][-6:]: ``` `/MiSTer.version` is written at build time by `board/mister/de10nano/post-build.sh`, -which derives its 6-byte `YYMMDD` stamp from `SOURCE_DATE_EPOCH`. `configs/fragments/de10nano-image.fragment` pins `SOURCE_DATE_EPOCH` to **Buildroot's own last-commit +which derives its 6-byte `YYMMDD` stamp from `SOURCE_DATE_EPOCH`. `configs/mister_de10nano_defconfig` pins `SOURCE_DATE_EPOCH` to **Buildroot's own last-commit date** — fixed as long as `BUILDROOT_VERSION` doesn't change (that pin is exactly what makes two independent builds of the same commit byte-identical, P2.5/A9's reproducibility requirement). @@ -86,7 +86,7 @@ exact-byte-match hazard" (a mismatched `/MiSTer.version` makes the inequality pe true) — here the mismatch is a **deliberate, chosen trade-off** rather than a whitespace bug, made because the alternative (never offering a new release to an already-updated device) was judged worse. **This should not be considered a closed question.** The -durable fix belongs in `post-build.sh`/`configs/fragments/de10nano-image.fragment` (P2.6), not +durable fix belongs in `post-build.sh`/`configs/mister_de10nano_defconfig` (P2.6), not here: have `post-build.sh` accept a build-time override (e.g. an env var the release workflow sets to that release's own real date) for `/MiSTer.version` specifically, while leaving `SOURCE_DATE_EPOCH` itself pinned for every *other* reproducibility guarantee diff --git a/docs/de25-dts-rationale.md b/docs/de25-dts-rationale.md index 5e99f666..703b6ab2 100644 --- a/docs/de25-dts-rationale.md +++ b/docs/de25-dts-rationale.md @@ -39,7 +39,7 @@ authored in the board file, by reference (`&label`) or by path (`&{/firmware/svc Nothing here needs a cross compiler — DTB generation and schema checking are host-only. ```sh -# 0. A private, writable copy of the pinned kernel. Do NOT use output-rt/build/linux-7.2.1; +# 0. A private, writable copy of the pinned kernel. Do NOT use output/build/linux-rt-; # that is a live DE10 build tree. mkdir -p /mnt/source/de25-work/t3 tar -xf dl/linux/linux-7.2.2.tar.xz -C /mnt/source/de25-work/t3/ diff --git a/docs/de25-implementation-path.md b/docs/de25-implementation-path.md index 713b5c94..adb4450f 100644 --- a/docs/de25-implementation-path.md +++ b/docs/de25-implementation-path.md @@ -536,7 +536,7 @@ architecture-generic C, so confidence is high. ADR 0021's per-variant machinery a DE25 pin at 7.2 is a **new instance of an existing pattern**, not new engineering. The real cost is the **bump treadmill**: 7.2 is not LTS, so the DE25 inherits the RT beta's -discipline (`rt-clean`, TOFU-hash re-verification, boot re-proved per version) indefinitely. Pinning +discipline (`make linux-rt-dirclean` on a version bump, TOFU-hash re-verification, boot re-proved per version) indefinitely. Pinning the DE25 to the same 7.x line the RT beta already tracks keeps that at **two** kernel lines in the repo rather than three, and lets one bump serve both. diff --git a/docs/de25-kernel-config.md b/docs/de25-kernel-config.md index 63170ce9..3c72de33 100644 --- a/docs/de25-kernel-config.md +++ b/docs/de25-kernel-config.md @@ -10,11 +10,16 @@ load-bearing comments were folded into this document when that file was deleted. |---|---|---| | [`board/mister/de25nano/linux.config`](../board/mister/de25nano/linux.config) | kernel `CONFIG_*` | the DE25's **base**: arm64 + Agilex 5 + boot path + FPGA stack + the "not a distro kernel" exclusions. A **minimal defconfig**, DE10 style. | | [`board/mister/common/linux-mister.fragment`](../board/mister/common/linux-mister.fragment) | kernel `CONFIG_*` | the **arch-neutral MiSTer personality**, shared: input/HID, Bluetooth, Wi-Fi, USB, sound, filesystems, netfilter, LEDs, RTC. | -| [`configs/fragments/de25nano.fragment`](../configs/fragments/de25nano.fragment) | Buildroot `BR2_*` | names both of the above (§7); rationale in [`docs/buildroot-config.md`](buildroot-config.md) §6.5. | +| [`configs/mister_de25nano_defconfig`](../configs/mister_de25nano_defconfig) | Buildroot `BR2_*` | names both of the above (§7); rationale in [`docs/buildroot-config.md`](buildroot-config.md) §6.5. | | [`scripts/check-kernel-fragment-noop.sh`](../scripts/check-kernel-fragment-noop.sh) | check | proves the fragment changes nothing on the DE10 (§6). | --- +> **2026-09-11:** `scripts/check-kernel-fragment-noop.sh`, the proof that the shared kernel +> fragment is a no-op on the DE10, had no caller and was removed with ADR 0030. The DE10 still +> carries its own `linux.config`; the shared `board/mister/common/linux-mister.fragment` remains +> the DE25's layer. Re-create the proof from git history if the DE10 adopts the fragment. + ## 1. The problem this closes Wave 1 built the DE25 kernel as **arm64's in-tree `defconfig` plus a 38-symbol @@ -142,10 +147,10 @@ accounting set, `IKCONFIG` + `IKCONFIG_PROC`, `LOG_BUF_SHIFT=14`, `CGROUPS` + killing every connection preauth**, password and key alike. The DE10 fixes that with `# BR2_PACKAGE_OPENSSH_SANDBOX is not set` in its own image fragment (commit `9824cd6`; the line is now - `configs/fragments/de10nano-image.fragment` and the rationale + `configs/mister_de10nano_defconfig` and the rationale `docs/buildroot-config.md` §5.19). - **Action for `configs/fragments/de25nano.fragment`:** it ships no `openssh` + **Action for `configs/mister_de25nano_defconfig`:** it ships no `openssh` today (the DE25 is a bare BusyBox developer OS, ADR 0027), so nothing is broken now — but the day `BR2_PACKAGE_OPENSSH=y` is added there, `# BR2_PACKAGE_OPENSSH_SANDBOX is not set` must be added with it. The @@ -174,7 +179,7 @@ They are arch-neutral and both boards need exactly this value, and the project's standing rule is *one home per symbol* — duplicating a line into both files creates two places to change it and one place to forget. The consequence is stated at the top of the board file: **`linux.config` alone does not boot.** The -two files are a pair and `configs/fragments/de25nano.fragment` always names both. +two files are a pair and `configs/mister_de25nano_defconfig` always names both. ### 3.5 Networking core and netfilter (§5) The DE10's exact set: `NET`/`PACKET`/`UNIX`/`INET`, `NET_KEY`(+`_MIGRATE`), @@ -490,10 +495,10 @@ How it was implemented — structurally, not by copying lines into `de25nano.fragment`: * The whole block moved OUT of `de10nano-image.fragment` and INTO a new - `configs/fragments/image-common.fragment`, the layer shared by every board's + `package/mister-firmware/Config.in`, the layer shared by every board's IMAGE stack and by no kernel-only stack. `DE25NANO_FRAGMENTS` gained it, so the DE25 gets the identical 31 symbols with no second copy to keep in step - (`configs/fragments/stacks.mk`; `docs/buildroot-config.md` §12, per-symbol + (`configs/mister_*_defconfig`; `docs/buildroot-config.md` §12, per-symbol calls in §12.2). * `xow-firmware` did NOT come along: it `depends on BR2_PACKAGE_XONE`, an out-of-tree module this board does not build (§12.2). @@ -635,6 +640,6 @@ does **not** belong in the lint job, which runs on a bare checkout. trees under `output/build/` the script fails closed by design (the Makefile `rt` recipe's "never the first glob match" rule) and needs `--tree`. In CI there is exactly one tree. -* **Optional second call** for the RT variant: `--tree output-rt/build/linux-*`, +* **Optional second call** for the RT variant: `--tree output/build/linux-rt-*`, same argument shape. The fragment is not consumed there today, so this is only worth adding if the RT kernel ever adopts it. diff --git a/docs/de25-nano-plan.md b/docs/de25-nano-plan.md index 93fe57f0..0afb2bbc 100644 --- a/docs/de25-nano-plan.md +++ b/docs/de25-nano-plan.md @@ -15,6 +15,14 @@ hardware, §1 and §4 are discarded and everything else transfers. --- +> **Layout note (2026-09-11, ADR 0030):** file and target names in this document predate the +> refactor that replaced the fragment stacks with committed `configs/mister_*_defconfig` files and +> Kconfig profiles, moved the RT kernel into `package/linux-rt` (`output/build/linux-rt-*`, no +> `output-rt/`), the stage-1 initramfs into `package/mister-initramfs`, and retired the +> kernel-variant CI matrix, `scripts/list-kernel-variants.sh`, `check-kernel-defconfig-sync.sh` +> and `scripts/lib/board-expectations.sh`. Read the paths here as of their date; the current +> layout is README "Building it yourself" and `docs/ci.md` "The pipeline today". + ## 1. The board, and the delta from DE10-Nano | | DE10-Nano (today) | DE25-Nano | Notes | diff --git a/docs/de25-nano-tasks.md b/docs/de25-nano-tasks.md index 98d1295a..20808ed2 100644 --- a/docs/de25-nano-tasks.md +++ b/docs/de25-nano-tasks.md @@ -64,6 +64,14 @@ places (boot flow, flash paths) where this board can be bricked. --- +> **Layout note (2026-09-11, ADR 0030):** file and target names in this document predate the +> refactor that replaced the fragment stacks with committed `configs/mister_*_defconfig` files and +> Kconfig profiles, moved the RT kernel into `package/linux-rt` (`output/build/linux-rt-*`, no +> `output-rt/`), the stage-1 initramfs into `package/mister-initramfs`, and retired the +> kernel-variant CI matrix, `scripts/list-kernel-variants.sh`, `check-kernel-defconfig-sync.sh` +> and `scripts/lib/board-expectations.sh`. Read the paths here as of their date; the current +> layout is README "Building it yourself" and `docs/ci.md` "The pipeline today". + ## Phase D0 — Recon (no gate; run any time; pure research) ### D0.1 Boot-chain contract dossier → `docs/de25-boot-chain.md` @@ -323,7 +331,7 @@ adversarial passes (config refactor; boot path) before anything is called done. | U-Boot + TF-A (D2.4 desk half) | mainline U-Boot v2026.07 + TF-A v2.15.0 as Buildroot packages; `board/mister/de25nano/uboot.fragment`, `uboot-dts/`; `docs/de25-uboot.md` | `u-boot.itb` built by binman and `dumpimage`-verified against the factory SPL contract (crc32 only, no keys; addresses disjoint). QSPI write paths compiled OUT (`CMD_SF`/`MTD`/`UBI`/`ENV_IS_IN_UBI` absent from the resolved config; verified again in the binary's strings). Stock's default boot command contains a `saveenv && ubi part root` leg — gone with `CMD_SF`. `HANDOFF` and `BLOBLIST` off (factory SPL, not ours, runs first). §8 Q6 closed negative: `# CONFIG_SPL is not set` removes the FIT. SD PHY: SoCDK-validated delays, default-speed 25 MHz for first contact. | | SD card image (D2.4 other half) | `genimage-sdcard.cfg`, `post-image.sh`, `scripts/check-sdcard-de25.sh`, `docs/de25-sdcard.md` | MBR, p1 FAT32 `DE25BOOT` (`u-boot.itb`, `Image`, dtb, `extlinux/extlinux.conf`), p2 = ext4 rootfs written directly (**interim** p2 decision). Checker opens the FIT, allow-lists p1, rejects the DE10 card and every mutated card. `make de25` asserts the card exists and passed. | | Kernel diet + shared fragment | `board/mister/common/linux-mister.fragment`, `board/mister/de25nano/linux.config`, `scripts/check-kernel-fragment-noop.sh`, `docs/de25-kernel-config.md` | 1,481 → 92 modules, 90 MB → 2.4 MiB, `Image` 41.9 → 20.7 MB; installed module name set identical to the DE10's. Fragment proven a **no-op on the DE10 6.18 tree** (mechanical check; wire it after the DE10 kernel build step). The wave-1 arm64-defconfig kernel had joydev/uinput/hidraw and the pad drivers OFF — invisible in a green build. | -| Config refactor (owner option 2) | `configs/fragments/*` stacks, monoliths deleted, comments → `docs/buildroot-config.md`, `scripts/check-config-fragments.sh` + golden hashes, `lint-config` CI job | PR #137. DE10 resolved config identical old vs new (two independent proofs); fingerprint residue byte-identical; 30+ mutations exercised; kernel-pin bumps don't move the golden, Buildroot bumps warn and are auto-refreshed by hash-sync case 8. | +| Config refactor (owner option 2) | `configs/fragments/*` stacks, monoliths deleted, comments → `docs/buildroot-config.md`, `scripts/check-defconfigs.sh` + golden hashes, `lint-config` CI job | PR #137. DE10 resolved config identical old vs new (two independent proofs); fingerprint residue byte-identical; 30+ mutations exercised; kernel-pin bumps don't move the golden, Buildroot bumps warn and are auto-refreshed by hash-sync case 8. | ### What the boot-path `fable` pass established (for the borrowed-board owner) @@ -359,8 +367,8 @@ QEMU path that boots it — done sequentially in the main tree (owner request: s | Track | Deliverable | Result | |---|---|---| -| Stage 1 as a fragment stack | `configs/fragments/initramfs-common.fragment` + `initramfs-de10nano` / `initramfs-de25nano`; `configs/mister_initramfs_defconfig` deleted; `/init`, `initramfs-busybox.config`, `initramfs-post-build.sh` moved to `board/mister/common/`; `INITRAMFS_*_FRAGMENTS` in `stacks.mk`; golden lines for both; checker (f) arch lockstep | DE10 stage-1 resolved config identical old vs new on Buildroot 2026.08 bar `BR2_DEFCONFIG`, the `-dirty` suffix and the three moved paths (5,240 lines). Existing four golden lines unchanged. `BR_INITRAMFS_HOST_KEY` now hashes the stack via `config_stack_files` (one cold CI cache, once). | -| `make de25-initramfs` family | `de25-initramfs`, `-verify` (the DE10 `initramfs-verify` recipe with three variables re-pointed, parse under `qemu-aarch64`), `-clean`, `-defconfig`, `-menuconfig`, `-busybox-menuconfig`; `output-initramfs-de25/` in clean/distclean/help | aarch64 musl toolchain + cpio in 6 min from nothing; 466,944-byte cpio, static aarch64 BusyBox; verify OK (19 applets + fsck.exfat + 5 trimmed + /init + /dev/console + ash parses /init). NOT embedded in the DE25 kernel (D11 interim); `external.mk` comment carries the switch. | +| Stage 1 as a fragment stack | `package/mister-initramfs` + `initramfs-de10nano` / `initramfs-de25nano`; `configs/mister_initramfs_defconfig` deleted; `/init`, `initramfs-busybox.config`, `initramfs-post-build.sh` moved to `board/mister/common/`; `INITRAMFS_*_FRAGMENTS` in `stacks.mk`; golden lines for both; checker (f) arch lockstep | DE10 stage-1 resolved config identical old vs new on Buildroot 2026.08 bar `BR2_DEFCONFIG`, the `-dirty` suffix and the three moved paths (5,240 lines). Existing four golden lines unchanged. `BR_INITRAMFS_HOST_KEY` now hashes the stack via `config_stack_files` (one cold CI cache, once). | +| `make de25` with `BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS=y` in the DE25 defconfig family | `de25-initramfs`, `-verify` (the DE10 `initramfs-verify` recipe with three variables re-pointed, parse under `qemu-aarch64`), `-clean`, `-defconfig`, `-menuconfig`, `-busybox-menuconfig`; `output-initramfs-de25/` in clean/distclean/help | aarch64 musl toolchain + cpio in 6 min from nothing; 466,944-byte cpio, static aarch64 BusyBox; verify OK (19 applets + fsck.exfat + 5 trimmed + /init + /dev/console + ash parses /init). NOT embedded in the DE25 kernel (D11 interim); `external.mk` comment carries the switch. | | `scripts/test-initramfs.sh --board de25nano` | board switch (`--board` / `TEST_INITRAMFS_BOARD`); per-board cpio, QEMU binary/machine (`-M virt -cpu cortex-a76`), cross compiler (the stage-1 build's own musl toolchain — no `make de25` needed), kernel version pin, 0031 source, caches (`work/test-initramfs-de25*`); test kernel = `board/mister/de25nano/linux.config` + `linux-mister.fragment` + the unchanged harness fragment; kernel tarball default now prefers `dl/linux/` | Whole run incl. the 7.2.3 kernel build: 4 m 16 s; one case re-run 5.5 s. **7/8 PASS**; `symlink` FAIL = a real kernel Oops (below). DE10 leg byte-for-byte unchanged in behaviour. `ci-tests.sh` gained the DE25 leg (skips when no DE25 cpio was built). | **Finding (the point of the exercise).** Patch 0031's `exfat_symlink` → `page_symlink()` → @@ -394,7 +402,11 @@ Remaining, in unblock order: pointed to from the DE25 series; the aarch64 leg's `symlink` case is the acceptance test — it is the ONLY place 0031-on-7.x is executed rather than compiled.~~ **DONE 2026-09-06:** beta-local copy, DE25 series relinked, aarch64 leg 8/8, arm compile clean on the RT config. - Remaining: the first `ln -s` on an RT-booted DE10 (32-bit 7.x is still compile-only). + ~~Remaining: the first `ln -s` on an RT-booted DE10 (32-bit 7.x is still compile-only).~~ + **2026-09-11:** executed as 32-bit ARM by `scripts/test-initramfs.sh --kernel rt` (7.2.4, + `symlink`/`exfat`/`fsck-request` pass; the 6.18-form patch on 7.2.4 reproduces the Oops), + after the rig, still on a pre-rewrite RT 7.2.3, panicked on the Arcade Organizer's first + symlink (ADR 0002 §8b). Hardware boot of the fixed RT kernel still owed. 3. **Owner decisions still open**: a Renovate manager for the DE25 kernel pin; upstream submission of 0101/0102; patch 0002 (audio). Hardware is expected after the owner's vacation (ordered on return). diff --git a/docs/de25-readiness-ledger.md b/docs/de25-readiness-ledger.md index 217ab868..3cf52592 100644 --- a/docs/de25-readiness-ledger.md +++ b/docs/de25-readiness-ledger.md @@ -13,6 +13,14 @@ DP-2 depends on). --- +> **Layout note (2026-09-11, ADR 0030):** file and target names in this document predate the +> refactor that replaced the fragment stacks with committed `configs/mister_*_defconfig` files and +> Kconfig profiles, moved the RT kernel into `package/linux-rt` (`output/build/linux-rt-*`, no +> `output-rt/`), the stage-1 initramfs into `package/mister-initramfs`, and retired the +> kernel-variant CI matrix, `scripts/list-kernel-variants.sh`, `check-kernel-defconfig-sync.sh` +> and `scripts/lib/board-expectations.sh`. Read the paths here as of their date; the current +> layout is README "Building it yourself" and `docs/ci.md` "The pipeline today". + ## 1. Why this document exists, and what it is *not* A fresh grep for `de10nano|BR2_arm|zImage` outside `board/mister/de10nano/` and `docs/` hits @@ -89,10 +97,10 @@ in prose, no action or a one-word reword. > `renovate.json`, `renovate-hash-sync.yml`, `scripts/hash-sync-kernel.sh`, > `scripts/ci-tests.sh`, `scripts/test-initramfs.sh`, `scripts/test-sdcard-install.sh`, > `scripts/export-kernel-tree.sh` and `scripts/lint-kernel-patches.sh` read -> `configs/fragments/de10nano.fragment`; `scripts/check-linux-img.sh` cites -> `configs/fragments/de10nano-image.fragment`; `scripts/check-kernel-defconfig-sync.sh` +> `configs/mister_de10nano_defconfig`; `scripts/check-linux-img.sh` cites +> `configs/mister_de10nano_defconfig`; `scripts/check-kernel-defconfig-sync.sh` > compares the two DE10 stacks' merged text. The `Makefile` rows in §4 are superseded -> by `make de10nano-defconfig` / `make de25nano-defconfig`. The line numbers below are +> by `make mister_de10nano_defconfig` / `make O=output-de25 mister_de25nano_defconfig`. The line numbers below are > the pre-split ones and are kept as the record of what was verified. | file:line | coupling | sev | when you touch this, do this instead | @@ -130,7 +138,7 @@ in prose, no action or a one-word reword. | `configs/mister_initramfs_defconfig:5,56,59,84` | Prose plus busybox-config / overlay / post-build-script paths under the board dir **[V]** | parameterize | Path substitution only — no arch semantics in any of the three. | | `configs/mister_installer_defconfig:60-64` | `BR2_arm=y` / `BR2_cortex_a9=y` / NEON / VFP / FPU_NEON for the throwaway installer OS **[V]** | cosmetic | Board-owned file: DE25 gets its own installer defconfig if and when its installer flow is designed (which DP-2 and coupling (b) gate anyway). | | `configs/mister_installer_defconfig:109,116` | Installer busybox config + installer overlay under the board dir **[V]** | cosmetic | Same — the DE25 copy repeats the pattern. | -| `configs/mister_rt.fragment:23,62,100,105,108` | Kernel-patch dir, RT fragment path, and the hash coupling all name `board/mister/de10nano/`; `:100` records a `zImage_dtb` build check **[V]** | parameterize | Board-scope the three paths when the RT variant is next touched; note DP-6 says RT on big.LITTLE must be re-evaluated, not assumed to port. | +| `package/linux-rt/Config.in:23,62,100,105,108` | Kernel-patch dir, RT fragment path, and the hash coupling all name `board/mister/de10nano/`; `:100` records a `zImage_dtb` build check **[V]** | parameterize | Board-scope the three paths when the RT variant is next touched; note DP-6 says RT on big.LITTLE must be re-evaluated, not assumed to port. | | `Makefile:69` | `INITRAMFS_INIT := $(ROOT_DIR)/board/mister/de10nano/initramfs-overlay/init` **[V]** | parameterize | Take the board dir from a `BOARD` make variable defaulting to `de10nano` — see §6.2. | | `Makefile:330` | `$(BR_MAKE) mister_de10nano_defconfig` in the `.config` recipe **[V]** | parameterize | Drive the defconfig name off the same `BOARD` variable so `make BOARD=de25nano` is the whole invocation surface — see §6.2. | | `Makefile:393,436,450,541,628,654,701,886` | Eight more board-dir paths and error strings, incl. `:701` invoking `board/mister/de10nano/post-image.sh` **[V]** | parameterize | Same `BOARD` substitution; `:701` is the one that actually *runs* something, so it moves with `:69`/`:330` in the same diff. | diff --git a/docs/de25-sdcard.md b/docs/de25-sdcard.md index 8b8b1e94..bd1c0755 100644 --- a/docs/de25-sdcard.md +++ b/docs/de25-sdcard.md @@ -121,23 +121,28 @@ config's p2 stanza and `check-sdcard-de25.sh`'s `EXPECT_ROOT_DEV` **in one commi data partition holding `linux/linux.img`, loop-mounted as the root by the embedded stage-1 initramfs, `/media/fat` = p2. The interim shape above stays until a board has booted it. -**The stage-1 half is already built (2026-09-06).** `make de25-initramfs` builds the DE10's -`/init` for aarch64 (`configs/fragments/initramfs-de25nano.fragment`; the `/init`, BusyBox config -and post-build hook are shared under `board/mister/common/`) and verifies it; `scripts/ -test-initramfs.sh --board de25nano` boots it on `qemu-system-aarch64` through the DE10's eight -cases with a test kernel built from THIS board's `linux.config`. All eight pass — the `symlink` +**The stage-1 half is already built (2026-09-06; re-shaped 2026-09-11 by ADR 0030).** The DE10's +`/init` is arch-neutral and ships as `package/mister-initramfs`, a package of whichever board +configuration selects it, built with that board's own toolchain (static glibc BusyBox + static +`fsck.exfat`; `board/mister/common/` holds the `/init` and the BusyBox config). Under the +pre-ADR-0030 layout it was built for aarch64 as a separate musl stack and boot-tested with +`scripts/test-initramfs.sh --board de25nano` on `qemu-system-aarch64` through the DE10's eight +cases with a test kernel built from THIS board's `linux.config`. All eight passed — the `symlink` case first exposed that patch 0031 crashed on any 7.x kernel, and the same PR re-anchored it -(ADR 0002 §8b). The switch itself is one commit touching, together: +(ADR 0002 §8b). That run predates the package shape; the aarch64 package build has not been +exercised yet and is re-verified as part of the switch. The switch itself is one commit touching, +together: | File | Change | |---|---| -| `external.mk` | the embedding fixup keys on `BR2_LINUX_KERNEL` and picks the cpio path by architecture (the guard's comment carries the exact text) | -| `Makefile` | `de25: de25-initramfs …`, and `check-initramfs` (or a DE25 twin) asserting the DE25 kernel's `CONFIG_INITRAMFS_SOURCE` | +| `configs/mister_de25nano_defconfig` | `BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS=y` — selects `package/mister-initramfs` for the DE25 build and makes its kernel embed the cpio (`linux/linux-ext-mister-initramfs.mk`); regenerate `golden.sha256` | | `board/mister/de25nano/post-image.sh` | `BOOTARGS` → `root=/dev/mmcblk0p2 loop=linux/linux.img ro rootwait console=… earlycon` (the DE10's exact shape, p2 instead of p1) | | `board/mister/de25nano/genimage-sdcard.cfg` | p2 becomes an exFAT partition (type 0x07, label per the downloader contract) carrying `linux/linux.img` = `rootfs.ext4`; needs a host `mkfs.exfat` genimage can drive, or the DE10's installer route | | `scripts/check-sdcard-de25.sh` | `EXPECT_ROOT_DEV` + a `loop=` assert; p2 type/label/contents | | `docs/de25-boot-chain.md`, this file §1 | the layout table | +Then `scripts/test-initramfs.sh --board de25nano` against `output-de25/images/mister-initramfs.cpio`. + Nothing in `/init` changes: it takes `root=` and `loop=` from the command line and has no board-specific line, which is what the aarch64 leg proves. diff --git a/docs/de25-uboot.md b/docs/de25-uboot.md index 15659688..a5643617 100644 --- a/docs/de25-uboot.md +++ b/docs/de25-uboot.md @@ -68,7 +68,7 @@ item, and building green does not close it. Terasic and Altera document only ven | File | Role | |---|---| -| `configs/fragments/de25nano.fragment` | the ATF/U-Boot/host-tools stanza (rationale: `docs/buildroot-config.md` §6.9, §6.10) | +| `configs/mister_de25nano_defconfig` | the ATF/U-Boot/host-tools stanza (rationale: `docs/buildroot-config.md` §6.9, §6.10) | | `board/mister/de25nano/uboot.fragment` | the U-Boot Kconfig delta on `socfpga_agilex5_defconfig` (§4) | | `board/mister/de25nano/uboot-dts/socfpga_agilex5_de25nano.dts` | U-Boot board device tree (§5) | | `board/mister/de25nano/uboot-dts/socfpga_agilex5_de25nano-u-boot.dtsi` | U-Boot additions: `stdout-path`, mmc caps, FIT tweaks (§5, §6) | @@ -558,7 +558,7 @@ have nothing to bind to (§5). **Third lock, outside U-Boot:** §7 row 11 — a Linux-side `fw_setenv` with an `fw_env.config` naming an MTD device bypasses everything above. Nothing in this build ships `fw_setenv` -(`configs/fragments/de25nano.fragment` has no packages at all), but that is an accident of scope, not +(`configs/mister_de25nano_defconfig` has no packages at all), but that is an accident of scope, not a guard. §5's proposed release-blocking CI check ("the DE25 U-Boot config has `ENV_IS_IN_UBI` unset and ships no QSPI-write command set") is still **unimplemented**; this table is what it should assert. @@ -747,7 +747,7 @@ this build; typing them should produce `Unknown command` — which is itself a u ## 12b. One change here that is not about U-Boot -The DE25's Buildroot configuration (`configs/fragments/de25nano.fragment`) is shared by three +The DE25's Buildroot configuration (`configs/mister_de25nano_defconfig`) is shared by three tracks working in parallel, and the kernel track deliberately did not touch it — the kernel-config commit's message says *"The defconfig switch (custom config + fragment, delete de25nano/linux.fragment) lands with the U-Boot track's defconfig edit."* So this pass also lands diff --git a/docs/debug-tooling.md b/docs/debug-tooling.md index ea74a91f..c4f57da5 100644 --- a/docs/debug-tooling.md +++ b/docs/debug-tooling.md @@ -54,7 +54,7 @@ $ grep -rn "DEBUG TOOLING" configs/ board/ | Where | What | | --- | --- | -| `configs/fragments/de10nano-image.fragment` | `BR2_PACKAGE_GDB` + `_GDB_SERVER` + `_GDB_DEBUGGER`, `BR2_PACKAGE_LINUX_TOOLS_PERF` (+ `_NEEDS_HOST_PYTHON3`), `BR2_PACKAGE_RT_TESTS`. `BR2_PACKAGE_STRACE` was in the block too until the 2026-09 fragment split: T5 had already promoted strace to a permanent package (its own line in the T5 section), and the fragment sets it once, there — deleting the block no longer removes strace (`docs/buildroot-config.md` §5.32) | +| `configs/mister_de10nano_defconfig` | `BR2_PACKAGE_GDB` + `_GDB_SERVER` + `_GDB_DEBUGGER`, `BR2_PACKAGE_LINUX_TOOLS_PERF` (+ `_NEEDS_HOST_PYTHON3`), `BR2_PACKAGE_RT_TESTS`. `BR2_PACKAGE_STRACE` was in the block too until the 2026-09 fragment split: T5 had already promoted strace to a permanent package (its own line in the T5 section), and the fragment sets it once, there — deleting the block no longer removes strace (`docs/buildroot-config.md` §5.32) | | `board/mister/de10nano/linux.config` | `CONFIG_COREDUMP=y` (was `# CONFIG_COREDUMP is not set`) | Nothing else in the tree references any of it. @@ -65,7 +65,7 @@ Nothing else in the tree references any of it. | --- | --- | --- | | gdb / gdbserver | 15.2 | `BR2_GDB_VERSION` default for a GCC >= 9 toolchain (`package/gdb/Config.in.host:77`) | | strace | 7.0 | `package/strace/strace.mk` | -| perf | = the kernel pin (`BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE`, `configs/fragments/de10nano.fragment`) | built from **our own kernel's** `tools/perf`, not a standalone release — so it tracks the pin by construction, never separately (§2) | +| perf | = the kernel pin (`BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE`, `configs/mister_de10nano_defconfig`) | built from **our own kernel's** `tools/perf`, not a standalone release — so it tracks the pin by construction, never separately (§2) | | rt-tests | 2.8 | `package/rt-tests/rt-tests.mk` | | numactl | 2.0.19 | pulled in by rt-tests (`select`) | | mpfr | 4.2.2 | pulled in by the full gdb (`select`) | @@ -133,7 +133,7 @@ which is **part of the `linux` package**, not a standalone one. Consequences: * perf is rebuilt whenever the kernel is, and always matches the running kernel's `tools/perf` — no version skew; -* it is *not* built by the kernel-only fragment stack (`configs/fragments/kernel-only.fragment`) / `make rt` +* it is *not* built by the kernel-only fragment stack (`package/linux-rt/linux-rt.mk`) / `make linux-rt` path, which sets no packages. RT gets `CONFIG_COREDUMP` but not a perf of its own — the single shipped `perf` is the one from the main image's kernel build, and it is what runs under the RT kernel too. The `perf_event_attr` ABI is @@ -247,7 +247,7 @@ actually writes the ELF core file. It turns on for free and **must not** get a line of its own: it is invisible to kconfig while `COREDUMP` is off, so a `savedefconfig` round-trip would drop any line added for it. -`linux.config` is shared with the kernel-only stack (`configs/fragments/de10nano.fragment` names it), so the RT/beta +`linux.config` is shared with the kernel-only stack (`configs/mister_de10nano_defconfig` names it), so the RT/beta kernel gets coredumps too. That is wanted — RT is the variant under active on-hardware investigation. @@ -336,7 +336,7 @@ is a decision on the record rather than an oversight: ## 5. How to revert 1. Delete the whole `DEBUG TOOLING` block from - `configs/fragments/de10nano-image.fragment` — opening banner (`>>> DEBUG TOOLING — + `configs/mister_de10nano_defconfig` — opening banner (`>>> DEBUG TOOLING — TEMPORARY, REMOVE AS ONE BLOCK <<<`) through closing banner (`>>> END DEBUG TOOLING <<<`), inclusive. See §1 for why the two banner lines are not mirror images. @@ -362,7 +362,7 @@ is a decision on the record rather than an oversight: 6. Rebuild: ```sh - make de10nano-defconfig # re-resolve output/.config from the fragment stack + make mister_de10nano_defconfig # re-resolve output/.config from the committed defconfig make all ``` @@ -410,8 +410,8 @@ Per binary, stripped, as installed: That figure needs one correction to be honest, and it is the reason the raw before/after percentages do not simply subtract. The master build this was compared against had **two** kernel module trees staged (`6.18.39` *and* the -`7.2.0-rc4` RT tree from a previous `make rt`, 3.2 MiB), and this branch has only -`6.18.39` — no `make rt` was run in this worktree. Comparing the images +`7.2.0-rc4` RT tree from a previous `make linux-rt`, 3.2 MiB), and this branch has only +`6.18.39` — no `make linux-rt` was run in this worktree. Comparing the images head-on (50.5 % free vs 48.4 %) therefore understates the debug tooling by crediting it with the absent RT tree. The +15 MiB above is `du -sm output/target` on both sides with the RT tree subtracted from master's, which is the diff --git a/docs/decisions/0002-initramfs.md b/docs/decisions/0002-initramfs.md index 3cf8b966..8b9f1e70 100644 --- a/docs/decisions/0002-initramfs.md +++ b/docs/decisions/0002-initramfs.md @@ -372,8 +372,77 @@ device directly and never sees a dirty bdev buffer), and does the `valid_size` / `zeroed_size` / `i_size` bookkeeping the write path would have done. Applies at `-F0` to pristine 7.2.3; compiles for arm with the RT `.config` and for arm64 with the DE25's; the aarch64 leg is **8/8** with the `symlink` case's full assertion set (hot+cold round-trip, -`DT_LNK`, the create+unlink cluster-leak tripwire via `statvfs`, host-side fsck-clean). What -remains unexecuted is 0031 on 32-bit 7.x — the RT kernel on a real board. +`DT_LNK`, the create+unlink cluster-leak tripwire via `statvfs`, host-side fsck-clean). + +**2026-09-11 — the 32-bit gap closed, the hard way first.** The maintainer's rig was still on +an RT 7.2.3 kernel built 2026-09-05, before the rewrite shipped there; `update_all.sh`'s +Arcade Organizer created its first `.mra` symlink on `/media/fat` and the board Oopsed +exactly as above (`PC is at 0x0`, `LR is at page_symlink+0x90`, from `exfat_symlink`; captured +by netconsole) and, with `CONFIG_PANIC_ON_OOPS=y` + `panic=15`, rebooted 17 s later. The +same day `scripts/test-initramfs.sh --kernel rt` was added: the DE10 leg built at the RT pin +(`BR2_PACKAGE_LINUX_RT_VERSION`) with `linux-patches-beta/0031`, on `qemu-system-arm`, so the +rewrite is executed as 32-bit ARM. Result at 7.2.4: `symlink`, `exfat`, `fsck-request` pass; +the negative control (the 6.18-form patch on the same 7.2.4 source) reproduces the rig's +Oops in QEMU, so the leg detects the bug it exists for. `ci-tests.sh` runs it after the +DE10 leg. What remains is the ordinary hardware claim: a board boot of the fixed RT kernel. + +## 8c. Amendment 2026-09-11 — stage 1 becomes a package of the main build (ADR 0030) + +The two-stage build's *mechanism* changes; nothing about what `/init` does, or the four +kernel-side requirements (I1–I4), changes. The owner accepted ADR 0030's Phase B: stage 1 is no +longer a second Buildroot configuration in `output-initramfs/` with its own musl toolchain. It is +`package/mister-initramfs` in the main configuration: + +- `mister-initramfs-busybox` — a kconfig-package over the same + `board/mister/common/initramfs-busybox.config`, built with the **main glibc toolchain** and + linked `-static` by the package itself (`CONFIG_STATIC` pinned in its fixup), upstream's busybox + patches applied. §10's "glibc + `CONFIG_STATIC`" rejection was about a Buildroot + *configuration* (`BR2_STATIC_LIBS` is not offered with glibc, and the rootfs would carry the + shared libc): neither applies to a package that builds one static binary into its own + directory. +- `mister-initramfs-exfatprogs` — the same for `fsck.exfat`; only that binary is copied, so + ADR 0026's trim of the other five tools is structural rather than a post-build deletion. +- `mister-initramfs` — assembles the tree, the overlay's `/init` and `/dev/console` (under + `host-fakeroot`, as `fs/common.mk` does), packs the cpio with `--reproducible` and pinned + mtimes under `BR2_REPRODUCIBLE`, runs `verify.sh` (the applet, forbidden-binary, `/init` and + `ash -n` checks that were `make initramfs-verify`; a failure fails the package), and installs + `images/mister-initramfs.cpio`. +- `linux/linux-ext-mister-initramfs.mk` + `linux/Config.ext.in` — a br2-external **linux + extension** (`BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS`). It is included by `linux/linux.mk` + before the kernel package is evaluated, which is the only hook early enough to make the kernel + *depend* on the package; the `CONFIG_INITRAMFS_SOURCE` fixup moved there from `external.mk` + unchanged. `MISTER_INITRAMFS_CPIO` stays overridable for `mk-sdcard.sh`'s installer relink. + +**Measured cost (2026-09-11):** static glibc BusyBox 942,660 B against the musl 263,308 B +(§7's numbers); the static `fsck.exfat` adds a similar delta. Against the 16 MiB `zImage_dtb` +budget (`docs/boot-chain.md` §7.3, a RAM-layout limit, not a card-size one) with ~7.4 MB of +headroom on the RT kernel, accepted by the owner. + +**What this retires:** `output-initramfs/`, `output-initramfs-de25/`, the `initramfs-*` +fragment stacks and their golden lines, `make initramfs` / `check-initramfs` / +`initramfs-verify` / `de25-initramfs*`, `board/mister/common/initramfs-post-build.sh`, the +initramfs host-toolchain cache in CI, and `external.mk`'s embedding block. The `BR2_arm` gate +becomes the extension symbol, which the `de10nano` fragment sets and the `de25nano` fragment does +not (ADR 0029 D11 unchanged: enabling it there is the one-line switch). + +**Verification for this amendment (2026-09-11, branch `feat/vanilla-buildroot`, worktree +build from scratch on Buildroot 2026.08):** +- `make all` exit 0; `mister-initramfs: verify OK (44 entries, 1577984 bytes)`; `images/zImage_dtb` + 9,717,297 bytes, `check-zimage-dtb.sh` headroom 7,059,919 bytes under the 16 MiB budget. +- `zcat output/build/linux-6.18.50/usr/initramfs_inc_data | cmp - images/mister-initramfs.cpio`: + **identical** (§7's check, on the package cpio). Kernel `.config`: `CONFIG_BLK_DEV_INITRD=y`, + `CONFIG_INITRAMFS_SOURCE` = the package cpio, `CONFIG_INITRAMFS_COMPRESSION_GZIP=y`. +- Content against the retired musl cpio (80 entries → 44): the applet symlink set is + **identical**, `/init` is byte-identical to the overlay, `/dev/console` present; the entries + gone are Buildroot's skeleton (`etc/*`, `lib/ld-musl*`, `dev/fd`, `var`, …), none of which + `/init` touches; the entries new are `mnt/fat` and `newroot`, which `/init` `mkdir -p`s anyway. + `bin/busybox` 942,660 B and `usr/sbin/fsck.exfat` 611,508 B, both static glibc. +- `scripts/ci-tests.sh`: **366 pass, 0 fail, 6 skip**, including `initramfs embedding` and + `test-initramfs.sh` **8/8** QEMU boot cases on the new cpio (fat32, exfat, fsck-request, + symlink, label, nonascii, missing-image, rootwait). +- Not yet done: a boot on the rig. The verify-before-switch protocol + (`docs/rt-beta-kernel.md` §5 shape: copy as `_vN`, `sha256sum` on device, then edit + `u-boot.txt` with a rollback copy) applies; the owner flashes. ## 9. Known gaps (deliberate, not oversights) diff --git a/docs/decisions/0021-rt-kernel-first-class-ci.md b/docs/decisions/0021-rt-kernel-first-class-ci.md index e781e8cc..faa8dc45 100644 --- a/docs/decisions/0021-rt-kernel-first-class-ci.md +++ b/docs/decisions/0021-rt-kernel-first-class-ci.md @@ -277,3 +277,50 @@ single hardcoded slot by that script's own design — one flashable card, one bonus kernel — not a variant list. See docs/rt-beta-kernel.md's "Adding a future kernel variant" paragraph for the same accounting kept in sync with the code. + +--- + +## Amendment 2026-09-11 — the variant becomes a package of the main build (ADR 0030 Phase C) + +Accepted by the owner with ADR 0030. The RT kernel is no longer a kernel-only Buildroot tree +(`output-rt/`) whose module tree the wrapper Makefile staged into an overlay for the next +`make all`. It is `package/linux-rt`: a kconfig-package in this br2-external, the same shape as +Buildroot's own `barebox-aux` (one source, a second configuration, one tree), reusing the main +kernel's `LINUX_MAKE_FLAGS`/`LINUX_MAKE_ENV`/`LINUX_KCONFIG_FIXUP_CMDS`, `linux.config` and the +stage-1 extension, layering `linux-rt.fragment`, and applying `linux-patches-beta` through +`BR2_GLOBAL_PATCH_DIR/linux-rt`. + +What this keeps from §2's amended decision: one `linux.img` with every variant's module tree +(now by `modules_install` into `TARGET_DIR`, with the package's own depmod hook and a +non-empty `modules.alias` assertion); the `CONFIG_PREEMPT_RT=y` proof (a post-configure hook +that fails in seconds, before the compile); `zImage_dtb-rt` and `linux-rt.config` as release +assets, budget-checked by `scripts/check-zimage-dtb.sh`. + +What it retires: `output-rt/`, `work/extra-modules-overlay` and its stamps, `rt-clean`'s +two-place removal (there is no overlay rsync to fight), the `make rt` before `make all` order, +the `build-kernel` matrix with the `kernel-leg` and `merge-kernel-modules` actions, the variant +dl/ and host caches, `scripts/list-kernel-variants.sh`, `scripts/check-kernel-defconfig-sync.sh`, +`configs/mister_rt.fragment` and `configs/fragments/kernel-only.fragment`. The +`legal-info-rt.tar.gz` asset folds into `legal-info.tar.gz` (the package has a manifest row +there). The variant's version pin moves to `BR2_PACKAGE_LINUX_RT_VERSION` in +`configs/fragments/de10nano-image.fragment`, its hash to `package/linux-rt/linux-rt.hash`; +Renovate and `scripts/hash-sync-kernel.sh --pin=rt` follow. + +Why the owner wanted it serial in the first place: CI already serialised the kernel leg before +the image job (19 min then 3 h 05 min on the last green master run), and every extra tree was +another toolchain to cache or rebuild. One tree means at most one toolchain build on a cache +miss. + +Verification (2026-09-11, branch `feat/vanilla-buildroot`, incremental `make all` on the +Phase B tree): `package/linux-rt` extracted 7.2.4, applied all **42** series entries through +`BR2_GLOBAL_PATCH_DIR/linux-rt`, took the shared kernel fixups (including the stage-1 cpio +embedding), passed the `CONFIG_PREEMPT_RT=y` assertion at configure time, built, and produced +`images/zImage_dtb-rt` **10,091,326 bytes** (headroom 6,685,890 under the 16 MiB budget) and +`images/linux-rt.config`. `output/target/usr/lib/modules/` holds exactly `6.18.50` (103 modules) +and `7.2.4` (**90 modules**, `modules.alias` 67,054 bytes, depmod'd by the package's own hook). +`make legal-info`: the `linux-rt` row is in `manifest.csv` and all 42 patches are under +`sources/linux-rt-7.2.4/`. `scripts/ci-tests.sh`: **366 pass, 0 fail, 6 skip**. The configured +`linux-rt` `.config` diffed against the v2026.09.04-beta release's `linux-rt.config` differs only +in the Buildroot bump's gcc 15.3 symbols, the device-mapper and `FB_SYSMEM_FOPS` symbols that +landed on master after that beta, the cpio path, and host rustc probe values. Not yet booted on +the rig. diff --git a/docs/decisions/0029-de25-implementation-path.md b/docs/decisions/0029-de25-implementation-path.md index 2ef9d8e8..2a9bcb00 100644 --- a/docs/decisions/0029-de25-implementation-path.md +++ b/docs/decisions/0029-de25-implementation-path.md @@ -281,7 +281,7 @@ isolates the factory-SPL, DTS and SD-controller questions the first boot has to test kernel built from this board's own `linux.config`). 7/8 pass; the `symlink` case found that patch 0031 Oopses on every 7.x kernel (ADR 0002 §8b) — a fix is owed before the switch, and it applies to the DE10's RT kernel as well. The cpio is built and proven but NOT embedded - until the card switches (`external.mk` guard comment has the one-commit recipe). + until the card switches (`external.mk` guard comment had the one-commit recipe; since ADR 0030 (2026-09-11) the stage-1 cpio is `package/mister-initramfs` and the switch is `BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS=y` in the DE25 stack — `docs/de25-sdcard.md` §2). - **Re-open if.** The first hardware boot shows U-Boot cannot read the FAT boot files reliably, or Main_MiSTer's DE25 port needs a layout the loop root cannot provide. diff --git a/docs/decisions/0030-makefile-toward-vanilla-buildroot.md b/docs/decisions/0030-makefile-toward-vanilla-buildroot.md new file mode 100644 index 00000000..b9fd0c99 --- /dev/null +++ b/docs/decisions/0030-makefile-toward-vanilla-buildroot.md @@ -0,0 +1,569 @@ +# ADR 0030 — Shrinking the wrapper Makefile toward vanilla Buildroot + +**Status:** Accepted in direction (2026-09-11) — the owner accepted Phases B and C, the Makefile +and CI rewrite, the Kconfig profile package in place of Buildroot-config fragments (§5.7), and +Option G subject to its image-identity proof. **Landed:** Phases B and C (PR #166), then the +profiles + committed defconfigs + thin Makefile (branch `feat/vanilla-buildroot-defconfigs`); +each verified resolved-config-identical and `ci-tests.sh` green. Open: rig boot of both kernels, +Option G. +**Supersedes nothing.** Would amend [ADR 0002](0002-initramfs.md) (Phase B) and +[ADR 0021](0021-rt-kernel-first-class-ci.md) (Phase C) if those phases are accepted. +**Constraint:** the shipped artifacts stay byte-for-byte what they are today (`linux.img`, +`zImage_dtb`, `zImage_dtb-rt`, the sdcard images, the release asset set). Target names may change; +what is in the middle may change. +**Sources of record:** the wrapper `Makefile` (1,302 lines, read in full), `external.mk`, the pinned +Buildroot 2026.08 tree under `work/buildroot`, `.github/`, `scripts/`, and the ADRs cited inline. +Every Buildroot claim below was checked against that tree, not recalled. + +--- + +## 0. The interface goal (owner's framing, 2026-09-11) + +"Vanilla" here means the **same Makefile interface as a basic Buildroot project**: someone who +knows Buildroot should be able to clone this repo and type what they would type anywhere else. The +1,302-line Makefile with ~60 project-specific targets is the barrier. So the yardstick for every +option below is the newcomer's session, not the line count. + +| Task | Today | Goal | +|---|---|---| +| Configure the DE10 image | `make de10nano-defconfig` | `make mister_de10nano_defconfig` | +| Build it | `make all` (bare `make` prints help) | `make` | +| Build the RT kernel | `make rt` **before** `make all`, `make rt-clean` on bumps | nothing — it is part of `make` | +| Build stage 1 | `make initramfs` (implicit in `all`) | nothing — it is a package | +| Kernel menuconfig | `make linux-menuconfig`; `make rt-menuconfig` for RT | `make linux-menuconfig`; `make linux-rt-menuconfig` | +| Configure and build the DE25 | `make de25nano-defconfig && make de25` | `make O=output-de25 mister_de25nano_defconfig && make O=output-de25` | +| Clean one tree | `make clean` (all six at once, or fails) | `make clean` / `make O=output-de25 clean` | +| Regenerate a stale config after a Buildroot bump | `make rt-defconfig` (added today), `de10nano-defconfig`, … | `make mister_de10nano_defconfig` | +| Find out what a target does | read 1,300 lines | Buildroot's manual | + +The only thing the newcomer must learn that Buildroot does not teach is that the Buildroot tree is +fetched and hash-verified for them into `work/buildroot`. Everything else is Buildroot's own +vocabulary, including `O=` for the second board. + +### 0.1 The end-state Makefile, sketched + +Roughly this, plus comments and the pin block. It is the manual's "custom top Makefile" idiom with +the fetch step in front of it: + +```make +BUILDROOT_VERSION ?= 2026.08 +BUILDROOT_SHA256 ?= d678e810abf877d04513e03ca2c99f992dd49118b9c2e18d6e25f5f58fa8c5cd + +O ?= $(CURDIR)/output +export BR2_DL_DIR ?= $(CURDIR)/dl +BR := $(CURDIR)/work/buildroot +BR_STAMP := $(BR)/.stamp-$(BUILDROOT_VERSION) +BR_MAKE = $(MAKE) -C $(BR) O=$(O) BR2_EXTERNAL=$(CURDIR) + +.PHONY: all buildroot-unpack +all: $(BR_STAMP) + $(BR_MAKE) all + +$(BR_STAMP): + scripts/fetch-buildroot.sh $(BUILDROOT_VERSION) $(BUILDROOT_SHA256) $(BR) # download, verify, unpack + touch $@ +buildroot-unpack: $(BR_STAMP) + +Makefile: ; +%: $(BR_STAMP) + $(BR_MAKE) $@ +``` + +What is *not* in it, and where it went: + +- Six invocation variables, five `.config` rules, five `-defconfig` targets: gone; `make _defconfig` + and `O=` are Buildroot's. +- `initramfs`, `check-initramfs`, `initramfs-verify`, `de25-initramfs*`: Phase B's package and its + post-build hook. +- `rt`, `rt-clean`, the overlay, the stamps, `rt-legal-info`, `rt-external-deps`: Phase C's package. +- The PREEMPT_RT proof, the DE25 artifact assertions, the cpio applet checks: package post-build + hooks and `board/mister/*/post-image.sh`, which is where Buildroot puts such checks. +- `clean`/`distclean` across six trees: with one or two trees, Buildroot's own, per `O=`. `dl/` is + outside every `O=` and survives as before. +- `help`: Buildroot's `make help`, plus a ten-line `README` block naming the two defconfigs. +- `hostshim`: stays as a script the fetch step calls once, not a Makefile concept. +- The `%:` hazards: with no fragment prerequisites and no included makefiles, only `Makefile: ;` is + needed, which is exactly what Buildroot's own generated wrapper carries. + +Bare `make` becomes a build, as in Buildroot. On an unconfigured tree Buildroot's own message +appears ("Please configure Buildroot first"); the wrapper can prefix a one-line hint naming +`make mister_de10nano_defconfig`. The Makefile's help-by-default was premised on a defconfig with no +architecture, and its own comment marks that premise as expired. + +--- + +## 1. What the wrapper does today, and how much of it is wrapper + +The Makefile drives **six** Buildroot output trees, one per configuration: + +| Tree | Configuration | Why it is separate | +|---|---|---| +| `output/` | DE10 image (`common de10nano image-common de10nano-image`) | the product | +| `output-initramfs/` | stage-1 cpio (`initramfs-common initramfs-de10nano`), static musl BusyBox | a different libc needs a different toolchain, so a different `O=` | +| `output-initramfs-de25/` | the same stage 1 for aarch64 | different architecture | +| `output-rt/` | kernel-only PREEMPT_RT (`common de10nano kernel-only` + `mister_rt.fragment`) | a different kernel configuration in the same toolchain | +| `output-installer/` | sdcard installer cpio (`mister_installer_defconfig`) | static musl again, plus extra packages | +| `output-de25/` | DE25 developer OS | different architecture | + +Its responsibilities, sized by lines (comments included, since the comments are where the +load-bearing reasons live): + +| Responsibility | Lines | Vanilla Buildroot equivalent | +|---|---|---| +| Pin, download, SHA-verify, unpack Buildroot into `work/buildroot` | ~110 | none — Buildroot assumes it is already there | +| Build one `BR_MAKE_*` invocation per tree (six copies) | ~40 | Buildroot's own generated `$(O)/Makefile` forwards to the source tree with `O=` remembered | +| Generate each `.config` from a fragment stack (`merge_config.sh` + `olddefconfig`) and the `*-defconfig` regenerate targets | ~120 | `make _defconfig` from `configs/` — whole files only, no stacking | +| Orchestrate stage 1 before the kernel, stage RT modules into an overlay, stamps, `rt-clean`'s double removal | ~200 | none — one configuration per tree, no cross-tree dependencies | +| Post-build assertions (`check-initramfs`, `initramfs-verify`, PREEMPT_RT proof, DE25 artifact existence) | ~250 | post-build / post-image hook scripts | +| `clean` / `distclean` across six trees, extra-modules overlay lifecycle | ~60 | `make -C output clean` per tree | +| `help`, `br-help`, tombstone targets, `require-tools`, hostshim | ~150 | `make help` | +| Per-tree `menuconfig` / `busybox-menuconfig` / `linux-menuconfig` wrappers | ~40 | `make -C menuconfig` | +| The `%:` catch-all plus the four empty rules that keep it from recursing or loading a config into the wrong tree | ~40 | Buildroot's `$(O)/Makefile` uses `$(MAKECMDGOALS)`, which has neither hazard | +| `sdcard`, `zimage-dtb`, `installer` pass-throughs | ~30 | scripts / post-image hook (already the case) | + +Roughly 60% of the file exists because six configurations are orchestrated from one place, and +roughly 25% is assertion code that Buildroot's hook points could host. The pin/verify/unpack block +is the only part with no Buildroot-native home at all. + +### 1.1 What must survive any restructuring + +The three research passes (Buildroot mechanisms, CI and script consumers, design docs) converged on +this list. Anything not here is negotiable. + +**Artifact and boot (from ADR 0002, 0021, 0026, 0029; `docs/boot-chain.md`):** +- The stage-1 cpio is inside the zImage. U-Boot passes `-` for the initrd and never loads one. +- `BR2_TARGET_ROOTFS_INITRAMFS` is never set on an image config (A1: it embeds the whole rootfs). +- `zImage_dtb` under 16 MiB, enforced by `scripts/check-zimage-dtb.sh` from the post-image hook. +- The main rootfs is glibc (stock `MiSTer` links against it), so stage 1 is a *second* configuration + today rather than a flag. +- One `linux.img` carries every kernel variant's module tree. +- The RT kernel is proved RT (`CONFIG_PREEMPT_RT=y` in the built `.config`) and its module tree is + depmod'd; `merge_config.sh` only warns when a symbol is dropped. +- The DE25 kernel embeds nothing until D11 is closed, and never the armv7 cpio. +- Buildroot is pinned by version and SHA-256 taken from the signed manifest, verified before unpack, + with a version-qualified stamp; `SOURCE_DATE_EPOCH` derives from that pinned tree. + +**CI and script contract (from `.github/` and `scripts/`, cited in the research notes):** +- `BUILDROOT_VERSION ?=` and `BUILDROOT_SHA256 ?=` as single greppable lines in the root `Makefile`. + Four regexes and Renovate read them; the hash-sync rewrites the SHA line in place. +- `configs/fragments/stacks.mk` in its one-line-per-stack shape; three check scripts parse it as text. +- Repo-root output directory names: `output/`, `output-/`, `output-initramfs*/`, + `output-installer/`, `output-de25/`, `work/buildroot`, `work/.hostshim`, `work/extra-modules-overlay`, + `dl/`. Cache keys, artifact tars and every checker are built on them. +- Targets invoked by name from outside: `hostshim`, `de10nano-defconfig`, `all`, ``, + `-legal-info`, `-external-deps`, `buildroot-unpack`, `check-initramfs`, + `initramfs-verify`, `de25-initramfs-verify`, plus forwarded Buildroot targets (`legal-info`, + `external-deps`, `olddefconfig`, `azcopy`, `-dirclean`, `linux-rebuild`). +- Command-line and environment pass-through into Buildroot (`BR2_CCACHE*`, `AZCOPY_GO_ENV`, + `MISTER_INITRAMFS_CPIO`, `MISTER_VERSION`). +- The release asset set: seven main files, `zImage_dtb-` / `linux-.config` / + `legal-info-.tar.gz` per variant, sdcard images, azcopy. `SHA256SUMS` is the variant registry + for the publish job. +- `output/.config` has no file prerequisites (menuconfig edits survive); CI regenerates it with + `de10nano-defconfig` unconditionally. + +**Make-semantics hazards the current shape created (and which a different shape can simply avoid):** +the `%:` catch-all recursing on `Makefile`, forwarding a fragment path into Buildroot with the wrong +`O=`, `clean` falling through to one tree, `distclean` leaving `.config` behind, `-j` ordering of the +hostshim. None of these is a requirement; they are scars of the current design. + +--- + +## 2. What vanilla Buildroot 2026.08 offers (checked in the pinned tree) + +- **External defconfigs.** `make _defconfig` searches every `BR2_EXTERNAL` tree's `configs/` + (`Makefile:1049-1060`). `make list-defconfigs` lists them. Whole files only. +- **No fragment stacking for the Buildroot config.** There is no `BR2_CONFIG_FRAGMENT_FILES`. The + upstream precedent for stacking is `utils/test-pkg:174`, which calls + `support/kconfig/merge_config.sh` with `CONFIG_=""` on a base plus fragments — exactly what the + wrapper does. `support/scripts/check-dotconfig.py` asserts every line of a defconfig survived into + `.config`; upstream CI runs it after every `make _defconfig`. +- **Generated forwarding Makefile.** After the first configure, Buildroot writes `$(O)/Makefile` + (`support/scripts/mkmakefile`), so `make -C output ` works with `BR2_EXTERNAL` remembered + in `$(O)/.br2-external.mk`. `BR2_DL_DIR` and `BR2_CCACHE_DIR` are honoured from the environment + before `.config` is read (`Makefile:201-208`). This is the mechanism that makes a thin wrapper + possible: the wrapper is needed for the *first* command per tree, not for the rest. +- **The manual's own wrapper** (`docs/manual/customize-directory-structure.adoc:114-153`) is + fifteen lines: `%: configs/%` → `make -C buildroot O=output/ $@`. It handles only + `_defconfig` goals and leaves everything else to `make -C output/`. +- **Kernel dependency injection from an external.** `LINUX_DEPENDENCIES` cannot be extended from + `external.mk` (too late: `linux/linux.mk:700` has already expanded them). It *can* from + `$(BR2_EXTERNAL)/linux/linux-ext-*.mk`, included at `linux/linux.mk:643-644` before the eval. + `LINUX_KCONFIG_FIXUP_CMDS` and `_LINUX_CONFIG_FIXUPS` work from `external.mk` because the + fixup block expands at recipe time. This is the hook that lets a package produce the cpio and + make the kernel depend on it. +- **Same package, two configs.** `boot/barebox` builds a second barebox (`barebox-aux`) from the same + source with a different config inside one tree (`boot/barebox/barebox.mk:8-29,192-195`). The + kconfig-package infrastructure (`package/pkg-kconfig.mk`) is available to external packages and + gives `-menuconfig`, fragment merging, and patch application from `BR2_GLOBAL_PATCH_DIR` + for free. This is the precedent for a second kernel package. +- **Toolchain reuse across trees.** `make sdk` produces a relocatable toolchain + (`support/misc/relocate-sdk.sh`); a second tree consumes it with `BR2_TOOLCHAIN_EXTERNAL_PATH`. +- **Hooks.** `BR2_ROOTFS_POST_BUILD_SCRIPT`, `POST_FAKEROOT`, `POST_IMAGE` (space-separated lists, + exported `BR2_CONFIG`, `TARGET_DIR`, `BINARIES_DIR`, `HOST_DIR`, `BR2_EXTERNAL__PATH`). The DE10 + already uses post-build and post-image; the assertions the Makefile carries could live there. +- **Things Buildroot cannot do:** two toolchains in one tree; embed a cpio built elsewhere without + an external's help; delete from an overlay (`SYSTEM_RSYNC` has no `--delete`); make a bare `make` + on an unconfigured tree do anything but error; `distclean` a non-default `O=`. + +--- + +## 3. Two measurements that decide the shape + +**3.1 Stage 1 built with the main glibc toolchain.** The same `initramfs-busybox.config`, same +BusyBox 1.38.0 source with Buildroot's patches, linked `-static` with the DE10's own +`arm-buildroot-linux-gnueabihf-gcc` (the toolchain in `output/host`): + +| | musl static (today) | glibc static (measured 2026-09-11) | +|---|---|---| +| `busybox` | 263,308 B | 942,660 B | +| cpio today | 424,448 B | ≈ 1,100,000 B (estimate: BusyBox delta only) | +| gzipped inside the kernel | ≈ 134 KB (ADR 0002 §7) | ≈ 350–400 KB (estimate) | +| headroom under 16 MiB after the change | 7.47 MB (RT), more for main | ≈ 7.2 MB | + +ADR 0002 rejected glibc for stage 1 on two grounds: `BR2_STATIC_LIBS` is not offered with glibc, and +"Buildroot would still copy the shared glibc into the cpio". Both hold for a *Buildroot +configuration* and neither holds for a *package* that builds one static binary into its own staging +directory and produces the cpio itself. The size cost is real but small against the budget. + +**3.2 CI already serialises RT.** In the last green master run the RT kernel job ran 19 min and the +image job waited for it, then ran 3 h 05 min. A second kernel compiled *inside* the main build +replaces that 19-minute leg with roughly a kernel compile on a warm ccache. Wall clock is neutral to +slightly better; the parallelism ADR 0021 originally wanted was already given up in its 2026-07-18 +amendment. + +--- + +## 4. Options + +Each option is independent of the others except where stated. "Makefile after" is an estimate of +the wrapper's size with comments kept at today's density. + +### Option A — Mechanical consolidation, no behaviour change + +Keep every tree, every target name and every assertion; remove the duplication. + +- One `br_make` function taking the `O=` directory; the six `BR_MAKE_*` variables go. +- One table of trees (name, `O=` dir, stack) and pattern rules `%-defconfig`, `%-menuconfig`, + `%-clean` derived from it. The five hand-written copies of each go. +- Move every assertion body into `scripts/` (`assert-rt-kernel.sh`, `assert-de25-artifacts.sh`; + `initramfs-verify` and `check-initramfs` already have the shape of scripts). The Makefile calls + them. `ci-tests.sh` keeps calling the targets, which keep their names. +- Replace the `%:` catch-all with Buildroot's own idiom: forward `$(MAKECMDGOALS)` through one + `_all` rule. The four empty rules and the recursion hazard disappear with it. +- Fix the one inconsistency found: `$(INSTALLER_OUTPUT_DIR)/.config` is the only config rule with a + real file prerequisite and no hostshim ordering. + +Makefile after: ≈ 400 lines. Risk: low; every consumer in §1.1 is untouched. This is the floor and +should happen regardless of what else is chosen. + +### Option B — Stage 1 becomes a package of the main build (amends ADR 0002) + +A br2-external package `mister-initramfs` builds a static BusyBox with the main toolchain from +`board/mister/common/initramfs-busybox.config`, lays down the `/init` overlay, runs today's +post-build trimming, and installs `mister-initramfs.cpio` into `$(BINARIES_DIR)`. A +`linux/linux-ext-mister-initramfs.mk` in the external adds it to `LINUX_DEPENDENCIES`; the existing +`LINUX_KCONFIG_FIXUP_CMDS` block points `CONFIG_INITRAMFS_SOURCE` at it. The verify checks (applet +list, forbidden binaries, `/dev/console`, `ash -n /init` under qemu) become the package's +post-build hook, failing the package. + +Removes: `output-initramfs/`, `output-initramfs-de25/`, the `initramfs*` and `de25-initramfs*` +targets, `check-initramfs` (the kernel fixup now cannot run without the cpio, so the assertion is +structural), the initramfs host cache in CI, the `initramfs-common`/`initramfs-*` stacks and their +two golden lines. `make all` is `make -C output all`. + +The DE25 gets the same package for aarch64 for free; the D11 switch becomes one Kconfig line in the +DE25 stack instead of a six-file commit. `mk-sdcard.sh`'s installer relink keeps working: the +`MISTER_INITRAMFS_CPIO` override becomes a package variable override. + +Cost: the cpio grows by roughly 700 KB uncompressed (§3.1), the `arch`-gated fixup in `external.mk` +becomes a `BR2_PACKAGE_MISTER_INITRAMFS` gate (ADR 0002 rejected a bool because it moved the +toolchain-fingerprint cache key; that cost is paid once). The stage-1 cpio was byte-reproducible via +`BR2_REPRODUCIBLE`; a package build inherits the same setting from the main config. + +Makefile after (with A): ≈ 250 lines. Risk: medium. New package code (~120 lines) replaces ~350 +lines of Makefile plus two stacks; the risk is concentrated in one reviewable package. + +### Option C — RT kernel becomes a second kernel package of the main build (amends ADR 0021) + +A kconfig-package `linux-rt` in the external, modelled on barebox-aux: same tarball as the +`linux` package's 7.2.x pin via `BR2_GLOBAL_PATCH_DIR`'s `linux-rt/` (a symlink to +`linux-patches-beta/`, whose `series` file Buildroot's `apply-patches.sh` honours), the RT kernel +config fragment, `zImage` + DTB concatenated to `$(BINARIES_DIR)/zImage_dtb-rt`, and +`modules_install` into `$(TARGET_DIR)`. The PREEMPT_RT proof and the depmod'd-tree check become the +package's post-build hook. `linux-rt-menuconfig` comes with the infrastructure. + +Removes: `output-rt/`, the extra-modules overlay and its stamp, `rt-clean`'s two-place deletion (no +overlay means no rsync-never-deletes problem), the `rt` before `all` ordering rule, `rt-defconfig`, +`rt-menuconfig`, `rt-external-deps`, `rt-legal-info`, the `build-kernel` matrix job, the +`kernel-leg` and `merge-kernel-modules` actions, and the per-variant host cache. One `make -C output +all` produces both kernels and the one `linux.img` natively. + +Changes the release contract: `legal-info-rt.tar.gz` folds into `legal-info.tar.gz` (the single +`legal-info` covers every package), and `linux-rt.config` is read from +`output/build/linux-rt-*/.config`. The publish job's variant registry (derived from `SHA256SUMS`) +needs a matching edit. The `configs/mister_.fragment` registry becomes a Kconfig option per +variant; `scripts/list-kernel-variants.sh` reads Kconfig instead of the filesystem. + +Cost: ~150 lines of package `.mk` reimplementing what `linux.mk` does for the second kernel (patch, +configure with fragments, build `zImage` and modules, install). `make rt` alone is no longer a +thing; locally an RT-less build is `BR2_PACKAGE_LINUX_RT=n`. CI wall clock is neutral (§3.2). + +Makefile after (with A and B): ≈ 150 lines. Risk: medium-high, mostly in CI rewiring (three +actions and two workflows) rather than in the build itself. + +### Option D — Generated defconfigs committed next to the fragments + +Keep `configs/fragments/` as the source of truth, but generate `configs/mister__defconfig` +(the `savedefconfig` of the merged stack) and commit it. A CI check regenerates and diffs; upstream's +`check-dotconfig.py` runs after every `make _defconfig`, as in upstream's own CI. + +Gains: `make -C work/buildroot O=$PWD/output BR2_EXTERNAL=$PWD mister_de10nano_defconfig` is fully +vanilla, with no wrapper involved. The golden-hash mechanism becomes redundant: the resolved change +that the DE25 uClibc regression hid behind an opaque hash on the 2026.08 bump would have appeared as +a reviewable diff in the committed defconfig. `savedefconfig` round-trips to a file whose diff is +the change. + +Cost: two representations in git; every fragment edit must regenerate (a pre-commit hook or the CI +diff enforces it). The `-defconfig` regenerate targets stay only as aliases. + +Makefile impact: neutral; this is about where the config generator lives, not how large the +Makefile is. Independent of A–C. + +### Option E — Buildroot as a git submodule instead of a pinned tarball + +Rejected on project grounds, recorded for completeness. The pinned, signed-manifest-verified tarball +is the settled pattern (G4/G6, TASKS standing rule 1; the U-Boot submodule proposal in ADR 0017 was +superseded by ADR 0024 in favour of the same idiom). Renovate, the hash-sync case 6 and three +scripts are built on the two pin lines. A submodule would move ~110 lines out of the Makefile at the +price of re-deriving `SOURCE_DATE_EPOCH` and the supply-chain story. Not recommended. + +### Option F — Share the toolchain between the trees that remain (`make sdk`) + +Only relevant if C is *not* taken: `output-rt` would consume `output/`'s relocated SDK as an +external toolchain, removing the 16-minute toolchain rebuild and the per-variant host cache. It is a +config change (`BR2_TOOLCHAIN_EXTERNAL_*` in `mister_rt.fragment`) plus one `make prepare-sdk` step, +and adds a dependency of the RT tree on the main tree's host directory. Strictly worse than C for +simplicity; listed as the fallback if C is refused. + +--- + +## 5. Recommendation (revised 2026-09-11 after the owner's answers) + +The owner answered Q1 and Q2 the same day: a glibc-static stage 1 is acceptable, and moving RT +into the main build serially is *wanted*, on the grounds that the pipeline leans too hard on +GitHub's best-effort cache and a cache miss can rebuild a toolchain more than once per run. CI +simplification is in scope for this workstream. That changes the plan in three ways. + +**One correction to the premise first.** The 16 MiB kernel budget has nothing to do with SD card +size. It is U-Boot's memory map: the kernel is loaded at `0x01000000` and `menu.rbf` is staged at +`0x02000000`, so a `zImage_dtb` past 16 MiB overwrites the FPGA bitstream buffer +(`docs/boot-chain.md` §7.3). The conclusion stands, because the measured headroom is 7.4 MB on the +larger RT kernel and stage 1 is fixed-purpose, but the reasoning to carry forward is "RAM layout", +not "card size". + +### 5.1 Phase A is folded away + +A standalone consolidation pass would refactor the six-tree orchestration that Phases B and C then +delete. With B and C accepted in principle, the Makefile is rewritten once, at the end, around what +remains. What A contributed survives as rules for that rewrite: one invocation function, a table of +trees, assertions in scripts or hooks, Buildroot's `$(MAKECMDGOALS)` forwarding idiom instead of `%:`. + +### 5.2 Order of work + +1. **B — stage 1 as a package** (`package/mister-initramfs/`, `linux/linux-ext-mister-initramfs.mk`, + ADR 0002 amendment). Deletes `output-initramfs*`, two stacks, the initramfs host cache. Gate: + boot on the rig plus the eight `test-initramfs.sh` cases plus the `zcat usr/initramfs_inc_data | + cmp` identity check. The DE25 gets the aarch64 build of the same package; D11 stays closed until + the owner says otherwise, now as one Kconfig line. +2. **C — RT as `package/linux-rt/`** (kconfig-package, barebox-aux pattern, ADR 0021 amendment). + Deletes `output-rt`, the overlay, the stamps, `build-kernel`, `kernel-leg`, + `merge-kernel-modules`, the variant host and dl caches. One `make all` yields both kernels and the + one `linux.img`. Release assets: `legal-info-rt.tar.gz` folds into `legal-info.tar.gz`; + `zImage_dtb-rt` and `linux-rt.config` are still published, now read from `output/`. +3. **Makefile rewrite** to the thin form (§5.4), same PR as the CI rewrite below or the one after. +4. **D — committed generated defconfigs**, at any point; it is orthogonal. + +### 5.3 CI after B and C + +Today the composite build action holds **seven** caches (tarball, main dl, variant dl, main host +toolchain, variant host toolchain, initramfs host toolchain, ccache) across 640 lines, plus the +kernel leg and module-merge actions (353 lines) and a matrix job. After B and C: + +- **Four caches**: tarball, dl, one host toolchain, ccache. The toolchain fingerprint machinery + keys one cache instead of three, or goes entirely with Option G below. +- **One build job** in `build.yml` (`gate → lint-config → build → status`); the `build-kernel` + matrix, `kernel-leg` and `merge-kernel-modules` are deleted. `release.yml` loses the same matrix + and the per-variant asset staging; the publish job's variant registry becomes a fixed list. +- **Worst case on a cache miss is one toolchain build**, because there is one tree. Today it is up + to three. +- `list-kernel-variants.sh` reads Kconfig symbols instead of `configs/mister_*.fragment`; the two + `hashFiles()` lists and their `check_hashfiles` assertions shrink to one. + +### 5.4 Option G — the toolchain as a pinned, hash-verified artifact instead of a cache + +This is the lever that removes the dependence on caching rather than reducing it. Buildroot has a +first-class, vanilla mechanism for it: a br2-external can ship a **toolchain package** +(`provides/toolchains.in` plus `toolchain/toolchain-external-mister/` using +`toolchain-external-package`, `docs/manual/customize-outside-br.adoc` "toolchains"), which is a +normal package with `_SITE`, `_SOURCE` and a `.hash` file, so the download is hash-verified like +every other package. The upstream ARM and Bootlin toolchains are packaged exactly this way +(`toolchain/toolchain-external/toolchain-external-arm-arm/` ships a `.hash`). Note that the *other* +route, `BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD` with a custom URL, explicitly cannot verify hashes +(`toolchain-external-custom.mk:11`) and is not proposed. + +Shape: +- A `toolchain.yml` workflow, manual or triggered by a Buildroot pin change, runs `make sdk` on a + kernel-only-style config and publishes `arm-buildroot-linux-gnueabihf_sdk-buildroot.tar.gz` plus + its sha256 as assets of a `toolchain-YYYYMMDD` release. The same for the DE25's aarch64 SDK. +- The image config selects that toolchain package; its `.hash` pins the bytes. Buildroot checks the + declared gcc, glibc and kernel-headers properties against the SDK at configure time and fails on + mismatch, so a stale pin cannot go unnoticed. +- The build job downloads ~100 MB instead of restoring a ~1 GB cache or compiling for 20 minutes. + A fresh local clone gets a first build in minutes. + +Costs and the one open risk: +- "No binaries in git" is respected (a release asset, like azcopy), but the project now ships a + toolchain it built. The SDK is built from the pinned Buildroot with the pinned config, so its + inputs are pinned; the bump discipline is "Buildroot pin moves → toolchain release first". +- **Artifact identity must be measured, not assumed.** An external-toolchain build installs the + target libc from the SDK's sysroot (`copy_toolchain_lib_root`) rather than through the internal + glibc package's install rules. The bytes of `libc.so` are the same, but which locale, gconv and + debug files land in the image can differ. The gate for G is a `linux.img` content diff against an + internal-toolchain build of the same commit, with any difference explained or eliminated before + the switch. If it cannot be made identical, G is dropped and the single host cache stays. +- Reproducibility (A9) keeps its meaning: same pinned inputs, same output. The + `.br-toolchain-fingerprint` file and its sentinels become unnecessary. + +Recommendation: do G **after** C, as its own PR with the identity measurement in the PR body. It is +the largest single CI simplification available, and the one that answers the stated worry directly. + +### 5.5 Target mapping if everything lands + +| Today | After | +|---|---| +| `make de10nano-defconfig` | `make mister_de10nano_defconfig` (CI alias kept for one release) | +| `make all` | `make all` (forwards to `output/`) — unchanged name | +| `make initramfs`, `make check-initramfs`, `make initramfs-verify` | gone; the package fails the build instead | +| `make rt`, `rt-defconfig`, `rt-menuconfig`, `rt-clean`, `rt-legal-info`, `rt-external-deps` | gone; `make linux-rt-menuconfig`, `BR2_PACKAGE_LINUX_RT` | +| `make de25`, `de25nano-defconfig`, `de25-*` | `make mister_de25nano_defconfig`; `make -C output-de25 all`; assertions in `board/mister/de25nano/post-image.sh` (already the card's hook) | +| `make de25-initramfs*` | gone; `BR2_PACKAGE_MISTER_INITRAMFS=y` in the DE25 stack when D11 closes | +| `make installer*` | unchanged (`mk-sdcard.sh` owns it) | +| `make clean` / `distclean` | loop over the trees that exist; `dl/` kept | +| `make buildroot-unpack`, `buildroot-verify`, `buildroot-showsig`, `hostshim` | unchanged (CI contract) | +| `make ` | forwarded to `output/` as today | + +End state: one DE10 tree, one DE25 tree, one installer tree driven by `mk-sdcard.sh`; a wrapper of +roughly 150 lines whose only non-vanilla job is pin/verify/unpack; a build workflow with one build +job and four caches, or three if G lands. + +### 5.6 Touch list per phase (from the consumer map) + +- **B:** `package/mister-initramfs/`, `linux/linux-ext-mister-initramfs.mk`, `external.mk` (fixup + gate), `configs/fragments/` (delete two stacks, add one symbol), `golden.sha256`, + `.github/actions/buildroot-build/action.yml` (drop the initramfs host cache and the + `INITRAMFS_DE10NANO` stack reads), `scripts/ci-tests.sh` (drop three target calls), + `scripts/test-initramfs.sh` (cpio path), `scripts/mk-sdcard.sh` (override variable name), + `docs/decisions/0002-initramfs.md` amendment, README build section. +- **C:** `package/linux-rt/`, `board/mister/de10nano/patches/linux-rt` symlink, `configs/fragments/` + (variant symbol), `.github/workflows/build.yml` and `release.yml` (drop `build-kernel`, adjust + assets), delete `kernel-leg` and `merge-kernel-modules` actions, `scripts/list-kernel-variants.sh`, + `docs/decisions/0021` amendment, `docs/rt-beta-kernel.md` §5. +- **Makefile rewrite + CI:** `Makefile`, `.github/actions/buildroot-build/action.yml` (four caches), + `docs/ci.md`, README. +- **D:** `scripts/gen-defconfigs.sh` (new), `configs/mister_*_defconfig` (generated), + `scripts/check-config-fragments.sh` (diff instead of hash), `lint.yml`. +- **G:** `toolchain/toolchain-external-mister/`, `provides/toolchains.in`, `.github/workflows/toolchain.yml` + (new), `configs/fragments/de10nano.fragment` (toolchain selection), the identity measurement. + +--- + +### 5.7 Sharing between the DE10 and the DE25: what the shared layers actually contain + +The owner's stated direction (2026-09-11) is two architectures with a nearly identical userspace and +similar kernels, maintained in one place. Whether the fragment generator is the right tool for that +depends on what the shared lines *are*, so they were counted: + +| Layer | symbols | `BR2_PACKAGE_*` | everything else | +|---|---|---|---| +| `common` (shared by all stacks) | 7 | 0 | 7 (toolchain C++, hash check, kernel on, DTS, reproducible, merged-usr) | +| `image-common` (shared DE10/DE25) | 31 | 31 | 0 | +| `de10nano-image` | 228 | 213 | 15 (ext4 sizing/UUID, eudev, bash, locale, timezone, overlay, post-build) | +| `de10nano` | 16 | 1 | 15 (arch, toolchain, kernel pin, patches, DTS, post-image) | +| `de25nano` | 46 | 6 | 40 (arch, toolchain, kernel, U-Boot, TF-A, card) | + +The userspace that is to be shared is **packages**, overwhelmingly. Buildroot shares packages +between boards natively, without a generator: a **profile package** in the external's `Config.in` +(`BR2_PACKAGE_MISTER_USERSPACE`, a bool that `select`s the package set) — the same shape as any +upstream package that pulls in its dependencies, visible in `make menuconfig` under "External +options" as one checkbox. Board-only packages (`aic8800`, `azcopy`, later the MiSTer binaries) stay +as explicit lines in the board's defconfig or in a second, explicitly named profile +(`BR2_PACKAGE_MISTER_DE10_EXTRAS`), which turns `docs/buildroot-config.md`'s rule 5 ("no DE10 +package reaches the DE25 without a decision") from a review convention into Kconfig structure. + +The rest of the sharing already uses Buildroot's list-valued options and needs no generator: + +- **Kernel drivers:** `BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES` pointing at + `board/mister/common/linux-mister.fragment` — the DE25 stack does this today; the DE10 would adopt + it, keeping a per-SoC base `linux.config` under each board. Known cost, already accepted for the + DE25: `linux-update-defconfig` refuses to round-trip a fragment-built config, so edits go through + `linux-diff-config` and a hand fold. +- **Overlay, patches, hook scripts:** `BR2_ROOTFS_OVERLAY`, `BR2_GLOBAL_PATCH_DIR`, + `BR2_ROOTFS_POST_*_SCRIPT` are space-separated lists; `board/mister/common/` plus + `board/mister//` is the manual's documented layering + (`customize-directory-structure.adoc` §"layered customizations"). + +What cannot be shared natively is the non-package remainder: about 20 system-level lines (rootfs +size and UUID, locale, timezone, shell, device manager, reproducibility, hash checking). Those are +duplicated in the two defconfigs, and one lint asserts the named list agrees between them. That is +the whole cost, and it is smaller than the generator, the golden hash and the stack lockstep checks +it replaces. + +**Caveat to document for newcomers (owner, 2026-09-11).** This *is* a departure from a plain +Buildroot project in one respect: in a plain project every top-level package choice is a line in +the defconfig, whereas here the shared userspace is one `BR2_PACKAGE_MISTER_USERSPACE` line whose +contents live in `package/mister-userspace/Config.in`. That is idiomatic Kconfig, but a reader +looking for "why is `bluez5_utils` in my image" must know to look in the profile, not the +defconfig. Three pointers cover it: the profile's own Kconfig help text (visible in `menuconfig`), +a README paragraph under "Building it yourself", and a two-line note at the top of the wrapper +Makefile. Nothing else in the build differs from the manual's description. + +**Recommendation for Q3:** retire the Buildroot-config fragment layer once B and C land, and move +the sharing to the profile package plus the list-valued options. Two committed defconfigs of +roughly 50 lines each become the only source; `make mister_de10nano_defconfig` is fully vanilla; +`savedefconfig` round-trips; `make menuconfig` shows the shared userspace as one option. Keep +`check-config-fragments.sh` only as the ~20-line shared-remainder diff. Caveat to mirror in the +profile: `select` force-enables a package even when its own `depends on` is unmet (kconfig warns), +so arch-limited packages must not be selected unconditionally; that is exactly why they belong in +the board defconfig or an arch-gated profile. + +## 6. Questions for the owner + +1. ~~Is a larger compressed kernel acceptable (Phase B)?~~ **Yes, 2026-09-11.** +2. ~~Is losing the separate RT legal-info asset and the parallel kernel job acceptable (Phase C)?~~ + **Yes, 2026-09-11**; serial RT is wanted for cache reasons. +3. **Fragments after B and C** — see §5.7: the shared userspace is packages, which a Kconfig + profile shares natively; recommendation is to retire the fragment generator for two plain + defconfigs plus the profile. Owner to confirm. +4. Keep the `output-` directory names? Recommended yes. +5. **New:** Option G, the toolchain as a hash-verified release asset. Yes in principle, subject to + the image-identity measurement? + +--- + +## 7. Research notes (where each claim came from) + +- Buildroot mechanisms: `work/buildroot/Makefile` 33-87, 189-208, 599-609, 973-984, 1043-1070, + 1086-1090, 1139-1151; `support/scripts/mkmakefile`; `support/kconfig/merge_config.sh`; + `utils/test-pkg:174`; `support/scripts/check-dotconfig.py`; `linux/linux.mk` 408-420, 643-644, + 700-716; `package/pkg-kconfig.mk`; `boot/barebox/barebox.mk` 8-29, 192-195; + `docs/manual/customize-directory-structure.adoc` 114-153. +- Consumers: `.github/actions/buildroot-build/action.yml` 182-306, 456-542; + `.github/workflows/release.yml` 243-300, 460-467, 674-737, 800-898; + `scripts/lib/config-stacks.sh`; `scripts/check-config-fragments.sh` 172-305, 426-491; + `scripts/mk-sdcard.sh` 29-46, 101-175, 351-482; `scripts/ci-tests.sh` 26-28, 269-312. +- Constraints: ADR 0002 §3, §7, §8a, §10; ADR 0021 §2-4 and its 2026-07-18/07-27 amendments; + ADR 0026; ADR 0029 D11; `docs/boot-chain.md` §7.3, §8.2; `docs/buildroot-config.md` §1, §5.1, + §7, §8, §11; `external.mk` 32-135, 140-174. +- Measurements: static glibc BusyBox built 2026-09-11 in `/mnt/source/bb-static-measure`; CI job + times from run 34560109238. diff --git a/docs/firmware-parity.md b/docs/firmware-parity.md index d1eaa215..59b9f749 100644 --- a/docs/firmware-parity.md +++ b/docs/firmware-parity.md @@ -108,7 +108,7 @@ build. This is the P3.3 deliverable for the **firmware population** half of "Module loading & firmware infra" (TASKS.md). The **module-autoload** half (kmod/depmod/eudev/xz-compression) was already done — see the P3.3 (core) -commit and `configs/fragments/de10nano-image.fragment`'s `BR2_PACKAGE_HOST_KMOD_XZ` / +commit and `configs/mister_de10nano_defconfig`'s `BR2_PACKAGE_HOST_KMOD_XZ` / `BR2_PACKAGE_KMOD_TOOLS` lines. This document covers only `/lib/firmware`. **Target:** `docs/stock-inventory/20250402/firmware.md` — the authoritative 66-file @@ -154,7 +154,7 @@ Config.in reasoning: > The original P3.3 run measured 56 present / 10 missing. `brcm/BCM20702A1-0b05-17cb.hcd` > was subsequently sourced by `package/bcm20702-firmware` (P3.14, -> `BR2_PACKAGE_BCM20702_FIRMWARE=y` at `configs/fragments/image-common.fragment` +> `BR2_PACKAGE_BCM20702_FIRMWARE=y` at `package/mister-firmware/Config.in` > (it was in `de10nano-image.fragment` until 2026-09-03, `docs/buildroot-config.md` §12.2); > `scripts/ci-tests.sh` fails the build if it is absent from the image), which is what > moves present 56→57 and flagged 2→1. The obsolete count was independently a miscount: @@ -234,9 +234,9 @@ driver exists to use them (harmless unused bytes, not a gap). ## defconfig changes -These lines were added to `configs/fragments/de10nano-image.fragment` after +These lines were added to `configs/mister_de10nano_defconfig` after the P3.2 block. **Since 2026-09-03 they live in -`configs/fragments/image-common.fragment`** — the layer shared by every board's +`package/mister-firmware/Config.in`** — the layer shared by every board's image stack — because the DE25-Nano image adopted the same set for parity (owner decision; `docs/buildroot-config.md` §12, and §12.1 for the full sub-option table this document feeds). The symbols and their rationale are diff --git a/docs/init-parity.md b/docs/init-parity.md index 2c7bb862..1ca802a2 100644 --- a/docs/init-parity.md +++ b/docs/init-parity.md @@ -22,10 +22,10 @@ read from `output/target/` **after** P2.1's full package-set build but **before* this task's overlay was wired in, so the diffs are genuinely against what Buildroot's packages install unprompted, not against a strawman. The overlay itself lives at `board/mister/de10nano/rootfs-overlay/` and is wired via `BR2_ROOTFS_OVERLAY` in -`configs/fragments/de10nano-image.fragment` (added by this task; previously unset for the +`configs/mister_de10nano_defconfig` (added by this task; previously unset for the full-rootfs build — only the initramfs defconfig had its own overlay). -Build verified: `make de10nano-defconfig && make all` completed clean, +Build verified: `make mister_de10nano_defconfig && make all` completed clean, `output/images/rootfs.tar` (180 MB) and `output/images/zImage_dtb` (8,771,237 bytes, `check-zimage-dtb.sh` all-pass) both produced. All claims below were checked against `output/images/rootfs.tar`, extracted fresh, with the actual commands and output @@ -177,7 +177,7 @@ mechanism that wasn't there. It was flagged here rather than silently left out, not affect SSH or networking (P2.3's hard requirements), which is why it wasn't a blocker. **This gap is now closed.** `BR2_PACKAGE_USBMOUNT=y` is set in -`configs/fragments/de10nano-image.fragment`, the stock-tuned `usbmount.conf` ships in the overlay, +`configs/mister_de10nano_defconfig`, the stock-tuned `usbmount.conf` ships in the overlay, and util-linux `mount` plus a `mount.ntfs -> ntfs-3g` helper make NTFS drives mount the way they do on stock. See **`docs/usb-automount-parity.md`** for the full picture. diff --git a/docs/kernel-export.md b/docs/kernel-export.md index 3be3478f..afd7bbb8 100644 --- a/docs/kernel-export.md +++ b/docs/kernel-export.md @@ -181,7 +181,7 @@ exercised, the driver contents were not. | Step | Result | |---|---| -| **Export script bug found and fixed** | It read `BR2_PACKAGE_*=y` from `configs/fragments/de10nano.fragment` only; the 2026-09 fragment split moved those lines to `de10nano-image.fragment`, so the script's own "zero kernel-module packages" guard would have **aborted every export since**. It now resolves the DE10 stack from `configs/fragments/stacks.mk` via `scripts/lib/config-stacks.sh` and reads all four fragments, last-wins | +| **Export script bug found and fixed** | It read `BR2_PACKAGE_*=y` from `configs/mister_de10nano_defconfig` only; the 2026-09 fragment split moved those lines to `de10nano-image.fragment`, so the script's own "zero kernel-module packages" guard would have **aborted every export since**. It now resolves the DE10 stack from `configs/mister_*_defconfig` via `scripts/lib/config-stacks.sh` and reads all four fragments, last-wins | | Export (`--parent d9ac12a691`, `--fork-sync c129b0fac`) | PASS, 48 commits: base `v6.18.49` → 40 carried → 1 upstream-only → defconfig → **DTS alias** → 2 vendored → build script → `EXPORT.md`; tag `mister-6.18.49` | | Emulated Buildroot tree (tarball + `linux-patches/*.patch` at `-F0`) | 40/40 applied, offsets only (max +49), no fuzz | | `check-export-tree.sh --build-dir … --llvm` | **PASS — 19 checks, 1 skipped**: 88,335 files byte-identical between the export's carried tip and the Buildroot-style tree; resolved configuration identical (3,744 symbols); `socfpga_cyclone5_de10_nano.dtb` (his name) and `socfpga_cyclone5_de10nano.dtb` (vanilla's) byte-identical, sha256 `199f14b1…3dae`, and equal to the build dir's DTB; `zImage` skipped only because the host lacks `lz4` for the final compression step (the tree compiled through `vmlinux` in an earlier full run) | diff --git a/docs/logitech-pairing.md b/docs/logitech-pairing.md index 9af2bfb6..7099285a 100644 --- a/docs/logitech-pairing.md +++ b/docs/logitech-pairing.md @@ -294,7 +294,7 @@ glibc 2.43): * **`read-dev-usbmon` correctly not built**, and `ltunify --version` reports the pinned SHA rather than an empty string. -`make de10nano-defconfig` against the external tree resolves +`make mister_de10nano_defconfig` against the external tree resolves `BR2_PACKAGE_LTUNIFY=y`, leaves `BR2_PACKAGE_LIBEXECINFO` unselected (correct on a glibc toolchain), and `LTUNIFY_SOURCE` matches the filename on the `.hash` line character for character. diff --git a/docs/main-shared-libs.md b/docs/main-shared-libs.md index 02f874a4..4c81ea9f 100644 --- a/docs/main-shared-libs.md +++ b/docs/main-shared-libs.md @@ -11,7 +11,7 @@ consumer: which package provides what, under which SONAME/header-dir/pkg-config name, and how Main's vendored dirs map onto them. Three of the five packages are upstream Buildroot, enabled straight from -`configs/fragments/de10nano-image.fragment` (compression block); the other two are +`configs/mister_de10nano_defconfig` (compression block); the other two are authored in this tree under `package/` and sourced via the "Main_MiSTer shared libraries" menu in the top-level `Config.in`. diff --git a/docs/midi-mt32-parity.md b/docs/midi-mt32-parity.md index ff76c32d..14b90072 100644 --- a/docs/midi-mt32-parity.md +++ b/docs/midi-mt32-parity.md @@ -204,7 +204,7 @@ BR2_PACKAGE_ALSA_UTILS_ASEQNET=y (`BAT`), `iecset`, `speaker-test` — are present in stock (`docs/stock-inventory/20250402/binaries-needed-full.txt`) but are general ALSA audio parity, not MIDI parity. **P3.15 — General ALSA userland parity** subsequently owned and closed this: -`configs/fragments/de10nano-image.fragment` now sets +`configs/mister_de10nano_defconfig` now sets `BR2_PACKAGE_ALSA_UTILS_{ALSACTL,ALSALOOP,ALSAMIXER,ALSATPLG,ALSAUCM,AMIXER,APLAY,BAT,IECSET,SPEAKER_TEST}=y` (`TASKS.md` P3.15, marked done). The general ALSA userland parity should pick this up. **A genuine gap in this Buildroot @@ -227,7 +227,7 @@ around (e.g. by hand-adding a custom install rule) for this task. - `package/midilink/{Config.in,midilink.mk,midilink.hash}` — new. - `Config.in` (repo root) — added a `"MIDI / MT-32 (P3.8)"` menu sourcing both new packages' `Config.in`. -- `configs/fragments/de10nano-image.fragment` — added `BR2_PACKAGE_MUNT=y`, +- `configs/mister_de10nano_defconfig` — added `BR2_PACKAGE_MUNT=y`, `BR2_PACKAGE_MIDILINK=y`, `BR2_PACKAGE_ALSA_UTILS=y` + six MIDI-specific `BR2_PACKAGE_ALSA_UTILS_*` suboptions, right after the existing FluidSynth block. diff --git a/docs/package-manifest.md b/docs/package-manifest.md index 33326cf9..b1d816d0 100644 --- a/docs/package-manifest.md +++ b/docs/package-manifest.md @@ -800,7 +800,7 @@ surprise found while adding it):** | `exfatprogs` | `mkfs.exfat`, `fsck.exfat`, `exfatlabel`, `dump.exfat`, `exfat2img`, `tune.exfat` | no sub-options, no collision (BusyBox has no exFAT support at all) | | `ntfs-3g` `NTFSPROGS` sub-option | `mkfs.ntfs` (→ `mkntfs`), `ntfsfix`, + the rest of ntfsprogs | **found missing despite `BR2_PACKAGE_NTFS_3G` already being `=y`** since P2.1 — a real oversight, not a deliberate omission: the sub-option defaults to "n" with no dependency of its own (`package/ntfs-3g/Config.in`), and without it `ntfs-3g.mk` passes `--disable-ntfsprogs`. Fixed in place next to the existing `BR2_PACKAGE_NTFS_3G=y` line | | `tmux` | `tmux` | chosen over `screen` (§5) — not both. Needs `BR2_USE_WCHAR`+`BR2_ENABLE_LOCALE` (both true); selects `LIBEVENT`+`NCURSES`, both already on | -| `strace` | `strace` | **BEYOND STOCK, not a gap closed** — `find work/imgroot -name strace` returns nothing. Already enabled *temporarily* by the `DEBUG TOOLING` block (`docs/debug-tooling.md`); this promotes it to a *permanent* part of the package set so it keeps shipping once that block is eventually deleted (and is what `docs/package-manifest.md` §5's `ltrace` row leans on when it rejects ltrace). Set in both places deliberately (harmless, same value — `make de10nano-defconfig` prints a benign "override: reassigning to symbol BR2_PACKAGE_STRACE") | +| `strace` | `strace` | **BEYOND STOCK, not a gap closed** — `find work/imgroot -name strace` returns nothing. Already enabled *temporarily* by the `DEBUG TOOLING` block (`docs/debug-tooling.md`); this promotes it to a *permanent* part of the package set so it keeps shipping once that block is eventually deleted (and is what `docs/package-manifest.md` §5's `ltrace` row leans on when it rejects ltrace). Set in both places deliberately (harmless, same value — `make mister_de10nano_defconfig` prints a benign "override: reassigning to symbol BR2_PACKAGE_STRACE") | | `lsof` | `usr/bin/lsof` | **An UPGRADE over stock, not parity restoration** — stock's `usr/bin/lsof` is a symlink → `../../bin/busybox`, so stock's provider is the BusyBox applet, and choosing the real lsof is a deliberate divergence (worth it: the applet has no network-socket, NFS, `-p` or `-i` support). Needs `BUSYBOX_SHOW_OTHERS`, already on (for `i2c-tools`); **collides with BusyBox's own `lsof` applet**, already on — disabled in `busybox.fragment` | | `tcpdump` | `tcpdump` | **BEYOND STOCK, not a gap closed** — `find work/imgroot -name tcpdump` returns nothing. Added anyway for on-device WiFi/network debugging (P3.4 territory). Selects `LIBPCAP` automatically; `TCPDUMP_SMB` ("possibly-buggy" per its own Config.in) deliberately left off | | `iperf3` | `iperf3` | **BEYOND STOCK, not a gap closed** — `find work/imgroot -name 'iperf*'` returns nothing (no iperf2 either). Added anyway: throughput measurement is how a WiFi driver change gets judged. Needs `BR2_TOOLCHAIN_HAS_ATOMIC`+`_THREADS`, both true | @@ -1125,7 +1125,7 @@ BR2_PACKAGE_BUSYBOX=y # 1.38.0 in this Buildroot (busybo ``` > ⚠ **This list is deliberately not identical to the live defconfig.** -> `configs/fragments/de10nano-image.fragment` currently also carries a bannered +> `configs/mister_de10nano_defconfig` currently also carries a bannered > `DEBUG TOOLING` block — gdb (+ gdbserver + full debugger), strace, > perf and rt-tests — which is **temporary and out of scope for this manifest**: it is > not stock parity and never claimed to be. Do **not** reconcile the two by @@ -1133,7 +1133,7 @@ BR2_PACKAGE_BUSYBOX=y # 1.38.0 in this Buildroot (busybo > block. Two further, *intentional* divergences: (1) §6's `BR2_PACKAGE_PYTHON3=y` line > predates P3.9 — the live defconfig also sets > `BR2_PACKAGE_PYTHON3_{SSL,ZLIB,BZIP2,XZ,PYEXPAT,READLINE,CURSES}=y` -> (`configs/fragments/de10nano-image.fragment`), and `_SSL`/`_ZLIB` are **hard blockers** +> (`configs/mister_de10nano_defconfig`), and `_SSL`/`_ZLIB` are **hard blockers** > for Downloader_MiSTer (`docs/python-compat.md`), so do not paste this Python block > without them. (2) The ~21 utility packages added by T3/T5 are documented in §4c above, > not repeated here. §6 remains the P2.1 stock-parity paste list, not a defconfig mirror. diff --git a/docs/patch-provenance.md b/docs/patch-provenance.md index 408dbd53..321ec35b 100644 --- a/docs/patch-provenance.md +++ b/docs/patch-provenance.md @@ -1631,10 +1631,10 @@ from `v6.18.38`, `v6.18.44`, `v6.18.45`, `v7.0` and `v7.1`; present in `v7.2-rc1 Three consequences follow, and each is written down where the reader who needs it will be: -- **It is the one shared patch the RT/beta series omits.** `configs/mister_rt.fragment` pins +- **It is the one shared patch the RT/beta series omits.** `package/linux-rt/Config.in` pins 7.2, which already has the ID. That omission is forced, not tidy: at `-F0` against a pristine `v7.2` the hunk reports `Hunk #1 FAILED at 786`, so listing it would break - `make rt` at patch time rather than apply harmlessly twice. + `make linux-rt` at patch time rather than apply harmlessly twice. (`board/mister/de10nano/linux-patches-beta/series` header; `docs/rt-beta-kernel.md` §2.) - **It has an expiry date.** The day the stock kernel pin leaves `6.18.y` for 7.2 or newer, this patch is deleted outright — re-applying it would collide with the in-tree row. The diff --git a/docs/python-compat.md b/docs/python-compat.md index b5a60435..4eddbfe0 100644 --- a/docs/python-compat.md +++ b/docs/python-compat.md @@ -6,7 +6,7 @@ > investigation exactly as it was run, against a build whose Python had almost every > optional C-extension deselected. Its two blocking recommendations were applied in the > same commit that added this document (`a549bd0`): -> `configs/fragments/de10nano-image.fragment` now sets +> `configs/mister_de10nano_defconfig` now sets > `BR2_PACKAGE_PYTHON3_{SSL,ZLIB,BZIP2,XZ,PYEXPAT,READLINE,CURSES}=y`, and > `scripts/ci-tests.sh`'s "P3.9 — Python & Downloader ABI gate" imports all seven under > `qemu-arm` on every run. **The image no longer ships a Python that cannot `import @@ -388,7 +388,7 @@ I did not make any of these changes — per the task constraints, this is a repo orchestrator to apply and rebuild. **Applied 2026-07-13 (`a549bd0`).** Both MUSTs plus `BZIP2`/`XZ`/`PYEXPAT`/`READLINE`/ -`CURSES` are live at `configs/fragments/de10nano-image.fragment` (a `python3-dirclean` +`CURSES` are live at `configs/mister_de10nano_defconfig` (a `python3-dirclean` was required to force the rebuild). `SQLITE` and `DECIMAL` were deliberately declined — stock's Python 3.9 shipped neither. diff --git a/docs/renovate.md b/docs/renovate.md index 72dd9924..f32a5201 100644 --- a/docs/renovate.md +++ b/docs/renovate.md @@ -47,9 +47,9 @@ for the specific pieces most likely to need a fix on the first live run. | Pin | File(s) | Mechanism | Hash companion | |---|---|---|---| -| Buildroot release | `Makefile` (`BUILDROOT_VERSION`) | `customManagers` regex, `github-tags` datasource, `allowedVersions` locked to `2026.08.x` | `BUILDROOT_SHA256` — **auto-refreshed since 2026-08-24** by `renovate-hash-sync.yml` (`hash-sync-buildroot.sh`, case 6) from buildroot.org's GPG-signed `.sign` manifest; **manual** before that date (this row used to say so), and the `make buildroot-showsig` transcription remains the fallback — see below. **Since 2026-09-02 a second companion:** `configs/fragments/golden.sha256` — the resolved-config hashes `scripts/check-config-fragments.sh` asserts per Buildroot version — is recorded for the new version by case 8 (`hash-sync-golden.sh`) in the same PR; if that case skips, `lint-config` only *warns* on the missing lines and the manual step is `scripts/check-config-fragments.sh --update-golden` + commit | -| Kernel (6.18.y longterm) | `configs/fragments/de10nano.fragment` (`BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE`) — the ONE file both DE10 stacks share since the 2026-09 fragment split | one `customManagers` regex on that file + a `customDatasources` entry over `kernel.org/releases.json`, filtered to `moniker=longterm` and the `6.18.` prefix; `allowedVersions` locked to `6.18.y` as defense in depth. Same `depName` for both files, so Renovate emits **one PR touching both** | `board/mister/de10nano/patches/linux/linux.hash` — auto-refreshed by `renovate-hash-sync.yml` from kernel.org's signed `sha256sums.asc` | -| Kernel (RT/beta, the **7.2 line**) | `configs/mister_rt.fragment` (same symbol, different line) | a **separate** `customManagers` regex + its own `kernelStable72` datasource; `allowedVersions` locked to `/^7\.2(\.\d+)?$/`. Labeled `rt-kernel-pin` + `needs-manual-version-check`. **Rewritten 2026-08-17** when 7.2 released: the datasource was `kernelMainline` (`moniker=mainline`) and the depName `kernel-mainline-rt`. Both were right while 7.2 was in `-rc` and wrong the moment it shipped — mainline moves to 7.3-rc1 about two weeks later, so the old filter would have dragged the variant straight back off the line it had just reached. The filter is now **moniker-agnostic and version-scoped**, because the 7.2 line changes moniker underneath us: today 7.2 is the `mainline` entry and no 7.2.y stable release exists yet, and once 7.2.1 ships it becomes the `stable` entry instead. The matchString accepts two- *and* three-component values for the same reason | `board/mister/de10nano/patches/linux/linux.hash` — **auto-refreshed since 2026-08-17** by `renovate-hash-sync.yml` (`hash-sync-kernel.sh --pin=rt`) from kernel.org's signed `sha256sums.asc`, same as the 6.18 pin. This row says the opposite of what it said before that date, and the reason is that the pin changed sides, not that the rule loosened: an `-rc` is fetched as a cgit `.tar.gz` snapshot upstream signs in no way, so its hash could only be hand-written TOFU; a 7.2.y release is an ordinary `.tar.xz` covered by the signed manifest. The script still **refuses** any `-rc` for either pin, leaving the build to fail closed | +| Buildroot release | `Makefile` (`BUILDROOT_VERSION`) | `customManagers` regex, `github-tags` datasource, `allowedVersions` locked to `2026.08.x` | `BUILDROOT_SHA256` — **auto-refreshed since 2026-08-24** by `renovate-hash-sync.yml` (`hash-sync-buildroot.sh`, case 6) from buildroot.org's GPG-signed `.sign` manifest; **manual** before that date (this row used to say so), and the `make buildroot-showsig` transcription remains the fallback — see below. **Since 2026-09-02 a second companion:** `scripts/check-defconfigs.sh` — the resolved-config hashes `scripts/check-defconfigs.sh` asserts per Buildroot version — is recorded for the new version by case 8 (`hash-sync-golden.sh`) in the same PR; if that case skips, `lint-config` only *warns* on the missing lines and the manual step is `scripts/check-defconfigs.sh --update-golden` + commit | +| Kernel (6.18.y longterm) | `configs/mister_de10nano_defconfig` (`BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE`) — the one committed DE10 defconfig (ADR 0030) | one `customManagers` regex on that file + a `customDatasources` entry over `kernel.org/releases.json`, filtered to `moniker=longterm` and the `6.18.` prefix; `allowedVersions` locked to `6.18.y` as defense in depth. Same `depName` for both files, so Renovate emits **one PR touching both** | `board/mister/de10nano/patches/linux/linux.hash` — auto-refreshed by `renovate-hash-sync.yml` from kernel.org's signed `sha256sums.asc` | +| Kernel (RT/beta, the **7.2 line**) | `configs/mister_de10nano_defconfig` (`BR2_PACKAGE_LINUX_RT_VERSION` — the `package/linux-rt` pin, a different symbol in the same file; its hash is `package/linux-rt/linux-rt.hash`) | a **separate** `customManagers` regex + its own `kernelStable72` datasource; `allowedVersions` locked to `/^7\.2(\.\d+)?$/`. Labeled `rt-kernel-pin` + `needs-manual-version-check`. **Rewritten 2026-08-17** when 7.2 released: the datasource was `kernelMainline` (`moniker=mainline`) and the depName `kernel-mainline-rt`. Both were right while 7.2 was in `-rc` and wrong the moment it shipped — mainline moves to 7.3-rc1 about two weeks later, so the old filter would have dragged the variant straight back off the line it had just reached. The filter is now **moniker-agnostic and version-scoped**, because the 7.2 line changes moniker underneath us: today 7.2 is the `mainline` entry and no 7.2.y stable release exists yet, and once 7.2.1 ships it becomes the `stable` entry instead. The matchString accepts two- *and* three-component values for the same reason | `board/mister/de10nano/patches/linux/linux.hash` — **auto-refreshed since 2026-08-17** by `renovate-hash-sync.yml` (`hash-sync-kernel.sh --pin=rt`) from kernel.org's signed `sha256sums.asc`, same as the 6.18 pin. This row says the opposite of what it said before that date, and the reason is that the pin changed sides, not that the rule loosened: an `-rc` is fetched as a cgit `.tar.gz` snapshot upstream signs in no way, so its hash could only be hand-written TOFU; a 7.2.y release is an ordinary `.tar.xz` covered by the signed manifest. The script still **refuses** any `-rc` for either pin, leaving the build to fail closed | | 4 driver commit-SHA pins | `package/{rtl8852cu-morrownr,aic8800,xone,midilink}/*.mk` | `customManagers` regex per package, `git-refs` datasource tracking the upstream default branch's HEAD via `currentDigest` | matching `.hash` file — auto-refreshed by `renovate-hash-sync.yml` | | munt tag pin | `package/munt/munt.mk` | `github-tags` datasource, custom `regex:` versioning for the `munt_MAJOR_MINOR_PATCH` tag scheme | `package/munt/munt.hash` — auto-refreshed | | bcm20702-firmware **commit** pin | `package/bcm20702-firmware/bcm20702-firmware.mk` | `git-refs` datasource tracking `master` HEAD via `currentDigest`. **Was** a `github-tags`/`loose` tag pin until 2026-07-19 — see "Why this one is a commit pin" below | `package/bcm20702-firmware/bcm20702-firmware.hash` — auto-refreshed | @@ -117,7 +117,7 @@ The same three-way rule applies to any new github-sourced package pin. ### Why the two kernel pins are separate managers -`configs/mister_rt.fragment` carries the **identical Kconfig symbol** as the two +`package/linux-rt/Config.in` carries the **identical Kconfig symbol** as the two defconfigs, but pins a different upstream line (the **7.2 line**, since 2026-08-17; before that, mainline `-rc` on its way to 7.2 final) with different cadence, provenance, and review bar. A single manager covering all three files @@ -134,19 +134,15 @@ hash-sync script — kept apart there by major-series line scoping rather than b being different managers; see [`docs/ci.md#renovate-hash-sync-rt-line-clobber`](ci.md#renovate-hash-sync-rt-line-clobber). -Conversely, the 6.18 pin now lives in exactly **one** file, -`configs/fragments/de10nano.fragment`, which both the image stack and the -kernel-only stack include (`configs/fragments/stacks.mk`, -`docs/buildroot-config.md` §1) — so one manager, one file, one branch. Before -the 2026-09 fragment split there were two files (`mister_de10nano_defconfig` -and its hand-mirrored copy `mister_kernel_defconfig`) deliberately in the same -manager so they moved together; a real Renovate run with both held back gave -two extracted upgrades and exactly one branch -(`renovate/kernel-longterm-6.18-6.x`). That lockstep check is what caught the -6.18.38 → 6.18.39 bump landing in only one of the two files, back when the -manager listed just `mister_de10nano_defconfig`; the failure mode is gone by -construction now, and `scripts/check-kernel-defconfig-sync.sh` guards the -construction instead. +Conversely, both kernel pins live in exactly **one** file, +`configs/mister_de10nano_defconfig` (ADR 0030: one committed defconfig per +board, no fragment stacks) — one manager per pin, one file, one branch. The +two pins are different symbols (`BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE` for +6.18.y, `BR2_PACKAGE_LINUX_RT_VERSION` for the 7.2 line), which is what lets +two managers share the file without proposing each other's version. Before +2026-09 the 6.18 pin was mirrored in a hand-copied `mister_kernel_defconfig`, +deliberately in the same manager so the two moved together; a real Renovate +run with both held back gave ### Why `bcm20702-firmware` is a commit pin, not a tag pin @@ -453,28 +449,15 @@ docs/ci.md#renovate-hash-sync-outcomes-gate. 7. **azcopy's vendored tarball hash** — see the table above. -8. **The golden config hashes** (`configs/fragments/golden.sha256`) — - **added 2026-09-02** with the fragment split (`docs/buildroot-config.md` - §11). `scripts/check-config-fragments.sh` pins, per `BUILDROOT_VERSION`, - the sha256 of each fragment stack's normalised resolved `.config`; a - Buildroot bump changes Kconfig defaults and is *expected* to move every - one of them. So that a Renovate Buildroot-bump PR still gets its build, - `lint-config` only **warns** when the pinned version has no golden lines - at all (a mismatch against a *recorded* line is still a failure — that is - drift), and this case, `scripts/hash-sync-golden.sh`, runs the **target - branch's** `check-config-fragments.sh --update-golden` through its - Makefile (`make buildroot-unpack` fetches and verifies the new tarball - with the hash case 6 just wrote) and commits the new lines alongside. It - never rewrites lines that already exist for the pinned version, and it is - a no-op on kernel bumps (the kernel-version symbols are excluded from the - normalisation). If it skips (unpack failed, the check found a real - fragment problem), the PR is not red for it — the manual step is: - - ``` - scripts/check-config-fragments.sh --update-golden --keep - # read output-config-check//normalised.config against the previous - # good run, then commit configs/fragments/golden.sha256 saying what changed - ``` +8. **The golden config hashes** — **retired 2026-09-11** with the fragment + stacks (ADR 0030 Phase D). The committed defconfigs are checked by + `scripts/check-defconfigs.sh`, which needs no per-Buildroot-version record: + it loads each defconfig, asserts every line survived into the resolved + `.config` (upstream's `check-dotconfig.py`), that `savedefconfig` + reproduces the file, and that every profile `select` landed. A Buildroot + bump that retires a symbol therefore **fails** lint on the bump PR instead + of silently moving a hash — which is the behaviour the 2026.08 headers + regression called for. **What it deliberately does NOT fix:** any `-rc` kernel hash (kernel.org signs no manifest for a cgit snapshot — hand-written TOFU only, and @@ -602,16 +585,16 @@ the next line bump comes, update **five** things together: separately: left behind it silently freezes the pin, moved ahead it invites a line jump nobody reviewed. 3. The row in the table above. -4. The golden config hashes (`scripts/check-config-fragments.sh - --update-golden`, case 8 above). +4. `scripts/check-defconfigs.sh` must pass on the bumped tree (case 8 above: + a retired symbol fails it, by design). 5. **The resolved-config diff — actually read it.** A line bump is exactly when - defaults move, and the golden hash only tells you *that* something moved. + defaults move, and a passing checker only tells you the committed lines survived. The 2026.08 bump is the cautionary tale: Buildroot retired the 7.0 kernel-headers series into `Config.in.legacy`, and because a retired symbol still *sets* cleanly, the fragment-survival check passed with 0 dropped while the DE25 toolchain silently fell from glibc to uClibc. Diffing the normalised configs against the previous line caught it; nothing else would have. Resolve the old line's configs with - `CHECK_CONFIG_BR_DIR= scripts/check-config-fragments.sh --keep` + `CHECK_CONFIG_BR_DIR= scripts/check-defconfigs.sh --keep` and diff `output-config-check//normalised.config` against the new run's. diff --git a/docs/reproducibility.md b/docs/reproducibility.md index 5eaeb0ab..7969c3c1 100644 --- a/docs/reproducibility.md +++ b/docs/reproducibility.md @@ -26,7 +26,7 @@ concrete reasons, not reproducibility as an abstract virtue: ## How this is delivered -Four mechanisms combine, all landed in P2.5 (`configs/fragments/de10nano-image.fragment`): +Four mechanisms combine, all landed in P2.5 (`configs/mister_de10nano_defconfig`): 1. **`BR2_REPRODUCIBLE=y`.** Buildroot's own reproducible-build mode. Exports `SOURCE_DATE_EPOCH` pinned to Buildroot's own pinned-tree last-commit date (constant @@ -139,7 +139,7 @@ this section should be updated with: ## Related -- `configs/fragments/de10nano-image.fragment` — the `BR2_REPRODUCIBLE` + ext4-options block +- `configs/mister_de10nano_defconfig` — the `BR2_REPRODUCIBLE` + ext4-options block (search `BR2_REPRODUCIBLE` / `BR2_TARGET_ROOTFS_EXT2_MKFS_OPTIONS`). - `scripts/check-linux-img.sh` — asserts the pinned size/label/UUID/hash-seed/feature-set contract (and the ADR 0015 no-baked-keys invariant) on every build; runs automatically diff --git a/docs/rt-beta-kernel.md b/docs/rt-beta-kernel.md index c48866ec..a6d6f6ee 100644 --- a/docs/rt-beta-kernel.md +++ b/docs/rt-beta-kernel.md @@ -65,6 +65,16 @@ alongside the main 6.18 image and selected on-device (§5). ## 2. Structure — a kernel-only base defconfig plus a per-variant fragment +> **Superseded 2026-09-11 (ADR 0030 Phase C).** There is no kernel-only stack or `output-rt/` +> tree any more. The variant is `package/linux-rt` (`package/linux-rt/linux-rt.mk`), a +> kconfig-package that reuses the main kernel's make flags, kconfig fixups and +> `board/mister/de10nano/linux.config`, layers `linux-rt.fragment`, applies +> `linux-patches-beta` through `BR2_GLOBAL_PATCH_DIR/linux-rt`, and is selected by +> `BR2_PACKAGE_LINUX_RT=y` in `configs/fragments/de10nano-image.fragment` (with its version pin +> `BR2_PACKAGE_LINUX_RT_VERSION`). The kernel-config layering described below (`linux.config` +> + `linux-rt.fragment`, the PREEMPT_RT assertion) is unchanged; the Buildroot-config layering +> (`configs/mister_rt.fragment` on the kernel-only stack) is what was retired. + The main 6.18 image build is untouched. Since ADR 0021's **2026-07-18 amendment** the variant is a **kernel-only** Buildroot build (no userland): the shared base is the `de10nano-kernel` fragment stack (`common` + `de10nano` + @@ -173,15 +183,20 @@ version code so it stays inert on the shared 6.18 build. ## 5. Build & flash +Since ADR 0030 Phase C (2026-09-11) the RT kernel is `package/linux-rt`, built by the same +`make all` that builds the image: + ```sh -make rt # -> output-rt/images/zImage_dtb (the RT kernel) - # + its module tree staged into the overlay -make all # -> linux.img now carries BOTH module trees +make mister_de10nano_defconfig # once, or after a Buildroot pin move +make all # -> output/images/zImage_dtb (6.18), zImage_dtb-rt (7.2 RT), + # linux-rt.config, and ONE linux.img carrying both module trees +make linux-rt # rebuild only the RT kernel package, if iterating on it +make linux-rt-menuconfig # its kernel config (linux.config + linux-rt.fragment) # 1. install THAT linux.img on the device first — the normal Linux update # path (replace /media/fat/linux/linux.img): it is the rootfs the RT # module tree lives in, and an older on-device image has only 6.18 modules # 2. then put the RT kernel next to it: -cp output-rt/images/zImage_dtb /media/fat/linux/zImage_dtb-rt +cp output/images/zImage_dtb-rt /media/fat/linux/zImage_dtb-rt ``` Select it on-device with a one-line edit to `/media/fat/linux/u-boot.txt` @@ -234,7 +249,7 @@ card, and nothing on the card referenced it), and deliberately NOT inside | **Module-tree merge into the one linux.img** | ✅ **green** — the row's "first green run pending" was overtaken by CI run 29758320422 (2026-07-20, rc4: `build-kernel` + `build` both green, so the merge assert ran). Re-verified locally on rc5 (2026-07-28): after `make rt`, a `make all` produced `output/target/usr/lib/modules/` holding exactly `6.18.40` and `7.2.0-rc5` — two trees, no stale third — and `linux.img` passed every `check-linux-img.sh` assertion (512 MiB, pinned UUID/hash-seed, the 14-feature stock-derived set, ADR 0015 ssh-key checks) | | **RT kernel boots on the DE10-Nano** | ⚠️ **NOT on the currently pinned 7.2 — re-opened 2026-08-17 by the rc7 → 7.2 bump.** ✅ **CONFIRMED 2026-07-20 on 7.2-rc4**, which booted and ran MiSTer on real hardware. That retired the single biggest open risk on the variant, and it is how the `0037` DualSense regression was caught: booting far enough to use a controller is what exposed the shifted PS5 button map (§7 item 3). ✅ **RE-CONFIRMED 2026-08-14 on 7.2-rc7** — the Wave-1 hardware pass ran on a `7.2.0-rc7 SMP PREEMPT_RT` kernel carrying `0043`, and the doorbell nodes enumerated and delivered events (that pass is also where H-1 and H-2 were found). Boot is a **per-version claim** and every bump re-opens it, which is exactly the state this row is in now: 7.2 final is patch-verified (**40/40** at `-F0`), DTS-verified, and **built on the whole 40-entry series** (`make rt` green from clean, 2026-08-17 — see the build rows above), but it has **not been booted**. Everything that can be checked without hardware has been checked and passed; none of it is a boot. This ✅ covers rc4 and rc7 and nothing else. It also does **not** cover `0044`, `0045`, `0046` or the re-added `0038`–`0042`: none were in the series when the rc7 kernel was built, and all six have since been built but never booted — §2, §8, §9 | | **vsync/IRQ-40 latency under RT threaded IRQs** | ❌ **unproven** (the point of the exercise) — boot and general operation are confirmed, but the latency measurement that motivates RT has not been taken | -| **Patch 0031 (exFAT Samsung symlinks) on 7.x** | ✅ **FIXED 2026-09-06 — after being found BROKEN the same day**, not by this variant but by the DE25's aarch64 initramfs QEMU leg (`scripts/test-initramfs.sh --board de25nano`), the first thing ever to EXECUTE 0031 on a 7.x kernel: `exfat_symlink()` → `page_symlink()` → `a_ops->write_begin` is NULL on 7.x exFAT (iomap; no `write_begin`/`write_end`) → Oops, `pc: 0x0`, on the first symlink created. `linux-patches-beta/0031` WAS a symlink to the shared 6.18 file, so this kernel had the same crash on any `ln -s` on `/media/fat` (reading existing links was fine). The "applies at -F0" and "compiles" rows above were true and insufficient. Now a **beta-local re-anchored copy** (the fifth): `exfat_symlink_write_target()` allocates clusters via 7.x's `exfat_map_cluster()`, writes the sectors through buffer heads, `sync_blockdev_range()`s them (iomap reads go straight to the device), and does the `valid_size`/`zeroed_size`/`i_size` bookkeeping; the DE25 series links to this copy. Verified: applies at `-F0` to pristine 7.2.3 (12/12 hunks), **compiles for arm with this variant's own `output-rt` `.config`** (`fs/exfat/`, zero warnings), and the aarch64 leg's `symlink` case passes — hot+cold round-trip, `DT_LNK`, the create+unlink cluster-leak tripwire, fsck-clean (ADR 0002 §8b). Still not executed on 32-bit ARM: the DE10 leg boots 6.18 only, so the first `ln -s` on an RT-booted board is the remaining proof. | +| **Patch 0031 (exFAT Samsung symlinks) on 7.x** | ✅ **FIXED 2026-09-06 — after being found BROKEN the same day**, not by this variant but by the DE25's aarch64 initramfs QEMU leg (`scripts/test-initramfs.sh --board de25nano`), the first thing ever to EXECUTE 0031 on a 7.x kernel: `exfat_symlink()` → `page_symlink()` → `a_ops->write_begin` is NULL on 7.x exFAT (iomap; no `write_begin`/`write_end`) → Oops, `pc: 0x0`, on the first symlink created. `linux-patches-beta/0031` WAS a symlink to the shared 6.18 file, so this kernel had the same crash on any `ln -s` on `/media/fat` (reading existing links was fine). The "applies at -F0" and "compiles" rows above were true and insufficient. Now a **beta-local re-anchored copy** (the fifth): `exfat_symlink_write_target()` allocates clusters via 7.x's `exfat_map_cluster()`, writes the sectors through buffer heads, `sync_blockdev_range()`s them (iomap reads go straight to the device), and does the `valid_size`/`zeroed_size`/`i_size` bookkeeping; the DE25 series links to this copy. Verified: applies at `-F0` to pristine 7.2.3 (12/12 hunks), **compiles for arm with this variant's own `output-rt` `.config`** (`fs/exfat/`, zero warnings), and the aarch64 leg's `symlink` case passes — hot+cold round-trip, `DT_LNK`, the create+unlink cluster-leak tripwire, fsck-clean (ADR 0002 §8b). Still not executed on 32-bit ARM: the DE10 leg boots 6.18 only, so the first `ln -s` on an RT-booted board is the remaining proof. **2026-09-11: executed as 32-bit ARM** — the rig (still on a pre-rewrite RT 7.2.3 from 2026-09-05) panicked on `update_all.sh`'s first Arcade Organizer symlink (netconsole: `PC is at 0x0`, `LR is at page_symlink+0x90`; `CONFIG_PANIC_ON_OOPS=y` + `panic=15` rebooted it), and `scripts/test-initramfs.sh --kernel rt` now builds the DE10 QEMU leg at the RT pin with `linux-patches-beta/0031`: 7.2.4 passes `symlink`/`exfat`/`fsck-request`; the 6.18-form patch on the same source reproduces the Oops. Only a hardware boot of the fixed kernel remains. | | `rtw88_8814au` firmware (`rtw88/rtw8814a_fw.bin`) present | ✅ ships via `BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW88` | ## 7. What is left diff --git a/docs/rtc-parity.md b/docs/rtc-parity.md index ea312729..7584e79f 100644 --- a/docs/rtc-parity.md +++ b/docs/rtc-parity.md @@ -164,7 +164,7 @@ applet disabled — matching stock, which shipped util-linux's `hwclock` too. It not wired into boot. See `docs/util-linux-parity.md`.) **No Buildroot `defconfig` changes needed for this task.** The one pre-existing RTC-related -line needed no change: `configs/fragments/de10nano-image.fragment` — +line needed no change: `configs/mister_de10nano_defconfig` — `BR2_PACKAGE_I2C_TOOLS=y # for the i2c-gpio RTC add-on, P3.11` (installs `i2cdetect`/ `i2cget`/`i2cset` for bench debugging of the bit-banged bus). diff --git a/docs/samba-parity.md b/docs/samba-parity.md index 3b126fbd..411bd61d 100644 --- a/docs/samba-parity.md +++ b/docs/samba-parity.md @@ -48,7 +48,7 @@ build's package install doesn't pre-bake either — fixed in `etc/fstab` - Our Samba version: `SAMBA4_VERSION = 4.23.8` in `work/buildroot/package/samba4/samba4.mk`, built with `--enable-fhs --localstatedir=/var` and no AD DC / ADS / smbtorture - (`configs/fragments/de10nano-image.fragment`'s existing `BR2_PACKAGE_SAMBA4=y` + (`configs/mister_de10nano_defconfig`'s existing `BR2_PACKAGE_SAMBA4=y` block, unchanged by this task). - Built-image ground truth: `work/p3-rootfs/` (an extracted rootfs from a prior build of this repo's *current* overlay+defconfig — verified @@ -235,7 +235,7 @@ directory by then. | `docs/samba-parity.md` | this file | **Not changed:** `overlay/etc/samba/smb.conf`, `etc/init.d/S91smb`, -`configs/fragments/de10nano-image.fragment` — see §1/§3 for why each is already +`configs/mister_de10nano_defconfig` — see §1/§3 for why each is already correct as committed. ## 5. What this task could not verify (needs BUILD / hardware LAN, P3.13) diff --git a/docs/size-budget.md b/docs/size-budget.md index 1a0adfc9..a879fead 100644 --- a/docs/size-budget.md +++ b/docs/size-budget.md @@ -88,7 +88,7 @@ headroom (60.6% free vs. the 15% floor). ## azcopy (2026-08-17) — packaged, deliberately NOT enabled `package/azcopy` would be the largest single thing added to this image since samba4, -and its size is exactly why `configs/fragments/de10nano-image.fragment` leaves it switched +and its size is exactly why `configs/mister_de10nano_defconfig` leaves it switched off. **None of the figures below are in the shipped image today** — they are what enabling that one line would cost. The full accounting — how the binary was measured, what the strip step does to a Go binary, the build-time diff --git a/docs/ssh-ftp-parity.md b/docs/ssh-ftp-parity.md index cd78caf8..6ac40022 100644 --- a/docs/ssh-ftp-parity.md +++ b/docs/ssh-ftp-parity.md @@ -267,7 +267,7 @@ No changes made. Notable existing content, confirmed intentional/stock-matching: Module set also matches stock: our defconfig sets only `BR2_PACKAGE_PROFTPD=y`, no `BR2_PACKAGE_PROFTPD_MOD_*` suboption (confirmed: -`grep PROFTPD configs/fragments/de10nano-image.fragment` → exactly one line). Stock's +`grep PROFTPD configs/mister_de10nano_defconfig` → exactly one line). Stock's own `usr/sbin/proftpd` dependency list (`docs/stock-inventory/20250402/binaries-needed-full.txt`: `libc.so.6,libcrypt.so.1,libdl.so.2,libpam.so.0` — no libssl, no sqlite, no pcre2) is consistent with the same bare/no-submodule build. @@ -277,7 +277,7 @@ pcre2) is consistent with the same bare/no-submodule build. ### 3.1 Root password — already correctly handled; initial "fix" here was wrong and has been reverted **Corrected after a false start, recorded here so it isn't retried.** -`configs/fragments/de10nano-image.fragment` has `BR2_TARGET_GENERIC_ROOT_PASSWD=""`. +`configs/mister_de10nano_defconfig` has `BR2_TARGET_GENERIC_ROOT_PASSWD=""`. Read in isolation, and per Buildroot's own `system/Config.in` ("If set to empty (the default), then no root password will be set, and root will need no password to log in"), this looks exactly like the bug it would be if diff --git a/docs/stock-reconciliation.md b/docs/stock-reconciliation.md index dae713f7..7c2deb4f 100644 --- a/docs/stock-reconciliation.md +++ b/docs/stock-reconciliation.md @@ -362,7 +362,7 @@ marked CLOSED here. | `usr/bin/vgmplay`, `usr/bin/VGMPlay.ini` | **C — DECLINED, documented** | Real gap, deliberate decline. VGMPlay (vgmrips/vgmplay, GPL) has no Buildroot package; writing one here could not be build-verified (T3 runs under a no-build constraint), and an untested C package is a worse outcome than an honest absence — it risks breaking `make all` for a niche feature (VGM chiptune playback inside mc). Cost of absence: mc's vgm handler and `m3u_play`'s vgm branch print `not found`; nothing else references it. Revisit as its own small task if VGM playback is ever asked for: pin a release tarball, `Makefile`-type package, install `VGMPlay.ini` beside the binary (it looks for its ini next to `argv[0]`). | | `usr/bin/memtool` | **A — CLOSED** | Not a sourceless blob after all: strings on the stock ELF are pengutronix memtool's exact usage text, and `addon.tar`'s `usr/bin/md`/`mw` are symlinks → `memtool` (argv[0] dispatch — `memtool.c:475` in the pinned 2018.03.0 tarball switches on `basename(argv[0])`). `BR2_PACKAGE_MEMTOOL=y` (Buildroot's own package, same upstream, 2018.03.0 — upstream's last release, confirmed against pengutronix's release directory). The package installs only the `memtool` binary, so stock's `md`/`mw` symlinks are reproduced in the overlay. | | `usr/bin/fpga` | **D — INFEASIBLE, precisely bounded** | Stripped ARM ELF; **no public source found**: GitHub code search for its distinctive strings finds only `Main_MiSTer/fpga_io.cpp` (which shares the literal `"FPGA: Unaligned data, realign to 32bit boundary."`, `fpga_io.cpp:352`) and u-boot's `drivers/fpga/socfpga.c`; no MiSTer-devel repo builds a standalone `fpga` binary. It is a dev-era peek/poke + RBF loader (`Usage(1): %s { address } [ data ]`, `Usage(2): %s { rbf_file }`, mmaps `/dev/mem`). Shipping the blob violates rule G6; recreating it from `fpga_io.cpp` would be new, untestable systems code. **Intent is covered**: core loading = `echo load_core > /dev/MiSTer_cmd` (Main, `input.cpp:6238-6242` — and mc's Enter-on-`.rbf` now does exactly that); peek/poke = `memtool md`/`mw` (above) or busybox `devmem`. Same documentation standard as `docs/firmware-parity.md`'s no-upstream-source firmware. | -| `usr/bin/rz`, `usr/bin/sz` | **A — CLOSED (T5, 2026-07-27)** | `BR2_PACKAGE_LRZSZ=y` — confirmed resolved `=y` in `output/.config` after `make de10nano-defconfig` (`lrzsz.mk` installs exactly `$(TARGET_DIR)/usr/bin/rz` and `.../sz`, matching stock's paths exactly, plus **six** bonus compat symlinks — `lrz`/`rb`/`rx` → `rz` and `lsz`/`sb`/`sx` → `sz`, `lrzsz.mk:21-26` — stock's `addon.tar` does not have). | +| `usr/bin/rz`, `usr/bin/sz` | **A — CLOSED (T5, 2026-07-27)** | `BR2_PACKAGE_LRZSZ=y` — confirmed resolved `=y` in `output/.config` after `make mister_de10nano_defconfig` (`lrzsz.mk` installs exactly `$(TARGET_DIR)/usr/bin/rz` and `.../sz`, matching stock's paths exactly, plus **six** bonus compat symlinks — `lrz`/`rb`/`rx` → `rz` and `lsz`/`sb`/`sx` → `sz`, `lrzsz.mk:21-26` — stock's `addon.tar` does not have). | | `usr/lib/libfluidsynth.so.3.0.0` | **covered (better version)** | The fluidsynth package ships `libfluidsynth.so.3.3.7` + the `libfluidsynth.so.3` SONAME link (verified in target) — same SONAME stock's addon symlinks resolve to, newer revision. Nothing links the full `3.0.0` filename. | | `usr/sbin/fluidsynth` (path diff) | **CLOSED (compat symlink)** | Stock installs the ELF at `/usr/sbin/`, our package at `/usr/bin/`. No shipped caller uses the absolute stock path — midilink builds the command `fluidsynth …` via PATH (`output/build/midilink-*/main.c:154`), the timidity wrapper and `uartmode`'s `killall` go by name, Main never references it — but third-party user scripts may hardcode it, so the overlay adds `usr/sbin/fluidsynth -> /usr/bin/fluidsynth` (same idiom as the existing `usr/sbin/mount.ntfs` link) and the difference is gone outright. | | `etc/asound.conf` | **B — CLOSED** | Vendored byte-identical. This is not optional polish: it routes ALSA's `!default` pcm through a 48 kHz S16_LE `file` plugin writing raw into `/dev/MrAudio`, the in-kernel MiSTer SPI audio ring (`CONFIG_SND_MISTER_AUDIO=y`; device created at `sound/drivers/MiSTer-audio-spi.c:231`) that Main/core mix into HDMI/analog out. **Not** because `hw:0` is missing — `hw:0` exists and *must*: `MiSTer-audio-spi.c` is a chardev SPI driver with no ALSA card at all, so the only card is the patched `snd-dummy` (`CONFIG_SND_DUMMY=y`, `board/mister/de10nano/linux.config:391`, built in; `enable[0]=1` at `sound/drivers/dummy.c:51` registers it as card 0), and this file's own innermost slave is `type hw; card 0` — the `type file` plugin *duplicates* the stream, so card 0 has to accept S16_LE/48 kHz/2ch or the default pcm fails to open outright ([`docs/abi-contract.md`](abi-contract.md) §8.2(a), §8.2(c) — "`CONFIG_SND_DUMMY=y` … *and it must be card 0*", MUST). The real cost of omitting `asound.conf` is that ALSA's default resolves to that dummy card, which discards the samples: the system is **silently mute** (`docs/phase0-review.md:128`, "omit it and the system is silent"). No package installs `/etc/asound.conf` (verified in target), so no shadowing. | @@ -440,7 +440,7 @@ Verified present in the built image: `usr/sbin/ifup` (72536-byte ARM ELF) and `output/target/sbin` is itself a symlink to `usr/sbin` (`BR2_ROOTFS_MERGED_USR=y`), so stock's `/sbin/…` spellings resolve to those same entries. `usr/sbin/iw` (264720-byte ARM ELF, `BR2_PACKAGE_IW=y` at -`configs/fragments/de10nano-image.fragment`). Not yet tested on real hardware — +`configs/mister_de10nano_defconfig`). Not yet tested on real hardware — see `docs/wifi-parity.md` §9's checklist. The former "**one path difference**" (stock `/usr/sbin/fluidsynth` vs our diff --git a/docs/uboot-mainline-port.md b/docs/uboot-mainline-port.md index df301156..3af42cff 100644 --- a/docs/uboot-mainline-port.md +++ b/docs/uboot-mainline-port.md @@ -19,7 +19,7 @@ identically to the stock 2017.03 fork as the evidence allows, as a **build artif (515,141 B, sha256 `e2d46cf9…62ba64`), fetched by hash. ADR 0017 §Decision-5 stands. * `sdcard.img` keeps embedding that same stock blob. `scripts/mk-sdcard.sh` and `scripts/check-sdcard.sh` are untouched. -* `configs/fragments/de10nano-image.fragment` gains **no** `BR2_TARGET_UBOOT*` line. +* `configs/mister_de10nano_defconfig` gains **no** `BR2_TARGET_UBOOT*` line. * **No artifact this plan produces may ever be named `uboot.img`.** `updateboot` `dd`s `/media/fat/linux/uboot.img` over the `0xA2` partition on every Linux update with no version check, no hash check and no opt-out (boot-chain §5). The build output is @@ -176,7 +176,7 @@ Measured against `work/buildroot` (2026.05.1), not recalled: (`uboot.mk:561-579`). * `BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES` exists (`Config.in:140-145`, `uboot.mk:401`) and applies via `merge_config.sh -m` + `olddefconfig` (`pkg-kconfig.mk:191-199`) — **the same - mechanism `make rt` uses**, and therefore **the same hazard**: dropped symbols only warn. + mechanism `make linux-rt` uses**, and therefore **the same hazard**: dropped symbols only warn. The `rt` recipe's `PREEMPT_RT` guard (`Makefile:504-521`) is the precedent for the resolved-`.config` assertion this build needs. * `BR2_TARGET_UBOOT_PATCH` (`Config.in:103-113`, `uboot.mk:342-354`) picks up diff --git a/docs/uboot-tasks.md b/docs/uboot-tasks.md index 0cedc1ff..f81fb8d9 100644 --- a/docs/uboot-tasks.md +++ b/docs/uboot-tasks.md @@ -16,6 +16,14 @@ verbatim from [`TASKS.md` §0](../TASKS.md). --- +> **Layout note (2026-09-11, ADR 0030):** file and target names in this document predate the +> refactor that replaced the fragment stacks with committed `configs/mister_*_defconfig` files and +> Kconfig profiles, moved the RT kernel into `package/linux-rt` (`output/build/linux-rt-*`, no +> `output-rt/`), the stage-1 initramfs into `package/mister-initramfs`, and retired the +> kernel-variant CI matrix, `scripts/list-kernel-variants.sh`, `check-kernel-defconfig-sync.sh` +> and `scripts/lib/board-expectations.sh`. Read the paths here as of their date; the current +> layout is README "Building it yourself" and `docs/ci.md` "The pipeline today". + ## The one-line summary Build mainline U-Boot **2026.04** for the DE10-Nano, configured to behave like stock's @@ -64,7 +72,7 @@ silent-brick if omitted. `board/mister/de10nano/uboot-mister.env`, and the patches in `board/mister/de10nano/uboot-patches/` (picked up by `BR2_TARGET_UBOOT_PATCH`, `Config.in:103-113` / `uboot.mk:342-354`; honours a `series` file, applies at fuzz zero). - Head the fragment with the same "which layer is which" note `configs/mister_rt.fragment:19-21` + Head the fragment with the same "which layer is which" note `package/linux-rt/Config.in:19-21` uses for the kernel. Every patch carries a full CONTRIBUTING §2 provenance header — use `board/mister/de10nano/linux-patches/0001-fbdev-add-MiSTer_fb-driver.patch` as the template. Per ADR 0024 §Decision 3, behaviour changes **are** permitted here; each must be diff --git a/docs/usb-automount-parity.md b/docs/usb-automount-parity.md index 70e13c50..7926b079 100644 --- a/docs/usb-automount-parity.md +++ b/docs/usb-automount-parity.md @@ -94,7 +94,7 @@ and are passed straight to ntfs-3g, same as on stock. ## Verification -- **Config resolves.** `make de10nano-defconfig && make olddefconfig` (kconfig +- **Config resolves.** `make mister_de10nano_defconfig && make olddefconfig` (kconfig only, no compile) produces an `output/.config` with `BR2_PACKAGE_USBMOUNT=y` + the auto-`select`ed `BR2_PACKAGE_LOCKFILE_PROGS=y`/`BR2_PACKAGE_LIBLOCKFILE=y`, and all the util-linux program toggles (`…_MOUNT`, `…_BINARIES`, `…_AGETTY`, …) — i.e. the diff --git a/docs/util-linux-parity.md b/docs/util-linux-parity.md index 9b5d7ead..37767de6 100644 --- a/docs/util-linux-parity.md +++ b/docs/util-linux-parity.md @@ -30,7 +30,7 @@ no new libraries. ## What is enabled -In `configs/fragments/de10nano-image.fragment`, next to the existing util-linux library +In `configs/mister_de10nano_defconfig`, next to the existing util-linux library selections: | Symbol | Programs | @@ -123,7 +123,7 @@ binary used for manual/debug `hwclock` calls. ## Verification -- **kconfig resolves cleanly.** `make de10nano-defconfig && make olddefconfig` +- **kconfig resolves cleanly.** `make mister_de10nano_defconfig && make olddefconfig` (no compile) lands all 16 enabled util-linux program toggles in `output/.config` with nothing silently dropped; the 25 BusyBox `# CONFIG_… is not set` fragment lines all target symbols confirmed present in the built BusyBox `.config` (so none is a diff --git a/docs/version-delta.md b/docs/version-delta.md index 6befcb22..5ccb5dfb 100644 --- a/docs/version-delta.md +++ b/docs/version-delta.md @@ -37,14 +37,14 @@ security-update path), and it belongs in the release notes. ## The stack > **Ours-side figures last re-read off the built tree on 2026-07-22** (kernel from -> `configs/fragments/de10nano.fragment`; package versions from `output/build/`). They move +> `configs/mister_de10nano_defconfig`; package versions from `output/build/`). They move > whenever Renovate lands a bump — when in doubt, the defconfig and `Makefile` pins are > the ground truth and this table is a summary of them. | Component | Stock (2021.02.4) | Ours (2026.08) | Note | |---|---|---|---| | Buildroot | **2021.02.4** | **2026.08** | ~5 years of the whole distro | -| Linux kernel | **5.15.1** (forked Nov 2021, **never merged a single 5.15.y**) | **6.18** LTS — the `.y` moves with upstream stable, so the pin (`BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE`, `configs/fragments/de10nano.fragment`) is the only place it is written down; hardware-validated at 6.18.33, 6.18.38 and 6.18.41 | on a stable `.y` line with security backports | +| Linux kernel | **5.15.1** (forked Nov 2021, **never merged a single 5.15.y**) | **6.18** LTS — the `.y` moves with upstream stable, so the pin (`BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE`, `configs/mister_de10nano_defconfig`) is the only place it is written down; hardware-validated at 6.18.33, 6.18.38 and 6.18.41 | on a stable `.y` line with security backports | | glibc | **2.31** | **2.44** | backward-compatible; every stock binary still runs (proven on hardware) | | gcc (toolchain) | 10.x era | **15.3.0** | | diff --git a/docs/wifi-parity.md b/docs/wifi-parity.md index 678b076b..8d849ce6 100644 --- a/docs/wifi-parity.md +++ b/docs/wifi-parity.md @@ -171,7 +171,7 @@ Everything below is cited to the actual fetched script, | `udhcpc`/direct `dhcpcd` invocation | v1.x: not called. **v2.3.0 calls all three in order** — `dhcpcd -n` (`:2021`), `udhcpc -n -q -i` (`:2024`), `dhclient` (`:2027`) — each under a timeout, taking the first that succeeds | — | — | **No gap** — we ship `dhcpcd` and `udhcpc`, so the chain succeeds at step 1 or 2 and never reaches `dhclient` (which we do not ship, deliberately: it is ISC's client and adding it to satisfy an unreachable third fallback would be dead weight). The global `S41dhcpcd` daemon still handles the boot path as before. (This row previously read "not called anywhere in the script".) | Three genuinely new Buildroot packages were needed -(`configs/fragments/de10nano-image.fragment`, new "P3.4: WiFi userland +(`configs/mister_de10nano_defconfig`, new "P3.4: WiFi userland parity (`wifi.sh` contract)" section): `BR2_PACKAGE_BASH`, `BR2_PACKAGE_DIALOG`, `BR2_PACKAGE_WIRELESS_TOOLS` (+`_IWCONFIG`, its own default-y sub-option, listed for clarity per this file's existing @@ -251,7 +251,7 @@ kernel from this era; no separate check needed. ## 4. Files touched by this task -- **Edited** `configs/fragments/de10nano-image.fragment` — added the "P3.4: WiFi +- **Edited** `configs/mister_de10nano_defconfig` — added the "P3.4: WiFi userland parity (`wifi.sh` contract)" section (lines 774-783): `BR2_PACKAGE_BASH=y`, `BR2_PACKAGE_DIALOG=y`, `BR2_PACKAGE_WIRELESS_TOOLS=y` (+`_IWCONFIG=y`), `BR2_PACKAGE_IPROUTE2=y`. No other defconfig lines @@ -972,7 +972,7 @@ on `argv[0]`). `output/target/sbin` is itself a symlink to `usr/sbin` (`BR2_ROOTFS_MERGED_USR=y`), so stock's `/sbin/ifup` and `/sbin/ifdown` spellings resolve to those same two entries. `output/target/usr/sbin/iw` — a 264720-byte ARM ELF, from `BR2_PACKAGE_IW=y` at -`configs/fragments/de10nano-image.fragment`; without it the `pre-up` loop's +`configs/mister_de10nano_defconfig`; without it the `pre-up` loop's `iw dev` would be a permanent 20 s no-op. ### Verify-on-hardware (adds to §5's checklist) diff --git a/external.mk b/external.mk index 3571946b..dddba47a 100644 --- a/external.mk +++ b/external.mk @@ -16,126 +16,13 @@ include $(sort $(wildcard $(BR2_EXTERNAL_MISTER_PATH)/package/*/*.mk)) -################################################################################ -# -# P1.10 — stage-2 half of the two-stage initramfs build (A1, PLAN.md §5, -# docs/decisions/0002-initramfs.md). -# -# Stage 1 (the `initramfs-common initramfs-de10nano` fragment stack, -# configs/fragments/stacks.mk, driven by the top-level Makefile's `initramfs` -# target) produces output-initramfs/images/rootfs.cpio. This block is -# what makes the MAIN build's kernel swallow it: it injects CONFIG_INITRAMFS_SOURCE -# into the kernel .config at kconfig-fixup time, which is the same mechanism -# Buildroot itself uses for BR2_TARGET_ROOTFS_INITRAMFS (linux/linux.mk:412-419) — -# we just point it at a different, much smaller cpio. -# -# WHY HERE AND NOT IN THE DEFCONFIG. The obvious alternative is -# BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES in configs/fragments/de10nano.fragment. Do -# not: package/pkg-kconfig.mk:19-20 makes `make linux-update-defconfig` and -# `make linux-savedefconfig` HARD-FAIL ("Unable to perform when fragment files are -# set") as soon as any fragment is configured — and those are precisely the commands -# P1.3 uses to regenerate board/mister/de10nano/linux.config. Doing it here keeps -# that workflow intact and keeps an absolute build path out of a committed defconfig. -# -# Ordering is safe: Buildroot's Makefile includes linux/linux.mk (line 553) before -# $(BR2_EXTERNAL_MKS) (line 564), and LINUX_KCONFIG_FIXUP_CMDS is expanded lazily -# inside the .stamp_kconfig_fixup_done recipe, so appending to it here works. -# $(sep) is Buildroot's newline (support/misc/utils.mk:103) — a bare `+=` would -# splice our first command onto the tail of linux.mk's last one. -# -################################################################################ - -# WHY THE ARCH TEST — added with the DE25-Nano target (D2.1). -# -# BR2_LINUX_KERNEL=y alone was the right condition while every output directory -# in this tree built for the same armv7 board. It no longer is: -# the de25nano fragment stack (configs/fragments/de25nano.fragment) builds an AARCH64 kernel for a different -# board (Agilex 5), in output-de25/, and this hook keys on the *symbol*, not on -# which defconfig or which O= is in play — so without a second test it would -# fire there too and try to embed $(MISTER_INITRAMFS_CPIO) into that kernel. -# -# Two things would go wrong, one loudly and one not: -# 1. LOUDLY, and only by luck: the fixup hard-fails if the cpio is absent, so -# a DE25 build in a tree that had never run `make initramfs` would die with -# an error message telling the developer to build a stage-1 initramfs their -# board does not have and does not want. -# 2. QUIETLY, which is the real hazard: in a tree that HAS run `make -# initramfs` (i.e. any tree that has built the DE10 image — so, every -# developer's, and CI's), the cpio exists and the fixup succeeds. The -# aarch64 kernel then ships an armv7 BusyBox as its initramfs, boots, runs -# /init, and fails at the first exec with a message about the *binary* -# rather than about the build. A green build that produces that is worse -# than no build. -# -# THE TEST IS ON THE ARCHITECTURE, not on a board name or a defconfig name, and -# that is the point: the thing that makes this hook wrong for the DE25 is not -# "it is the DE25", it is that the cpio is armv7 userspace. Every output dir -# this hook is *meant* for -- the main DE10 image, the kernel-only stack -# and the rt variant built on it -- is BR2_arm=y, and every one of them wants the -# cpio. So `BR2_arm` names the actual precondition and needs no maintenance when -# a fourth armv7 variant or a second aarch64 board appears. -# -# Considered and rejected: a BR2_EXTERNAL Config.in symbol (e.g. a -# "BR2_PACKAGE_MISTER_EMBED_STAGE1_INITRAMFS" bool) would be more explicit, but -# it would have to be added to configs/fragments/de10nano.fragment (the board -# layer both DE10 stacks share) to keep them building — a toolchain-family -# edit that changes the DE10's toolchain-fingerprint cache key, for zero -# behavioural difference. -# -# THE DE25 SWITCH (ADR 0029 D11; docs/de25-sdcard.md §2). Since 2026-09-06 an -# aarch64 stage 1 of the same /init exists -- `make de25-initramfs`, the -# `initramfs-common initramfs-de25nano` stack, output-initramfs-de25/images/ -# rootfs.cpio, verified and booted through scripts/test-initramfs.sh --board -# de25nano -- but it is deliberately NOT embedded while the shipped DE25 card -# keeps D11's interim plain-ext4 root (the first hardware boot is meant to -# answer the SPL/DTS/SD-controller questions with as few moving parts as -# possible). When the card moves to the two-stage layout, the change HERE is -# to make the cpio path follow the architecture instead of gating on it: -# ifeq ($(BR2_LINUX_KERNEL),y) -# ifeq ($(BR2_aarch64),y) -# MISTER_INITRAMFS_CPIO ?= $(BR2_EXTERNAL_MISTER_PATH)/output-initramfs-de25/images/rootfs.cpio -# else -# MISTER_INITRAMFS_CPIO ?= $(BR2_EXTERNAL_MISTER_PATH)/output-initramfs/images/rootfs.cpio -# endif -# together with `de25: de25-initramfs ...` in the Makefile, the `loop=` -# bootargs in board/mister/de25nano/post-image.sh, the exFAT p2 in its -# genimage config and the checker -- one commit, as docs/de25-sdcard.md §2 -# lists. Until then the BR2_arm gate below stands, and the hazard it guards -# (an armv7 cpio in an aarch64 kernel) is unchanged. -ifeq ($(BR2_LINUX_KERNEL)$(BR2_arm),yy) - -# Overridable so CI can build the two stages in separate workspaces. -MISTER_INITRAMFS_CPIO ?= $(BR2_EXTERNAL_MISTER_PATH)/output-initramfs/images/rootfs.cpio - -define MISTER_LINUX_INITRAMFS_FIXUP - @if [ ! -f "$(MISTER_INITRAMFS_CPIO)" ]; then \ - echo "*** MISTER: stage-1 initramfs cpio not found:"; \ - echo "*** $(MISTER_INITRAMFS_CPIO)"; \ - echo "*** The kernel cannot be built without it — U-Boot never loads an"; \ - echo "*** initrd (A3), so the cpio must be INSIDE the zImage. Build it with:"; \ - echo "*** make initramfs"; \ - echo "*** (the top-level 'make all' does this for you)."; \ - exit 1; \ - fi - @$(call MESSAGE,"Embedding stage-1 initramfs: $(MISTER_INITRAMFS_CPIO)") - $(call KCONFIG_ENABLE_OPT,CONFIG_BLK_DEV_INITRD) - $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_SOURCE,"$(MISTER_INITRAMFS_CPIO)") - $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_UID,0) - $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_GID,0) - $(call KCONFIG_ENABLE_OPT,CONFIG_RD_GZIP) - $(call KCONFIG_ENABLE_OPT,CONFIG_INITRAMFS_COMPRESSION_GZIP) -endef - -# CONFIG_INITRAMFS_COMPRESSION_* is set explicitly rather than left to kconfig. The -# choice in usr/Kconfig carries NO `default`, so it silently resolves to its first -# visible entry — today that happens to be GZIP, but "whatever is listed first -# upstream" is not something a boot path should depend on. We ship an UNCOMPRESSED -# cpio (BR2_TARGET_ROOTFS_CPIO_NONE in stage 1) and let the kernel gzip it here: -# compressing it twice would be pointless, and gzip beats leaving it raw for the -# LZ4-compressed zImage to squeeze (LZ4 optimises for decode speed, not ratio). -LINUX_KCONFIG_FIXUP_CMDS += $(sep)$(MISTER_LINUX_INITRAMFS_FIXUP) +# The stage-1 initramfs is embedded by linux/linux-ext-mister-initramfs.mk +# (a Buildroot "linux extension", included by linux/linux.mk before the +# kernel package is evaluated -- the only hook early enough to make the +# kernel DEPEND on package/mister-initramfs). It used to live here as a +# LINUX_KCONFIG_FIXUP_CMDS append against a cpio from a second Buildroot +# tree; ADR 0030 moved both the cpio and the fixup into the main build. -endif # BR2_LINUX_KERNEL && BR2_arm ################################################################################ # diff --git a/linux/Config.ext.in b/linux/Config.ext.in new file mode 100644 index 00000000..bea6cc58 --- /dev/null +++ b/linux/Config.ext.in @@ -0,0 +1,20 @@ +config BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS + bool "MiSTer stage-1 initramfs embedded in the kernel" + select BR2_PACKAGE_MISTER_INITRAMFS + help + Embed package/mister-initramfs's cpio into the kernel + (CONFIG_INITRAMFS_SOURCE). REQUIRED for a bootable MiSTer kernel: + U-Boot passes `-` for bootz's initrd argument and never loads one, + so the initramfs that mounts the SD card and loop-mounts + linux/linux.img has to be INSIDE the zImage (ADR 0002, A3). + + This is a br2-external "linux extension": it makes the kernel + depend on the package and sets CONFIG_INITRAMFS_SOURCE, + CONFIG_BLK_DEV_INITRD and gzip compression in the kernel config at + kconfig-fixup time -- the same mechanism Buildroot uses for + BR2_TARGET_ROOTFS_INITRAMFS, which must NEVER be used here (it + embeds the whole rootfs). + + Override the cpio for one build with MISTER_INITRAMFS_CPIO= + on the make command line (scripts/mk-sdcard.sh does this to relink + the installer kernel). diff --git a/linux/linux-ext-mister-initramfs.mk b/linux/linux-ext-mister-initramfs.mk new file mode 100644 index 00000000..5b349c97 --- /dev/null +++ b/linux/linux-ext-mister-initramfs.mk @@ -0,0 +1,62 @@ +################################################################################ +# +# Linux kernel extension: MiSTer stage-1 initramfs (ADR 0002) +# +################################################################################ + +# Included by linux/linux.mk BEFORE it evaluates the kernel package (that is +# what a linux-ext-*.mk is for), so package/mister-initramfs becomes a real +# dependency of the kernel: LINUX_PATCH_DEPENDENCIES += mister-initramfs is +# derived from LINUX_EXTENSIONS by linux.mk itself. external.mk cannot do +# that -- it is included after the kernel's prerequisites are expanded. +# +# The fixup below is what makes CONFIG_INITRAMFS_SOURCE point at the cpio. It +# runs at kernel kconfig-fixup time, after board/mister//linux.config +# is loaded, and it is deliberately NOT in that committed linux.config: an +# absolute build path has no place in a defconfig, and setting the symbol via +# a kernel-config fragment would break `make linux-update-defconfig` +# (pkg-kconfig.mk refuses to save a config assembled from fragments). +# +# Compression: the kernel's usr/Kconfig initramfs-compression choice has NO +# default, so it is pinned to gzip explicitly (with the matching CONFIG_RD_). +# The cpio itself is uncompressed; compressing twice would be pointless. + +LINUX_EXTENSIONS += mister-initramfs + +ifeq ($(BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS),y) + +# LINUX_EXTENSIONS only orders the kernel's PATCH stage after the extension's +# PATCH stage (linux.mk derives LINUX_PATCH_DEPENDENCIES from it -- enough for +# xenomai, whose prepare-kernel needs sources, not a build). The cpio has to be +# BUILT and installed before the kernel's kconfig fixup runs, so the package is +# a full dependency as well. This file is included before linux.mk evaluates +# the kernel package, which is the only place this line can take effect. +LINUX_DEPENDENCIES += mister-initramfs + +# Overridable on the make command line: scripts/mk-sdcard.sh relinks the +# kernel around the installer's cpio with MISTER_INITRAMFS_CPIO=. +MISTER_INITRAMFS_CPIO ?= $(BINARIES_DIR)/mister-initramfs.cpio + +# Nothing to do at kernel-patch time; the hook must exist because linux.mk +# registers _PREPARE_KERNEL for every enabled extension. +define MISTER_INITRAMFS_PREPARE_KERNEL +endef + +define MISTER_INITRAMFS_LINUX_KCONFIG_FIXUP + @if [ ! -f "$(MISTER_INITRAMFS_CPIO)" ]; then \ + echo "*** MISTER: stage-1 initramfs cpio not found: $(MISTER_INITRAMFS_CPIO)"; \ + echo "*** The kernel cannot boot without it (U-Boot never loads an initrd, A3)."; \ + echo "*** Is BR2_PACKAGE_MISTER_INITRAMFS built? (make mister-initramfs)"; \ + exit 1; \ + fi + @$(call MESSAGE,"Embedding stage-1 initramfs: $(MISTER_INITRAMFS_CPIO)") + $(call KCONFIG_ENABLE_OPT,CONFIG_BLK_DEV_INITRD) + $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_SOURCE,"$(MISTER_INITRAMFS_CPIO)") + $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_UID,0) + $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_GID,0) + $(call KCONFIG_ENABLE_OPT,CONFIG_RD_GZIP) + $(call KCONFIG_ENABLE_OPT,CONFIG_INITRAMFS_COMPRESSION_GZIP) +endef +LINUX_KCONFIG_FIXUP_CMDS += $(sep)$(MISTER_INITRAMFS_LINUX_KCONFIG_FIXUP) + +endif diff --git a/mk-release.log b/mk-release.log new file mode 100644 index 00000000..bee077cc --- /dev/null +++ b/mk-release.log @@ -0,0 +1,130 @@ + +==> mk-release: reading /MiSTer.version from /mnt/source/Buildroot_MiSTer-vanilla/output/images/linux.img + /MiSTer.version=260904 -> RELEASE_DATE=20260904 + +==> mk-release: staging image assets into /mnt/source/Buildroot_MiSTer-vanilla/dist +legal-info.tar.gz: 6923165 bytes (6 MiB) + +==> mk-release: fetching + verifying the pinned stock release + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00:01 0 100 80.00M 100 80.00M 0 0 56.07M 0 00:01 00:01 56.10M 100 80.00M 100 80.00M 0 0 56.07M 0 00:01 00:01 56.10M 100 80.00M 100 80.00M 0 0 56.07M 0 00:01 00:01 56.10M +fetch-stock: fetched volume 1: https://raw.githubusercontent.com/MiSTer-devel/SD-Installer-Win64_MiSTer/76fd6f4ced6350b0ad56a7013b41526f47e3a2fb/release_20260907.7z.001 + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 0 0 0 0 0 0 0 0 0 100 32.47M 100 32.47M 0 0 35.98M 0 0 100 32.47M 100 32.47M 0 0 35.97M 0 0 100 32.47M 100 32.47M 0 0 35.97M 0 0 +fetch-stock: fetched volume 2: https://raw.githubusercontent.com/MiSTer-devel/SD-Installer-Win64_MiSTer/76fd6f4ced6350b0ad56a7013b41526f47e3a2fb/release_20260907.7z.002 +fetch-stock: 2 volume(s) joined -> /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z +verify-stock: /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z verified -- size/MD5/SHA-256/internal-CRC all match. + +7-Zip 26.00 (x64) : Copyright (c) 1999-2026 Igor Pavlov : 2026-02-12 + 64-bit locale=C.UTF-8 Threads:32 OPEN_MAX:1048576, ASM + +Scanning the drive for archives: +1 file, 117936766 bytes (113 MiB) + +Extracting archive: /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z +-- +Path = /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z +Type = 7z +Physical Size = 117936766 +Headers Size = 765 +Method = LZMA2:26 LZMA:20 BCJ2 +Solid = + +Blocks = 2 + +Everything is Ok + +Folders: 3 +Files: 13 +Size: 402464951 +Compressed: 117936766 +extract-stock: extracted files/linux/* from /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z -> /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock-extract +verify-uboot: uboot.img and updateboot confirmed byte-identical to stock. + +==> mk-release: assembling files/linux and packing release_20260904.7z + 7za + MidiLink.INI + _samba.sh + _user-startup.sh + _wpa_supplicant.conf + gamecontrollerdb + linux + linux.img + mt32-rom-data + ppp_options + soundfonts + u-boot.txt_example + uboot.img + updateboot + zImage_dtb + wrote /mnt/source/Buildroot_MiSTer-vanilla/dist/release_20260904.7z (84632824 bytes) + +==> mk-release: round-tripping the archive under the pinned ARM 7za (qemu-arm) + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 100 454.6k 100 454.6k 0 0 578.2k 0 0 100 454.6k 100 454.6k 0 0 578.1k 0 0 100 454.6k 100 454.6k 0 0 578.0k 0 0 +fetch-7za: pinned ARM 7za fetched and verified -> /mnt/source/Buildroot_MiSTer-vanilla/release-work/7za + +7-Zip (a) [32] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 +p7zip Version 16.02 (locale=C.UTF-8,Utf16=on,HugeFiles=on,32 bits,32 CPUs LE) + +Scanning the drive for archives: +1 file, 84632824 bytes (81 MiB) + +Testing archive: /mnt/source/Buildroot_MiSTer-vanilla/dist/release_20260904.7z +-- +Path = /mnt/source/Buildroot_MiSTer-vanilla/dist/release_20260904.7z +Type = 7z +Physical Size = 84632824 +Headers Size = 607 +Method = LZMA2:28 +Solid = + +Blocks = 1 + +Everything is Ok + +Folders: 5 +Files: 14 +Size: 550398955 +Compressed: 84632824 + +7-Zip (a) [32] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 +p7zip Version 16.02 (locale=C.UTF-8,Utf16=on,HugeFiles=on,32 bits,32 CPUs LE) + +Scanning the drive for archives: +1 file, 84632824 bytes (81 MiB) + +Extracting archive: /mnt/source/Buildroot_MiSTer-vanilla/dist/release_20260904.7z +-- +Path = /mnt/source/Buildroot_MiSTer-vanilla/dist/release_20260904.7z +Type = 7z +Physical Size = 84632824 +Headers Size = 607 +Method = LZMA2:28 +Solid = + +Blocks = 1 + +Everything is Ok + +Folders: 3 +Files: 14 +Size: 550398955 +Compressed: 84632824 +roundtrip: pinned ARM 7za: both 't' and 'x -y ... files/linux/*' succeeded. +verify-uboot: uboot.img/updateboot survive our archive's create+pinned-7za-extract round trip unchanged. +verify-layout: archive layout matches docs/downloader-contract.md / docs/reference-materials.md. + +==> mk-release: SHA256SUMS +cbbc891b430fec1aa4e926f6cedfd129c66e934d8c312afd482f6fbb9c26a0e1 release_20260904.7z +b10f7c33466af0f20b17b5d47062686a5f7775c4aa4053b51a4957fdcc4639ef linux.img +012a1dc459a6b3cbd3ef038abee2121eecd3b43fcc81e7c6454aaf22419d5eef zImage_dtb +d266dd5111edc581b1352c1b07847145c38686e896fadbcf898696c4eef9dd99 zImage_dtb-rt +b5e9cc0cb85f6250eaf0e150b975fab5b1466c31f27f59fe917d9c86996d9ebc buildroot.config +7c0909f0e02084951e9347f3589fe9e2228d54833681d885d24c464d8f6a8a6b linux.config +907b63c0adb62aecf3344a12958a5b45caf8e56b78498eba180d6f0991bb5a48 linux-rt.config +b6da2bf61e26858209e5936ea419bbcebe941dd4a604957c0a2f623a439c30a0 legal-info.tar.gz + +==> mk-release: done: /mnt/source/Buildroot_MiSTer-vanilla/dist ready; stock archive kept at /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z for mk-sdcard.sh +exit=0 diff --git a/package/linux-rt/Config.in b/package/linux-rt/Config.in new file mode 100644 index 00000000..189ba5b9 --- /dev/null +++ b/package/linux-rt/Config.in @@ -0,0 +1,50 @@ +config BR2_PACKAGE_LINUX_RT + bool "linux-rt (PREEMPT_RT kernel variant -> images/zImage_dtb-rt)" + depends on BR2_LINUX_KERNEL + depends on BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS + help + A SECOND kernel built beside the main one (ADR 0021 as amended by + ADR 0030): the 7.2.y line with CONFIG_PREEMPT_RT=y, from the same + board/mister/de10nano/linux.config plus linux-rt.fragment, patched + with board/mister/de10nano/linux-patches-beta (a `series` dir, via + BR2_GLOBAL_PATCH_DIR/linux-rt), embedding the same stage-1 cpio. + + Products: images/zImage_dtb-rt (zImage + DTB, budget-checked by + scripts/check-zimage-dtb.sh), images/linux-rt.config, and its + depmod'd module tree in the ONE rootfs next to the main kernel's, + so switching kernels on the device is a u-boot.txt line and never a + rootfs flash (docs/rt-beta-kernel.md §5). + + The build hard-asserts CONFIG_PREEMPT_RT=y in the built kernel's + .config: merge_config.sh only warns when a fragment symbol is + dropped, so without it a plain 7.2 kernel could ship labeled RT. + + Same shape as Buildroot's own barebox-aux: one source, a second + configuration, in one tree. `make linux-rt-menuconfig` edits it. + + https://github.com/mcfbytes/Buildroot_MiSTer/blob/master/docs/rt-beta-kernel.md + +if BR2_PACKAGE_LINUX_RT + +config BR2_PACKAGE_LINUX_RT_VERSION + string "kernel version" + default "" + help + A kernel.org release on the 7.2.y line (PREEMPT_RT for 32-bit ARM + landed in 7.1; docs/rt-beta-kernel.md). DELIBERATELY NO DEFAULT: + the pin is a line in configs/mister_de10nano_defconfig, next to the + 6.18 pin, where Renovate bumps it and `savedefconfig` keeps it (a + Kconfig default would be dropped from the saved defconfig and the + pin would go unmanaged). The tarball's sha256 lives in + package/linux-rt/linux-rt.hash, transcribed from kernel.org's + PGP-signed sha256sums.asc -- never from a downloaded tarball. A bump + must move both, or the download fails closed. + +config BR2_PACKAGE_LINUX_RT_CONFIG_FRAGMENT_FILES + string "kernel config fragment files" + default "$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de10nano/linux-rt.fragment" + help + Merged onto the main kernel's BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE. + This is the layer that carries CONFIG_PREEMPT_RT=y. + +endif diff --git a/package/linux-rt/linux-rt.hash b/package/linux-rt/linux-rt.hash new file mode 100644 index 00000000..3c2ad834 --- /dev/null +++ b/package/linux-rt/linux-rt.hash @@ -0,0 +1,8 @@ +# The RT/beta kernel pin (ADR 0021 / ADR 0030). Transcribed from kernel.org's +# PGP-signed release manifest, https://cdn.kernel.org/pub/linux/kernel/v7.x/sha256sums.asc, +# NEVER from a downloaded tarball -- see board/mister/de10nano/patches/linux/linux.hash's +# header for the full rule; this file carries the same value that file held for the RT +# line until Phase C moved the variant into package/linux-rt. scripts/hash-sync-kernel.sh +# --pin=rt rewrites this line on a version bump. +sha256 01710ee01737dac492f1bae52becd057e08d20d11589089aa06accff415c28dd linux-7.2.4.tar.xz +sha256 fb5a425bd3b3cd6071a3a9aff9909a859e7c1158d54d32e07658398cd67eb6a0 COPYING diff --git a/package/linux-rt/linux-rt.mk b/package/linux-rt/linux-rt.mk new file mode 100644 index 00000000..11097fa5 --- /dev/null +++ b/package/linux-rt/linux-rt.mk @@ -0,0 +1,119 @@ +################################################################################ +# +# linux-rt -- the PREEMPT_RT kernel variant, built beside the main kernel +# +################################################################################ + +# ADR 0030 Phase C (amends ADR 0021). Until 2026-09 this kernel was a separate +# kernel-only Buildroot tree (output-rt/) whose module tree the wrapper +# Makefile copied into an overlay for the next `make all` to fold into +# linux.img, with stamps to remove stale trees because Buildroot's overlay +# rsync never deletes. As a package of the main configuration all of that +# disappears: modules_install lands in TARGET_DIR directly, depmod runs in a +# target-finalize hook like the main kernel's, and one `make` produces both +# kernels and the one image. Precedent: boot/barebox's barebox-aux (same +# source, second config, one tree). +# +# Everything kernel-generic is REUSED from linux/linux.mk rather than copied: +# LINUX_MAKE_ENV / LINUX_MAKE_FLAGS (ARCH, CROSS_COMPILE, KCFLAGS, +# INSTALL_MOD_PATH, reproducible KBUILD_* under BR2_REPRODUCIBLE), +# LINUX_KCONFIG_FIXUP_CMDS (every BR2_-driven kernel fixup, the +# PACKAGES_LINUX_CONFIG_FIXUPS every kmod/lvm2-style package contributes, and +# the stage-1 cpio fixup linux/linux-ext-mister-initramfs.mk appends to it), +# LINUX_DTBS / LINUX_IMAGE_NAME / LINUX_TARGET_NAME. The kconfig-package +# infrastructure's KCONFIG_* helpers act on THIS package's .config at recipe +# time (PKG=LINUX_RT), so the shared fixup body needs no adaptation. + +LINUX_RT_VERSION = $(call qstrip,$(BR2_PACKAGE_LINUX_RT_VERSION)) +ifeq ($(BR2_PACKAGE_LINUX_RT),y) +ifeq ($(LINUX_RT_VERSION),) +$(error BR2_PACKAGE_LINUX_RT_VERSION is empty: the RT kernel pin must be a line in the defconfig (see package/linux-rt/Config.in)) +endif +endif +LINUX_RT_SOURCE = linux-$(LINUX_RT_VERSION).tar.xz +LINUX_RT_SITE = $(call qstrip,$(BR2_KERNEL_MIRROR))/linux/kernel/v$(firstword $(subst ., ,$(LINUX_RT_VERSION))).x +LINUX_RT_DL_SUBDIR = linux +LINUX_RT_LICENSE = GPL-2.0 WITH Linux-syscall-note +LINUX_RT_LICENSE_FILES = COPYING +LINUX_RT_CPE_ID_VENDOR = linux +LINUX_RT_CPE_ID_PRODUCT = linux_kernel +LINUX_RT_INSTALL_IMAGES = YES + +# The same host tools the main kernel needs (kmod for depmod, compressors, +# firmware for CONFIG_EXTRA_FIRMWARE, ...), plus the cpio it embeds. +LINUX_RT_DEPENDENCIES = $(LINUX_DEPENDENCIES) mister-initramfs +LINUX_RT_KCONFIG_DEPENDENCIES = $(LINUX_KCONFIG_DEPENDENCIES) + +LINUX_RT_MAKE_ENV = $(LINUX_MAKE_ENV) +LINUX_RT_MAKE_FLAGS = $(LINUX_MAKE_FLAGS) +LINUX_RT_ARCH_PATH = $(@D)/arch/$(KERNEL_ARCH) + +# Base config = the main kernel's; the RT delta rides on top as a fragment. +LINUX_RT_KCONFIG_FILE = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE)) +LINUX_RT_KCONFIG_FRAGMENT_FILES = $(call qstrip,$(BR2_PACKAGE_LINUX_RT_CONFIG_FRAGMENT_FILES)) +LINUX_RT_KCONFIG_EDITORS = menuconfig nconfig +LINUX_RT_KCONFIG_OPTS = $(LINUX_KCONFIG_OPTS) +LINUX_RT_KCONFIG_FIXUP_CMDS = $(LINUX_KCONFIG_FIXUP_CMDS) + +LINUX_RT_VERSION_PROBED = `MAKEFLAGS='$(filter-out w,$(MAKEFLAGS))' $(BR2_MAKE) $(LINUX_RT_MAKE_FLAGS) -C $(LINUX_RT_DIR) --no-print-directory -s kernelrelease 2>/dev/null` + +# The RT proof. merge_config.sh only WARNS when a fragment symbol is dropped +# and olddefconfig silently discards symbols whose dependencies fail, so +# without this a plain 7.2 kernel would ship labeled zImage_dtb-rt. Checked +# before the (long) compile so a wrong config fails in seconds. +define LINUX_RT_ASSERT_PREEMPT_RT + @grep -qx 'CONFIG_PREEMPT_RT=y' $(@D)/.config || { \ + echo "*** linux-rt: the configured kernel is NOT RT: CONFIG_PREEMPT_RT=y is absent from $(@D)/.config."; \ + echo "*** Two config layers are in play: board/mister/de10nano/linux-rt.fragment (kernel"; \ + echo "*** config, where CONFIG_PREEMPT_RT lives) and BR2_PACKAGE_LINUX_RT_* (Buildroot config)."; \ + echo "*** Check the fragment against this kernel version's Kconfig (docs/rt-beta-kernel.md §1)."; \ + exit 1; } +endef +LINUX_RT_POST_CONFIGURE_HOOKS += LINUX_RT_ASSERT_PREEMPT_RT + +define LINUX_RT_BUILD_CMDS + $(call KCONFIG_DISABLE_OPT,CONFIG_GCC_PLUGINS) + $(LINUX_RT_MAKE_ENV) $(BR2_MAKE) $(LINUX_RT_MAKE_FLAGS) -C $(@D) all + $(LINUX_RT_MAKE_ENV) $(BR2_MAKE) $(LINUX_RT_MAKE_FLAGS) -C $(@D) $(LINUX_TARGET_NAME) + $(LINUX_RT_MAKE_ENV) $(BR2_MAKE) $(LINUX_RT_MAKE_FLAGS) -C $(@D) $(LINUX_DTBS) +endef + +# zImage_dtb-rt is zImage + DTB concatenated, exactly as +# board/mister/de10nano/post-image.sh assembles the main kernel's zImage_dtb, +# and it gets the same budget/DTB-at-EOF check. linux-rt.config is what the +# release publishes next to it. +define LINUX_RT_INSTALL_IMAGES_CMDS + cat $(LINUX_RT_ARCH_PATH)/boot/$(LINUX_IMAGE_NAME) \ + $(addprefix $(LINUX_RT_ARCH_PATH)/boot/dts/,$(LINUX_DTBS)) \ + > $(BINARIES_DIR)/zImage_dtb-rt + $(BR2_EXTERNAL_MISTER_PATH)/scripts/check-zimage-dtb.sh $(BINARIES_DIR)/zImage_dtb-rt + $(INSTALL) -m 0644 $(@D)/.config $(BINARIES_DIR)/linux-rt.config +endef + +# LINUX_RT_VERSION_PROBED shells out to `make kernelrelease`; each recipe +# below evaluates it ONCE into a shell variable rather than inlining it per use. +define LINUX_RT_INSTALL_TARGET_CMDS + @if grep -q "CONFIG_MODULES=y" $(@D)/.config; then \ + kver=$(LINUX_RT_VERSION_PROBED); \ + $(LINUX_RT_MAKE_ENV) $(BR2_MAKE1) $(LINUX_RT_MAKE_FLAGS) -C $(@D) modules_install; \ + rm -f $(TARGET_DIR)/lib/modules/$$kver/build ; \ + rm -f $(TARGET_DIR)/lib/modules/$$kver/source ; \ + fi +endef + +# linux.mk's own LINUX_RUN_DEPMOD only depmods the main kernel's version, so +# this tree gets its own -- and a non-empty modules.alias is asserted, because +# a tree without one cannot autoload a single driver on the device. +define LINUX_RT_RUN_DEPMOD + @kver=$(LINUX_RT_VERSION_PROBED); \ + if test -d $(TARGET_DIR)/lib/modules/$$kver \ + && grep -q "CONFIG_MODULES=y" $(LINUX_RT_DIR)/.config; then \ + $(HOST_DIR)/sbin/depmod -a -b $(TARGET_DIR) $$kver; \ + test -s $(TARGET_DIR)/lib/modules/$$kver/modules.alias || { \ + echo "*** linux-rt: $(TARGET_DIR)/lib/modules/$$kver/modules.alias is missing or empty -- depmod did not run; this tree cannot autoload modules on device"; exit 1; }; \ + echo ">>> linux-rt $$kver: module tree depmod'd in $(TARGET_DIR)/lib/modules/$$kver"; \ + fi +endef +LINUX_RT_TARGET_FINALIZE_HOOKS += LINUX_RT_RUN_DEPMOD + +$(eval $(kconfig-package)) diff --git a/package/mister-drivers/Config.in b/package/mister-drivers/Config.in new file mode 100644 index 00000000..da4ada4d --- /dev/null +++ b/package/mister-drivers/Config.in @@ -0,0 +1,22 @@ +# PROFILE PACKAGE (ADR 0030 §5.7): the out-of-tree kernel modules and their +# firmware. Kept apart from mister-userspace because these are kernel-side and +# each one is a mainline-first policy decision (ADR 0016, ADR 0003): a board +# adopts the group deliberately, not as a side effect of wanting the userspace. +# DE10-Nano today; the DE25-Nano opts in by owner decision (docs/buildroot-config.md +# rule 5). + +config BR2_PACKAGE_MISTER_DRIVERS + bool "MiSTer out-of-tree drivers (USB WiFi and Xbox accessories)" + select BR2_PACKAGE_RTL8852CU_MORROWNR + select BR2_PACKAGE_AIC8800 + select BR2_PACKAGE_XONE + select BR2_PACKAGE_XOW_FIRMWARE + help + The out-of-tree kernel-module packages and their firmware: the two + USB WiFi chips mainline still has no driver for (RTL8852CU via + rtl8852cu-morrownr, the AICSemi AIC8800 family via aic8800) and the + Xbox One/Series accessory driver xone with its dongle firmware + (xow-firmware). Every other WiFi chip uses the in-kernel driver + (ADR 0016, docs/wifi-parity.md). + + This is a PROFILE: selecting it selects the whole list below. diff --git a/package/mister-firmware/Config.in b/package/mister-firmware/Config.in new file mode 100644 index 00000000..f2f0688b --- /dev/null +++ b/package/mister-firmware/Config.in @@ -0,0 +1,52 @@ +# PROFILE PACKAGE (ADR 0030 §5.7): one symbol that selects the firmware set +# both boards ship. A plain-Buildroot project would list every one of these in +# the defconfig; here the defconfig says BR2_PACKAGE_MISTER_FIRMWARE=y and the +# list lives HERE, so the DE10 and the DE25 cannot drift apart on it. To add a +# firmware file for both boards, add its `select` below; a board-only one goes +# in that board's configs/mister__defconfig instead. The reason for each +# line is in docs/buildroot-config.md §12 and docs/firmware-parity.md. + +config BR2_PACKAGE_MISTER_FIRMWARE + bool "MiSTer firmware set (shared by every board)" + select BR2_PACKAGE_LINUX_FIRMWARE + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7610E + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7650 + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT76X2E + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7921 + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7925 + select BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT2XX + select BR2_PACKAGE_LINUX_FIRMWARE_RTL_81XX + select BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX + select BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX_BT + select BR2_PACKAGE_LINUX_FIRMWARE_RTL_88XX_BT + select BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW88 + select BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW89 + select BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_9271 + select BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_7010 + select BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_9170 + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7921_BT + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7922_BT + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7925_BT + select BR2_PACKAGE_LINUX_FIRMWARE_QUALCOMM_6174A_BT + select BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_6004 + select BR2_PACKAGE_LINUX_FIRMWARE_REDPINE_RS9113 + select BR2_PACKAGE_LINUX_FIRMWARE_REDPINE_RS9116 + select BR2_PACKAGE_LINUX_FIRMWARE_AR3011 + select BR2_PACKAGE_LINUX_FIRMWARE_AR3012_USB + select BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XX + select BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XXX + select BR2_PACKAGE_WIRELESS_REGDB + select BR2_PACKAGE_LINUX_FIRMWARE_EXTRA + select BR2_PACKAGE_BCM20702_FIRMWARE + help + The /lib/firmware population both boards ship: Buildroot's + linux-firmware with the WiFi/Bluetooth sub-options the in-kernel + drivers request, wireless-regdb, and the two project packages for + files upstream Buildroot has no toggle for (linux-firmware-extra) or + that upstream linux-firmware does not carry (bcm20702-firmware). + + This is a PROFILE: selecting it selects the whole list below. It is + the one place package selection differs from a plain Buildroot + project, where each of these would be a line in the defconfig. + See docs/buildroot-config.md. diff --git a/package/mister-initramfs-busybox/Config.in b/package/mister-initramfs-busybox/Config.in new file mode 100644 index 00000000..9f6b06c6 --- /dev/null +++ b/package/mister-initramfs-busybox/Config.in @@ -0,0 +1,3 @@ +# Hidden: selected by BR2_PACKAGE_MISTER_INITRAMFS. See package/mister-initramfs/Config.in. +config BR2_PACKAGE_MISTER_INITRAMFS_BUSYBOX + bool diff --git a/package/mister-initramfs-busybox/mister-initramfs-busybox.hash b/package/mister-initramfs-busybox/mister-initramfs-busybox.hash new file mode 100644 index 00000000..c4f7fe54 --- /dev/null +++ b/package/mister-initramfs-busybox/mister-initramfs-busybox.hash @@ -0,0 +1,7 @@ +# Same tarball as Buildroot's package/busybox (dl/busybox/ is shared via +# _DL_SUBDIR); hashes transcribed from the same upstream source: +# https://www.busybox.net/downloads/busybox-1.38.0.tar.bz2.sha256 +sha256 34f9ea6ff8636f2c9241153b9114eefa9e65674a45318ae1ef95bb5f31c53bb2 busybox-1.38.0.tar.bz2 +# Locally computed +sha256 bbfc9843646d483c334664f651c208b9839626891d8f17604db2146962f43548 LICENSE +sha256 b5a136ed67798e51fe2e0ca0b2a21cb01b904ff0c9f7d563a6292e276607e58f archival/libarchive/bz/LICENSE diff --git a/package/mister-initramfs-busybox/mister-initramfs-busybox.mk b/package/mister-initramfs-busybox/mister-initramfs-busybox.mk new file mode 100644 index 00000000..11703765 --- /dev/null +++ b/package/mister-initramfs-busybox/mister-initramfs-busybox.mk @@ -0,0 +1,78 @@ +################################################################################ +# +# mister-initramfs-busybox +# +################################################################################ + +# The stage-1 initramfs's BusyBox: a SECOND BusyBox in this build, configured +# from board/mister/common/initramfs-busybox.config (a deliberately tiny +# applet set -- exactly what /init calls), linked -static against the main +# toolchain's glibc, and installed into its own build directory only +# (_install/). Nothing here reaches the rootfs; package/mister-initramfs turns +# the result into the cpio the kernel embeds. ADR 0002 as amended by ADR 0030: +# stage 1 used to be a separate musl Buildroot configuration because +# BR2_STATIC_LIBS is not offered with glibc -- a limit of a Buildroot +# *configuration*, not of a package that passes -static itself. Measured +# cost: 942,660 B static-glibc vs 263,308 B static-musl, against a 16 MiB +# zImage_dtb budget with ~7 MB of headroom (docs/boot-chain.md §7.3). +# +# Same tarball as Buildroot's own busybox package; _DL_SUBDIR makes the +# download land in dl/busybox/ so it is fetched once. Upstream's patch set for +# busybox is applied too (POST_PATCH hook), so this BusyBox carries the same +# fixes and CVE backports as the rootfs one. +# +# It is a kconfig-package, so `make mister-initramfs-busybox-menuconfig` edits +# the stage-1 BusyBox config and `make mister-initramfs-busybox-update-config` +# saves it back to board/mister/common/initramfs-busybox.config. + +MISTER_INITRAMFS_BUSYBOX_VERSION = 1.38.0 +MISTER_INITRAMFS_BUSYBOX_SOURCE = busybox-$(MISTER_INITRAMFS_BUSYBOX_VERSION).tar.bz2 +MISTER_INITRAMFS_BUSYBOX_SITE = https://www.busybox.net/downloads +MISTER_INITRAMFS_BUSYBOX_DL_SUBDIR = busybox +MISTER_INITRAMFS_BUSYBOX_LICENSE = GPL-2.0, bzip2-1.0.6 +MISTER_INITRAMFS_BUSYBOX_LICENSE_FILES = LICENSE archival/libarchive/bz/LICENSE +MISTER_INITRAMFS_BUSYBOX_CPE_ID_VENDOR = busybox +MISTER_INITRAMFS_BUSYBOX_INSTALL_TARGET = NO +MISTER_INITRAMFS_BUSYBOX_INSTALL_STAGING = NO + +MISTER_INITRAMFS_BUSYBOX_KCONFIG_FILE = $(BR2_EXTERNAL_MISTER_PATH)/board/mister/common/initramfs-busybox.config +MISTER_INITRAMFS_BUSYBOX_KCONFIG_EDITORS = menuconfig +MISTER_INITRAMFS_BUSYBOX_KCONFIG_OPTS = $(MISTER_INITRAMFS_BUSYBOX_MAKE_OPTS) + +MISTER_INITRAMFS_BUSYBOX_MAKE_ENV = \ + $(TARGET_MAKE_ENV) \ + CFLAGS="$(TARGET_CFLAGS)" +ifeq ($(BR2_REPRODUCIBLE),y) +MISTER_INITRAMFS_BUSYBOX_MAKE_ENV += KCONFIG_NOTIMESTAMP=1 +endif + +# CONFIG_PREFIX on the command line overrides the .config's "./_install"; +# BusyBox strips the final binary itself (no SKIP_STRIP: this binary never +# passes through Buildroot's target-finalize strip). +MISTER_INITRAMFS_BUSYBOX_MAKE_OPTS = \ + AR="$(TARGET_AR)" \ + NM="$(TARGET_NM)" \ + RANLIB="$(TARGET_RANLIB)" \ + CC="$(TARGET_CC)" \ + ARCH=$(NORMALIZED_ARCH) \ + EXTRA_LDFLAGS="$(TARGET_LDFLAGS)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + CONFIG_PREFIX="$(@D)/_install" + +# Static is the point; pin it whatever the committed config says. +define MISTER_INITRAMFS_BUSYBOX_KCONFIG_FIXUP_CMDS + $(call KCONFIG_ENABLE_OPT,CONFIG_STATIC) +endef + +define MISTER_INITRAMFS_BUSYBOX_APPLY_UPSTREAM_PATCHES + $(APPLY_PATCHES) $(@D) $(TOPDIR)/package/busybox \*.patch +endef +MISTER_INITRAMFS_BUSYBOX_POST_PATCH_HOOKS += MISTER_INITRAMFS_BUSYBOX_APPLY_UPSTREAM_PATCHES + +define MISTER_INITRAMFS_BUSYBOX_BUILD_CMDS + $(MISTER_INITRAMFS_BUSYBOX_MAKE_ENV) $(MAKE) $(MISTER_INITRAMFS_BUSYBOX_MAKE_OPTS) -C $(@D) + rm -rf $(@D)/_install + $(MISTER_INITRAMFS_BUSYBOX_MAKE_ENV) $(MAKE) $(MISTER_INITRAMFS_BUSYBOX_MAKE_OPTS) -C $(@D) install +endef + +$(eval $(kconfig-package)) diff --git a/package/mister-initramfs-exfatprogs/Config.in b/package/mister-initramfs-exfatprogs/Config.in new file mode 100644 index 00000000..80632524 --- /dev/null +++ b/package/mister-initramfs-exfatprogs/Config.in @@ -0,0 +1,3 @@ +# Hidden: selected by BR2_PACKAGE_MISTER_INITRAMFS. See package/mister-initramfs/Config.in. +config BR2_PACKAGE_MISTER_INITRAMFS_EXFATPROGS + bool diff --git a/package/mister-initramfs-exfatprogs/mister-initramfs-exfatprogs.hash b/package/mister-initramfs-exfatprogs/mister-initramfs-exfatprogs.hash new file mode 100644 index 00000000..05c722a5 --- /dev/null +++ b/package/mister-initramfs-exfatprogs/mister-initramfs-exfatprogs.hash @@ -0,0 +1,7 @@ +# Same tarball as Buildroot's package/exfatprogs (dl/exfatprogs/ is shared via +# _DL_SUBDIR); hash transcribed from the same upstream source: +# https://github.com/exfatprogs/exfatprogs/releases/download/1.2.9/exfatprogs-1.2.9.tar.xz.sha256 +sha256 d9a42197c6ff9e6a8e923789413008e317415cf7a4ab85c486c5ffcaf49ca175 exfatprogs-1.2.9.tar.xz + +# Hash for license file +sha256 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 COPYING diff --git a/package/mister-initramfs-exfatprogs/mister-initramfs-exfatprogs.mk b/package/mister-initramfs-exfatprogs/mister-initramfs-exfatprogs.mk new file mode 100644 index 00000000..a2e2e912 --- /dev/null +++ b/package/mister-initramfs-exfatprogs/mister-initramfs-exfatprogs.mk @@ -0,0 +1,29 @@ +################################################################################ +# +# mister-initramfs-exfatprogs +# +################################################################################ + +# A SECOND exfatprogs in this build: the same tarball Buildroot's own +# exfatprogs package builds (shared through _DL_SUBDIR, so it is downloaded +# once), linked -static against the main toolchain's glibc so that ONE binary, +# fsck.exfat, can live inside the stage-1 initramfs with no shared libc next +# to it. Nothing is installed to the rootfs; package/mister-initramfs copies +# fsck.exfat out of this package's build directory. ADR 0026 is the reason +# fsck.exfat is in stage 1 at all, and the reason mkfs/tune/label/dump are +# deliberately NOT copied: a card reformatter must never sit one typo away +# from the boot path. + +MISTER_INITRAMFS_EXFATPROGS_VERSION = 1.2.9 +MISTER_INITRAMFS_EXFATPROGS_SOURCE = exfatprogs-$(MISTER_INITRAMFS_EXFATPROGS_VERSION).tar.xz +MISTER_INITRAMFS_EXFATPROGS_SITE = https://github.com/exfatprogs/exfatprogs/releases/download/$(MISTER_INITRAMFS_EXFATPROGS_VERSION) +MISTER_INITRAMFS_EXFATPROGS_DL_SUBDIR = exfatprogs +MISTER_INITRAMFS_EXFATPROGS_LICENSE = GPL-2.0+ +MISTER_INITRAMFS_EXFATPROGS_LICENSE_FILES = COPYING +MISTER_INITRAMFS_EXFATPROGS_CPE_ID_VENDOR = namjaejeon +MISTER_INITRAMFS_EXFATPROGS_INSTALL_TARGET = NO +MISTER_INITRAMFS_EXFATPROGS_INSTALL_STAGING = NO + +MISTER_INITRAMFS_EXFATPROGS_CONF_ENV = LDFLAGS="$(TARGET_LDFLAGS) -static" + +$(eval $(autotools-package)) diff --git a/package/mister-initramfs/Config.in b/package/mister-initramfs/Config.in new file mode 100644 index 00000000..464d257e --- /dev/null +++ b/package/mister-initramfs/Config.in @@ -0,0 +1,21 @@ +config BR2_PACKAGE_MISTER_INITRAMFS + bool "mister-initramfs (stage-1 initramfs cpio for the kernel)" + select BR2_PACKAGE_MISTER_INITRAMFS_BUSYBOX + select BR2_PACKAGE_MISTER_INITRAMFS_EXFATPROGS + help + The MiSTer stage-1 initramfs (ADR 0002): a static BusyBox, a + static fsck.exfat and board/mister/common/initramfs-overlay/init, + packed into images/mister-initramfs.cpio. It replaces stock's + in-kernel do_mounts.c patch: /init mounts the SD data partition, + loop-mounts linux/linux.img off it and switch_roots into it. + + It is a PACKAGE of the main build (built with the main toolchain, + statically linked) rather than a second Buildroot configuration, + so one 'make' produces it and the kernel that embeds it. Enable + the kernel side with BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS (Kernel + -> Linux Kernel Extensions), which selects this package and points + CONFIG_INITRAMFS_SOURCE at the cpio. + + Nothing from this package is installed into the rootfs. + + https://github.com/mcfbytes/Buildroot_MiSTer/blob/master/docs/decisions/0002-initramfs.md diff --git a/package/mister-initramfs/mister-initramfs.mk b/package/mister-initramfs/mister-initramfs.mk new file mode 100644 index 00000000..74c0cc0f --- /dev/null +++ b/package/mister-initramfs/mister-initramfs.mk @@ -0,0 +1,67 @@ +################################################################################ +# +# mister-initramfs +# +################################################################################ + +# Assembles the stage-1 initramfs cpio (ADR 0002, as amended by ADR 0030) +# from two sibling packages built with the main toolchain -- a static BusyBox +# (mister-initramfs-busybox) and a static fsck.exfat +# (mister-initramfs-exfatprogs) -- plus board/mister/common/initramfs-overlay, +# whose /init is the whole point. The result goes to images/ only; nothing is +# installed into the rootfs. linux/linux-ext-mister-initramfs.mk embeds it. +# +# Root ownership and the /dev/console node need fakeroot, exactly as +# fs/common.mk does for the real rootfs images. With BR2_REPRODUCIBLE the +# mtimes are pinned to SOURCE_DATE_EPOCH and host-cpio's --reproducible is +# used, for the same reason fs/cpio does: the cpio is inside zImage_dtb, so +# a non-reproducible cpio makes the kernel non-reproducible. + +MISTER_INITRAMFS_DEPENDENCIES = \ + mister-initramfs-busybox \ + mister-initramfs-exfatprogs \ + host-fakeroot +MISTER_INITRAMFS_INSTALL_TARGET = NO +MISTER_INITRAMFS_INSTALL_IMAGES = YES + +ifeq ($(BR2_REPRODUCIBLE),y) +MISTER_INITRAMFS_DEPENDENCIES += host-cpio +MISTER_INITRAMFS_CPIO_OPTS = --reproducible +endif + +MISTER_INITRAMFS_OVERLAY = $(BR2_EXTERNAL_MISTER_PATH)/board/mister/common/initramfs-overlay +MISTER_INITRAMFS_ROOT = $(@D)/root +MISTER_INITRAMFS_IMAGE = $(@D)/mister-initramfs.cpio +MISTER_INITRAMFS_QEMU = $(if $(BR2_arm),qemu-arm,$(if $(BR2_aarch64),qemu-aarch64,)) + +# /init does its own `mkdir -p /proc /sys /dev /mnt/fat /newroot`; the +# directories are created here anyway so the tree is complete without it. +define MISTER_INITRAMFS_BUILD_CMDS + rm -rf $(MISTER_INITRAMFS_ROOT) $(MISTER_INITRAMFS_IMAGE) + mkdir -p $(MISTER_INITRAMFS_ROOT)/dev $(MISTER_INITRAMFS_ROOT)/proc \ + $(MISTER_INITRAMFS_ROOT)/sys $(MISTER_INITRAMFS_ROOT)/mnt/fat \ + $(MISTER_INITRAMFS_ROOT)/newroot $(MISTER_INITRAMFS_ROOT)/tmp \ + $(MISTER_INITRAMFS_ROOT)/etc $(MISTER_INITRAMFS_ROOT)/usr/sbin + cp -a $(MISTER_INITRAMFS_BUSYBOX_DIR)/_install/. $(MISTER_INITRAMFS_ROOT)/ + rm -f $(MISTER_INITRAMFS_ROOT)/linuxrc + $(INSTALL) -m 0755 $(MISTER_INITRAMFS_EXFATPROGS_DIR)/fsck/fsck.exfat \ + $(MISTER_INITRAMFS_ROOT)/usr/sbin/fsck.exfat + $(TARGET_CROSS)strip $(MISTER_INITRAMFS_ROOT)/usr/sbin/fsck.exfat + cp -a $(MISTER_INITRAMFS_OVERLAY)/. $(MISTER_INITRAMFS_ROOT)/ + echo '#!/bin/sh' > $(@D)/fakeroot.sh + echo 'set -e' >> $(@D)/fakeroot.sh + echo 'chown -h -R 0:0 $(MISTER_INITRAMFS_ROOT)' >> $(@D)/fakeroot.sh + echo 'mknod -m 0622 $(MISTER_INITRAMFS_ROOT)/dev/console c 5 1' >> $(@D)/fakeroot.sh + $(if $(BR2_REPRODUCIBLE),echo 'find $(MISTER_INITRAMFS_ROOT) -print0 | xargs -0 -r touch -hd @$(SOURCE_DATE_EPOCH)' >> $(@D)/fakeroot.sh) + echo 'cd $(MISTER_INITRAMFS_ROOT) && find . | LC_ALL=C sort | cpio $(MISTER_INITRAMFS_CPIO_OPTS) --quiet -o -H newc > $(MISTER_INITRAMFS_IMAGE)' >> $(@D)/fakeroot.sh + chmod +x $(@D)/fakeroot.sh + PATH=$(BR_PATH) FAKEROOTDONTTRYCHOWN=1 $(HOST_DIR)/bin/fakeroot -- $(@D)/fakeroot.sh + PATH=$(BR_PATH) $(BR2_EXTERNAL_MISTER_PATH)/package/mister-initramfs/verify.sh \ + $(MISTER_INITRAMFS_ROOT) $(MISTER_INITRAMFS_IMAGE) $(MISTER_INITRAMFS_QEMU) +endef + +define MISTER_INITRAMFS_INSTALL_IMAGES_CMDS + $(INSTALL) -m 0644 -D $(MISTER_INITRAMFS_IMAGE) $(BINARIES_DIR)/mister-initramfs.cpio +endef + +$(eval $(generic-package)) diff --git a/package/mister-initramfs/verify.sh b/package/mister-initramfs/verify.sh new file mode 100755 index 00000000..0843f40b --- /dev/null +++ b/package/mister-initramfs/verify.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# Structural checks on the assembled stage-1 tree and its cpio, run by +# package/mister-initramfs before the cpio is handed to the kernel. +# +# Every one of these is a real, shipped failure mode (ADR 0002 §8a): kconfig +# silently drops unknown BusyBox symbols, so a misspelled CONFIG_ turns into a +# cpio that looks healthy and an /init that dies on its first `[`. Check the +# artifact, not the intent. +# +# usage: verify.sh [qemu-user binary] +set -eu + +root=$1 +cpio_file=$2 +qemu=${3:-} +rc=0 + +fail() { echo "mister-initramfs: FATAL: $*" >&2; rc=1; } + +# Applets /init invokes. A missing one is a brick: /init dies before the +# rescue shell can even be reached. +for a in sh mount umount losetup switch_root cttyhack setsid sleep mkdir cat ls \ + dmesg tail findfs printf echo test rm sync; do + found=0 + for d in bin sbin usr/bin usr/sbin; do + [ -e "$root/$d/$a" ] && { found=1; break; } + done + [ $found -eq 1 ] || fail "/init needs '$a' but it is not in the tree. Check its CONFIG_ symbol really exists in this BusyBox version (kconfig silently discards unknown symbols) -- board/mister/common/initramfs-busybox.config" +done + +# ADR 0026: fsck.exfat present; the other exfatprogs tools absent (a card +# reformatter must not be one typo away from the boot path). +[ -x "$root/usr/sbin/fsck.exfat" ] || fail "/usr/sbin/fsck.exfat is missing or not executable (mister-initramfs-exfatprogs did not build it?)" +for b in dump.exfat exfat2img exfatlabel mkfs.exfat tune.exfat; do + for d in sbin usr/sbin bin usr/bin; do + [ -e "$root/$d/$b" ] && fail "$d/$b is in the tree and must not be (ADR 0026)" + done +done + +[ -f "$root/init" ] && [ -x "$root/init" ] || fail "/init is not a regular executable file (the overlay did not apply?)" + +# The shipped ash must be able to PARSE /init. shellcheck checks the language; +# this checks the interpreter we ship (e.g. FEATURE_SH_MATH for $((...))). +if [ -n "$qemu" ] && command -v "$qemu" >/dev/null 2>&1; then + "$qemu" "$root/bin/busybox" ash -n "$root/init" || fail "the BusyBox ash we just built cannot parse /init" +else + echo "mister-initramfs: WARN: ${qemu:-qemu-user} not available; skipping the ash -n parse check of /init" >&2 +fi + +# The cpio must carry /dev/console (c 5 1): without it /init has no stdio and +# the rescue shell is unreachable. +if [ -f "$cpio_file" ]; then + cpio -t --quiet < "$cpio_file" | grep -qx 'dev/console' || fail "dev/console is not in the cpio (fakeroot mknod step failed?)" + cpio -t --quiet < "$cpio_file" | grep -qx 'init' || fail "init is not in the cpio" +else + fail "cpio $cpio_file was not produced" +fi + +[ $rc -eq 0 ] && echo "mister-initramfs: verify OK ($(cpio -t --quiet < "$cpio_file" | grep -c .) entries, $(stat -c %s "$cpio_file") bytes)" +exit $rc diff --git a/package/mister-userspace/Config.in b/package/mister-userspace/Config.in new file mode 100644 index 00000000..2d989cf9 --- /dev/null +++ b/package/mister-userspace/Config.in @@ -0,0 +1,277 @@ +# PROFILE PACKAGE (ADR 0030 §5.7): THE MiSTer userspace -- every package the +# shipped rootfs carries beyond BusyBox and the toolchain, grouped exactly as +# docs/buildroot-config.md §5 documents them (the section markers below are +# that document's headings). A plain-Buildroot project would list all of these +# in the defconfig; here configs/mister_de10nano_defconfig says +# BR2_PACKAGE_MISTER_USERSPACE=y and the list lives HERE, so a second board +# gets the identical userspace by selecting one symbol, and "why is package X +# in my image" is answered by this file's section headers and §5's rationale. +# +# Not in here, on purpose: firmware (package/mister-firmware), out-of-tree +# drivers (package/mister-drivers), the kernel variant (BR2_PACKAGE_LINUX_RT) +# and the stage-1 initramfs (a linux extension) -- each is its own decision. +# Package sub-options that are strings or `is not set` cannot be `select`ed +# and stay in the defconfig (busybox fragment path, OPENSSH_SANDBOX, ...). +# +# `select` force-enables a package even when its own `depends on` is unmet +# (kconfig warns), so a package that only builds on one architecture must NOT +# go here -- it belongs in that board's defconfig. And a Kconfig `choice` +# member (a PROVIDER choice such as BR2_PACKAGE_ZLIB_NG vs LIBZLIB, or the +# jpeg/openssl providers) cannot be `select`ed at all: kconfig SILENTLY +# ignores the select and the choice falls to its default. Those lines stay in +# the defconfig; scripts/check-defconfigs.sh asserts every `select` below +# really lands in the resolved config, so a silent drop fails CI. + +config BR2_PACKAGE_MISTER_USERSPACE + bool "MiSTer userspace (the shared package set)" + # --- compression (§5.4) --- + select BR2_PACKAGE_ZLIB + # (BR2_PACKAGE_ZLIB_NG is a `choice` member and cannot be selected -- it + # stays in the defconfig; see the header.) + select BR2_PACKAGE_BZIP2 + select BR2_PACKAGE_XZ + select BR2_PACKAGE_LZO + select BR2_PACKAGE_ZSTD + select BR2_PACKAGE_MINIZIP + select BR2_PACKAGE_MINIZIP_ZLIB + # --- Main_MiSTer shared libs (§5.5, docs/main-shared-libs.md) --- + select BR2_PACKAGE_LZMA_SDK + select BR2_PACKAGE_LIBCHDR + # --- graphics / fonts (§5.6) --- + select BR2_PACKAGE_FREETYPE + select BR2_PACKAGE_LIBPNG + select BR2_PACKAGE_JPEG + select BR2_PACKAGE_JPEG_TURBO + select BR2_PACKAGE_TIFF + select BR2_PACKAGE_GIFLIB + select BR2_PACKAGE_IMLIB2 + select BR2_PACKAGE_IMLIB2_JPEG + select BR2_PACKAGE_IMLIB2_PNG + select BR2_PACKAGE_IMLIB2_GIF + select BR2_PACKAGE_IMLIB2_TIFF + select BR2_PACKAGE_IMLIB2_ID3 + select BR2_PACKAGE_LIBXKBCOMMON + select BR2_PACKAGE_SDL2 + # --- audio (§5.7) --- + select BR2_PACKAGE_ALSA_LIB + select BR2_PACKAGE_LIBAO + select BR2_PACKAGE_LIBVORBIS + select BR2_PACKAGE_LIBOGG + select BR2_PACKAGE_MPG123 + select BR2_PACKAGE_LIBID3TAG + select BR2_PACKAGE_LIBMODPLUG + select BR2_PACKAGE_FLUIDSYNTH + select BR2_PACKAGE_FLUIDSYNTH_ALSA_LIB + # --- MIDI / MT-32 (P3.8) + ALSA CLI tools (P3.15) (§5.8, docs/midi-mt32-parity.md) --- + select BR2_PACKAGE_MUNT + select BR2_PACKAGE_MIDILINK + select BR2_PACKAGE_ALSA_UTILS + select BR2_PACKAGE_ALSA_UTILS_ACONNECT + select BR2_PACKAGE_ALSA_UTILS_AMIDI + select BR2_PACKAGE_ALSA_UTILS_APLAYMIDI + select BR2_PACKAGE_ALSA_UTILS_ARECORDMIDI + select BR2_PACKAGE_ALSA_UTILS_ASEQDUMP + select BR2_PACKAGE_ALSA_UTILS_ASEQNET + select BR2_PACKAGE_ALSA_UTILS_ALSACTL + select BR2_PACKAGE_ALSA_UTILS_ALSALOOP + select BR2_PACKAGE_ALSA_UTILS_ALSAMIXER + select BR2_PACKAGE_ALSA_UTILS_ALSATPLG + select BR2_PACKAGE_ALSA_UTILS_ALSAUCM + select BR2_PACKAGE_ALSA_UTILS_AMIXER + select BR2_PACKAGE_ALSA_UTILS_APLAY + select BR2_PACKAGE_ALSA_UTILS_BAT + select BR2_PACKAGE_ALSA_UTILS_IECSET + select BR2_PACKAGE_ALSA_UTILS_SPEAKER_TEST + # --- crypto / TLS (§5.9) --- + select BR2_PACKAGE_OPENSSL + select BR2_PACKAGE_LIBOPENSSL + select BR2_PACKAGE_GNUTLS + select BR2_PACKAGE_LIBGCRYPT + select BR2_PACKAGE_LIBSSH2 + select BR2_PACKAGE_CA_CERTIFICATES + # --- networking / D-Bus / GLib (§5.10) --- + select BR2_PACKAGE_LIBCURL + select BR2_PACKAGE_LIBCURL_CURL + select BR2_PACKAGE_LIBCURL_OPENSSL + select BR2_PACKAGE_WGET + select BR2_PACKAGE_DBUS + select BR2_PACKAGE_DBUS_CPP + select BR2_PACKAGE_DBUS_GLIB + select BR2_PACKAGE_LIBEVENT + select BR2_PACKAGE_LIBNL + select BR2_PACKAGE_IPTABLES + select BR2_PACKAGE_LIBGLIB2 + select BR2_PACKAGE_GOBJECT_INTROSPECTION + # --- util-linux / e2fsprogs / disk & fs tools (§5.11, docs/util-linux-parity.md) --- + select BR2_PACKAGE_UTIL_LINUX + select BR2_PACKAGE_UTIL_LINUX_LIBBLKID + select BR2_PACKAGE_UTIL_LINUX_LIBFDISK + select BR2_PACKAGE_UTIL_LINUX_LIBMOUNT + select BR2_PACKAGE_UTIL_LINUX_LIBSMARTCOLS + select BR2_PACKAGE_UTIL_LINUX_LIBUUID + select BR2_PACKAGE_UTIL_LINUX_BINARIES + select BR2_PACKAGE_UTIL_LINUX_MOUNT + select BR2_PACKAGE_UTIL_LINUX_MOUNTPOINT + select BR2_PACKAGE_UTIL_LINUX_AGETTY + select BR2_PACKAGE_UTIL_LINUX_HWCLOCK + select BR2_PACKAGE_UTIL_LINUX_FSCK + select BR2_PACKAGE_UTIL_LINUX_PARTX + select BR2_PACKAGE_UTIL_LINUX_SCHEDUTILS + select BR2_PACKAGE_UTIL_LINUX_IRQTOP + select BR2_PACKAGE_UTIL_LINUX_KILL + select BR2_PACKAGE_UTIL_LINUX_MORE + select BR2_PACKAGE_UTIL_LINUX_NEWGRP + select BR2_PACKAGE_UTIL_LINUX_NOLOGIN + select BR2_PACKAGE_UTIL_LINUX_RENAME + select BR2_PACKAGE_UTIL_LINUX_SETTERM + select BR2_PACKAGE_UTIL_LINUX_SWITCH_ROOT + select BR2_PACKAGE_E2FSPROGS + select BR2_PACKAGE_PARTED + select BR2_PACKAGE_NTFS_3G + select BR2_PACKAGE_NTFS_3G_NTFSPROGS + select BR2_PACKAGE_KMOD + select BR2_PACKAGE_INOTIFY_TOOLS + select BR2_PACKAGE_JQ + select BR2_PACKAGE_EXPAT + select BR2_PACKAGE_POPT + select BR2_PACKAGE_READLINE + select BR2_PACKAGE_NCURSES + select BR2_PACKAGE_NCURSES_WCHAR + select BR2_PACKAGE_SLANG + select BR2_PACKAGE_NEWT + select BR2_PACKAGE_GPM + select BR2_PACKAGE_LIBARCHIVE + select BR2_PACKAGE_LIBFUSE + # --- USB / input (§5.12, docs/usb-automount-parity.md) --- + select BR2_PACKAGE_LIBUSB + select BR2_PACKAGE_LIBUSB_COMPAT + select BR2_PACKAGE_LIBEVDEV + select BR2_PACKAGE_LIBINPUT + select BR2_PACKAGE_MTDEV + select BR2_PACKAGE_USBMOUNT + # --- Bluetooth (§5.13) --- + select BR2_PACKAGE_BLUEZ5_UTILS + select BR2_PACKAGE_BLUEZ5_UTILS_CLIENT + select BR2_PACKAGE_BLUEZ5_UTILS_TOOLS + select BR2_PACKAGE_BLUEZ5_UTILS_DEPRECATED + select BR2_PACKAGE_BLUEZ5_UTILS_PLUGINS_SIXAXIS + # --- PAM / capabilities (§5.14) --- + select BR2_PACKAGE_LINUX_PAM + select BR2_PACKAGE_LIBCAP + select BR2_PACKAGE_LIBCAP_NG + # --- misc small libraries / tools (§5.15) --- + select BR2_PACKAGE_DTC + select BR2_PACKAGE_DTC_PROGRAMS + select BR2_PACKAGE_SUDO + select BR2_PACKAGE_BUSYBOX_SHOW_OTHERS + select BR2_PACKAGE_I2C_TOOLS + select BR2_PACKAGE_JIMTCL + select BR2_PACKAGE_LIBLOCKFILE + select BR2_PACKAGE_LIBXML2 + select BR2_PACKAGE_FILE + select BR2_PACKAGE_MEMTOOL + select BR2_PACKAGE_PCRE2 + select BR2_PACKAGE_EUDEV + # --- lftp (§5.16) --- + select BR2_PACKAGE_LFTP + # --- Python (A6 / P3.9) + btctl runtime (§5.17, docs/python-compat.md) --- + select BR2_PACKAGE_PYTHON3 + select BR2_PACKAGE_PYTHON3_SSL + select BR2_PACKAGE_PYTHON3_ZLIB + select BR2_PACKAGE_PYTHON3_BZIP2 + select BR2_PACKAGE_PYTHON3_XZ + select BR2_PACKAGE_PYTHON3_PYEXPAT + select BR2_PACKAGE_PYTHON3_READLINE + select BR2_PACKAGE_PYTHON3_CURSES + select BR2_PACKAGE_DBUS_PYTHON + select BR2_PACKAGE_PYTHON_GOBJECT + # --- Samba: standalone file server only (§5.18) --- + select BR2_PACKAGE_SAMBA4 + # --- daemons / user-facing binaries (§5.19, docs/ssh-ftp-parity.md, docs/wifi-parity.md) --- + select BR2_PACKAGE_OPENSSH + select BR2_PACKAGE_PROFTPD + select BR2_PACKAGE_WPA_SUPPLICANT + select BR2_PACKAGE_WPA_SUPPLICANT_NL80211 + select BR2_PACKAGE_WPA_SUPPLICANT_WEXT + select BR2_PACKAGE_WPA_SUPPLICANT_DEBUG_SYSLOG + select BR2_PACKAGE_WPA_SUPPLICANT_WPA3 + select BR2_PACKAGE_WPA_SUPPLICANT_CLI + select BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE + select BR2_PACKAGE_BASH + select BR2_PACKAGE_DIALOG + select BR2_PACKAGE_WIRELESS_TOOLS + select BR2_PACKAGE_WIRELESS_TOOLS_IWCONFIG + select BR2_PACKAGE_IW + select BR2_PACKAGE_IPROUTE2 + # --- editors, ifupdown, BusyBox config fragment, dhcpcd, ntp, cifs (§5.20) --- + select BR2_PACKAGE_JOE + select BR2_PACKAGE_NANO + select BR2_PACKAGE_IFUPDOWN + select BR2_PACKAGE_DHCPCD + select BR2_PACKAGE_NTP + select BR2_PACKAGE_CIFS_UTILS + # --- Midnight Commander (T3, §5.21) --- + select BR2_PACKAGE_MC + # --- NFS client userland (ADR 0022, §5.22) --- + select BR2_PACKAGE_NFS_UTILS + select BR2_PACKAGE_NFS_UTILS_NFSV4 + # --- rsync, BusyBox (§5.23) --- + select BR2_PACKAGE_RSYNC + select BR2_PACKAGE_BUSYBOX + # --- dualsensectl (§5.26, docs/dualsense-tooling.md) --- + select BR2_PACKAGE_DUALSENSECTL + # --- ltunify: Logitech Unifying pairing (§5.27, docs/logitech-pairing.md) --- + select BR2_PACKAGE_LTUNIFY + # --- kmod: target tools (§5.30; the HOST xz half is in de10nano.fragment) --- + select BR2_PACKAGE_KMOD_TOOLS + # --- T5: process / file / syscall inspection (§5.32) --- + select BR2_PACKAGE_HTOP + select BR2_PACKAGE_STRACE + select BR2_PACKAGE_LSOF + # --- T5: USB / input / joystick & force-feedback (§5.33) --- + select BR2_PACKAGE_USBUTILS + select BR2_PACKAGE_EVTEST + select BR2_PACKAGE_LINUXCONSOLETOOLS + select BR2_PACKAGE_LINUXCONSOLETOOLS_JOYSTICK + select BR2_PACKAGE_LINUXCONSOLETOOLS_FORCEFEEDBACK + # --- T5: filesystem tools, FAT/exFAT (§5.34) --- + select BR2_PACKAGE_DOSFSTOOLS + select BR2_PACKAGE_DOSFSTOOLS_FATLABEL + select BR2_PACKAGE_DOSFSTOOLS_FSCK_FAT + select BR2_PACKAGE_DOSFSTOOLS_MKFS_FAT + select BR2_PACKAGE_EXFATPROGS + # --- T5: serial / terminal (§5.35) --- + select BR2_PACKAGE_PICOCOM + select BR2_PACKAGE_LRZSZ + select BR2_PACKAGE_TMUX + # --- T5: network diagnostics (§5.36) --- + select BR2_PACKAGE_ETHTOOL + select BR2_PACKAGE_SOCAT + select BR2_PACKAGE_TCPDUMP + select BR2_PACKAGE_IPERF3 + # --- T5: archival — package/7zip (OURS), not upstream p7zip (ADR 0023, §5.37) --- + select BR2_PACKAGE_7ZIP + select BR2_PACKAGE_ZIP + select BR2_PACKAGE_LZOP + # --- T5: hardware buses (§5.39) --- + select BR2_PACKAGE_SPI_TOOLS + # --- T5: Bluetooth CLI (§5.40) --- + select BR2_PACKAGE_BLUEZ_TOOLS + # --- T5: console / keyboard (§5.41) --- + select BR2_PACKAGE_KBD + select BR2_PACKAGE_GDB + select BR2_PACKAGE_GDB_SERVER + select BR2_PACKAGE_GDB_DEBUGGER + select BR2_PACKAGE_LINUX_TOOLS_PERF + select BR2_PACKAGE_LINUX_TOOLS_PERF_NEEDS_HOST_PYTHON3 + select BR2_PACKAGE_RT_TESTS + help + The complete MiSTer userspace package set, as one symbol: shared + libraries Main_MiSTer links against, audio/MIDI, networking, disk + tools, Bluetooth, Python, Samba, SSH/FTP, WiFi userland, editors and + the diagnostic tools (docs/buildroot-config.md §5, docs/package-manifest.md). + + This is a PROFILE: selecting it selects the whole list below. + It is the one place this project differs from a plain Buildroot + defconfig, where each package would be its own line -- see the + comment at the top of package/mister-userspace/Config.in. diff --git a/release-work/7za b/release-work/7za new file mode 100755 index 00000000..6f7f6a15 Binary files /dev/null and b/release-work/7za differ diff --git a/release-work/7za.gz b/release-work/7za.gz new file mode 100644 index 00000000..064dd2e7 Binary files /dev/null and b/release-work/7za.gz differ diff --git a/release-work/debugfs.log b/release-work/debugfs.log new file mode 100644 index 00000000..bf978405 --- /dev/null +++ b/release-work/debugfs.log @@ -0,0 +1,2 @@ +debugfs 1.47.2 (1-Jan-2025) +dump_file: Operation not permitted while changing ownership of /mnt/source/Buildroot_MiSTer-vanilla/release-work/ver/MiSTer.version diff --git a/release-work/downloader-extract/files/linux/7za b/release-work/downloader-extract/files/linux/7za new file mode 100755 index 00000000..4dabc74f Binary files /dev/null and b/release-work/downloader-extract/files/linux/7za differ diff --git a/release-work/downloader-extract/files/linux/MidiLink.INI b/release-work/downloader-extract/files/linux/MidiLink.INI new file mode 100644 index 00000000..24c8a571 --- /dev/null +++ b/release-work/downloader-extract/files/linux/MidiLink.INI @@ -0,0 +1,64 @@ +#This is the MidiLink INI File! +#Edit with Notepad++ under Windows + +MIDILINK_PRIORITY = -20 +MUNT_OPTIONS = +MP3_VOLUME = -1 +MUNT_VOLUME = -1 +MODEM_VOLUME = -1 +FSYNTH_VOLUME = -1 +MIXER_CONTROL = Master +MUNT_ROM_PATH = /media/fat/linux/mt32-rom-data +FSYNTH_SOUNDFONT = /media/fat/linux/soundfonts/SC-55.sf2 +UDP_SERVER = 192.168.1.130 +UDP_SERVER_PORT = 1999 +UDP_SERVER_FILTER = FALSE +UDP_FLOW = 0 +TCP_SERVER_PORT = 23 +TCP_TERM_UPLOAD = /media/fat/UPLOAD +TCP_TERM_DOWNLOAD = /media/fat +TCP_TERM_MP3 = /media/fat/MP3 +TCP_TERM_MIDI = /media/fat/MIDI +TCP_TERM_SYNTH = FluidSynth +TCP_TERM_ROWS = 23 +TCP_FLOW = 3 +TCP_SOUND = TRUE +DELAYSYSEX = TRUE +#USB_SERIAL_MODULE = /media/fat/pl2303.ko + +[AO486] +MIDI_BAUD = 31250 +UDP_BAUD = 38400 +#TCP_SOUND_CONNECT = /media/fat/SOUNDS/connect_sav.wav + +[ATARIST] +TCP_BAUD = 19200 +UDP_BAUD = 31250 +UDP_BAUD_ALT = 19200 +TCP_BAUD_ALT = 19200 + +[C64] +TCP_TERM_TRANS = PETSKII +MIDI_BAUD = 2400 +TCP_BAUD = 2400 +TCP_TERM_ROWS = 24 +TCP_ATH_DELAY = 0 + +[FXCAST] +TCP_BAUD = 19200 +UDP_BAUD = 31250 + +[MINIMIG] +TCP_TERM_ROWS = 22 +USB_SERIAL_BAUD = 9600 + +[NES] +MIDI_BAUD = 31250 + +[GBMIDI] +MIDI_BAUD = 31250 +UDP_BAUD = 31250 + +[X68000] +MIDI_BAUD = 31250 +DELAYSYSEX = FALSE diff --git a/release-work/downloader-extract/files/linux/_samba.sh b/release-work/downloader-extract/files/linux/_samba.sh new file mode 100644 index 00000000..b1e64129 --- /dev/null +++ b/release-work/downloader-extract/files/linux/_samba.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +SAMBA_USER=root +SAMBA_PASS=1 + +#================================================================== +(echo $SAMBA_PASS; echo $SAMBA_PASS;) | smbpasswd -a -s $SAMBA_USER diff --git a/release-work/downloader-extract/files/linux/_user-startup.sh b/release-work/downloader-extract/files/linux/_user-startup.sh new file mode 100644 index 00000000..25b9f9a0 --- /dev/null +++ b/release-work/downloader-extract/files/linux/_user-startup.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "***" $1 "***" diff --git a/release-work/downloader-extract/files/linux/_wpa_supplicant.conf b/release-work/downloader-extract/files/linux/_wpa_supplicant.conf new file mode 100644 index 00000000..9098ed29 --- /dev/null +++ b/release-work/downloader-extract/files/linux/_wpa_supplicant.conf @@ -0,0 +1,8 @@ +ctrl_interface=/run/wpa_supplicant +update_config=1 +country=TW + +network={ + ssid="put_your_SSID_here" + psk="put_your_password_here" +} diff --git a/release-work/downloader-extract/files/linux/gamecontrollerdb/gamecontrollerdb.txt b/release-work/downloader-extract/files/linux/gamecontrollerdb/gamecontrollerdb.txt new file mode 100644 index 00000000..51cbeb12 --- /dev/null +++ b/release-work/downloader-extract/files/linux/gamecontrollerdb/gamecontrollerdb.txt @@ -0,0 +1,582 @@ +# Original source: +# Game Controller DB for SDL in 2.0.16 format +# Source: https://github.com/gabomdq/SDL_GameControllerDB + +# Modified to remove non-Linux platforms and add MiSTer specific entries +030000005e0400008e02000020010000,8BitDo Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, +03000000021000000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000151000000010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000650000011010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, +03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, +03000000022000000090000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000631000014010000,8BitDo Pro 2 Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00001030000011010000,8BitDo Pro 2 Wired Controller,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000020000000000000,8BitDo Pro 2 Wired Controller for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +06000000c82d00000020000006010000,8BitDo Pro 2 Wired Controller for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00000131000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000231000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000331000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000431000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Linux, +05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +030000003512000012ab000010010000,8BitDo SFC30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux, +030000003512000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000102800000900000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00003028000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000351000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000260000011010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001130000011010000,8BitDo Ultimate Wired,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000760000011010000,8BitDo Ultimate Wireless,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001230000011010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00001330000011010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000121000011010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00000121000000010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, +05000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +050000005e040000e002000030110000,8BitDo Zero 2,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, +05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c01100000355000011010000,Acrux Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00003901000000430000,Afterglow Prismatic Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003901000013020000,Afterglow Prismatic Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001302000000010000,Afterglow Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003901000020060000,Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000100000008200000011010000,Akishop Customs PS360,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000007c1800000006000010010000,Alienware Dual Compatible Game PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +05000000491900000204000021000000,Amazon Fire Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux, +05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, +05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, +03000000050b00000579000011010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b36,paddle1:b52,paddle2:b53,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b21,paddle1:b22,paddle2:b23,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +03000000503200000110000011010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +05000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +05000000503200000110000044010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +05000000503200000110000046010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +03000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux, +03000000503200000210000011010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000045010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000046010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:-a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux, +03000000c62400001b89000011010000,BDA MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000c21100000791000011010000,Be1 GC101 Controller 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000c31100000791000011010000,Be1 GC101 Controller 1.03,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000005e0400008e02000003030000,Be1 GC101 Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000bc2000004d50000011010000,BEITONG A1T2 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000bc2000000055000001000000,BETOP AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006b1400000209000011010000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000200e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000210e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux, +03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux, +03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000242f00009100000000010000,EasySMX ESM-9101,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, +030000006e0500000720000010010000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux, +030000007d0400000640000010010000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Linux, +03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000007e0500003703000000000000,GameCube Adapter,a:b0,b:b1,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +19000000030000000300000002030000,GameForce Controller,a:b1,b:b0,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000ac0500005b05000010010000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ac0500001a06000011010000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +190000004b4800000010000000010000,GO-Advance Controller,a:b1,b:b0,back:b10,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,leftshoulder:b4,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b13,start:b15,x:b2,y:b3,platform:Linux, +190000004b4800000010000001010000,GO-Advance Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b13,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b16,righttrigger:b15,start:b17,x:b2,y:b3,platform:Linux, +190000004b4800000011000000010000,GO-Super Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b2,y:b3,platform:Linux, +03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000007d0400000540000000010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux, +030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +06000000adde0000efbe000002010000,Hidromancer Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, +03000000c9110000f055000011010000,HJC Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000632500002605000010010000,HJDX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux, +030000000d0f00006d00000020010000,Hori EDGE 301,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:+a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00008400000011010000,Hori Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005f00000011010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005e00000011010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005001000009040000,Hori Fighting Commander OCTA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00008500000010010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00008600000002010000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00003701000013010000,Hori Fighting Stick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b3,y:b2,platform:Linux, +030000000d0f00008800000011010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00008700000011010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,rightstick:b11,righttrigger:a4,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00001000000011010000,Hori Fightstick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000003f5000033050000,Hori Fightstick VX,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b8,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00004d00000011010000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux, +030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f0000aa00000011010000,Hori Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000000d0f00001100000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00002200000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00001600000000010000,Hori Real Arcade Pro EXSE,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00008501000015010000,Hori Switch Split Pad Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00006e00000011010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006600000011010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f0000ee00000011010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006700000001010000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +050000000d0f0000f600000001000000,Horipad Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +05000000242e00000b20000001000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Linux, +03000000242e0000ff0b000011010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Linux, +03000000242e00006a38000010010000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,start:b5,leftshoulder:b2,rightshoulder:b3,leftx:a0,lefty:a1,platform:Linux, +03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000f00300008d03000011010000,HyperX Clutch,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, +050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux, +03000000120c00000500000010010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, +03000000ef0500000300000000010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, +03000000fd0500000030000000010000,InterAct GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Linux, +03000000fd0500002a26000000010000,InterAct HammerHead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, +0500000049190000020400001b010000,Ipega PG 9069,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000632500007505000011010000,Ipega PG 9099,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +0500000049190000030400001b010000,Ipega PG9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000491900000204000000000000,Ipega PG9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000300f00001001000010010000,Jess Tech Dual Analog Rumble,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000ba2200002010000001010000,Jess Technology Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux, +050000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux, +030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, +03000000bd12000003c0000010010000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000242f00002d00000011010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000242f00008a00000011010000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, +030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d040000d1ca000000000000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001dc2000014400000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001ec2000019200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001ec2000020200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000019c2000011010000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001fc2000005030000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, +030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux, +05000000380700006652000025010000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008532000010010000,Mad Catz Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000380700005032000011010000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700005082000011010000,Mad Catz Fightpad Pro PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, +03000000380700008034000011010000,Mad Catz Fightstick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008084000011010000,Mad Catz Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008433000011010000,Mad Catz Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008483000011010000,Mad Catz Fightstick TE S PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700001888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700003888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700001647000010040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000380700003847000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +030000008f0e00001330000010010000,Mayflash Controller Adapter,a:b1,b:b2,back:b8,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3~,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +03000000790000004318000010010000,Mayflash GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, +0300000079000000d218000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000242f0000f700000001010000,Mayflash Magic S Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000008f0e00001030000010010000,Mayflash Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux, +0300000025090000e803000001010000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +03000000790000000318000011010000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux, +03000000790000000018000011010000,Mayflash Wii U Pro Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000b50700001203000010010000,Mega World Logic 3 Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000780000000600000010010000,Microntek Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +030000005e0400002800000000010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Linux, +030000005e0400000300000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux, +030000005e0400000700000000010000,Microsoft SideWinder,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux, +030000005e0400000e00000000010000,Microsoft SideWinder Freestyle Pro,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, +030000005e0400002700000000010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Linux, +030000005e0400008502000000010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e0400008902000021010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e0400008e02000001000000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.1,dpleft:h0.2,dpright:h0.8,dpup:h0.4,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000004010000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000056210000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000062230000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000001010000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000dd02000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000008040000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000e302000003020000,Microsoft Xbox One Elite,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000005e040000120b00000b050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, +050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +05000000e80400006e0400001b010000,Mocute 053X M59,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000004d4f435554452d3035305800,Mocute 054X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000d6200000e589000001000000,Moga 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +05000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +03000000c62400002b89000011010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c62400001a89000000010000,MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux, +03000000790000004518000010010000,Nexilux GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux, +060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +030000009b2800008000000020020000,Nintendo Classic Controller,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux, +030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux, +03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux, +060000004e696e74656e646f20537700,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +060000007e0500000620000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b16,b:b15,back:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,platform:Linux, +03000000d620000013a7000011010000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000007e0500000920000000026803,Nintendo Switch Pro Controller,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Linux, +030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux, +05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux, +050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux, +050000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux, +05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux, +03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux, +19000000010000000200000011000000,ODROID Go 2,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux, +03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:Linux, +05000000362800000100000002010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +05000000362800000100000003010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +05000000362800000100000004010000,OUYA Controller,a:b0,b:b3,back:b14,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b16,x:b1,y:b2,platform:Linux, +03000000830500005020000010010000,Padix Rockfire PlayStation Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux, +03000000ff1100003133000010010000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e0000b802000001010000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000b802000013020000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00008001000011010000,PDP Faceoff Nintendo Switch Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00008501000011010000,PDP Nintendo Switch Fightpad Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00002801000011010000,PDP PS3 Rock Candy Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00000901000011010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000004f9000000010000,PDP Xbox 360 Versus Fighting,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000a802000023020000,PDP Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000d802000006640000,PDP Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000666600006706000000010000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, +030000004c050000da0c000011010000,PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000d9040000160f000000010000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c62400001a53000000010000,PowerA Mini Pro Ex,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000c62400001a58000001010000,PowerA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000220000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, +03000000d62000000228000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000f20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000005f1400003102000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00001402000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000008f0e00000300000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +050000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +050000004c0500006802000000800000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +05000000504c415953544154494f4e00,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +060000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +03000000c01100000140000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000c405000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000f20d000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000f20d000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +03000000300f00001211000011010000,Qanba Arcade Joystick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux, +03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000222c00000020000011010000,Qanba Drone Arcade PS4 Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux, +03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000009b2800000300000001010000,Raphnet 4nes4snes,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, +030000009b2800004200000001010000,Raphnet Dual NES Adapter,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux, +030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, +030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, +030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000321500000204000011010000,Razer Panthera PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000104000011010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000810000011010000,Razer Panthera PS4 Evo Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000010000011010000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000321500000a10000001000000,Razer Raiju Tournament Edition,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000011000011010000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000008916000000fe000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c6240000045d000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux, +190000004b4800000111000000010000,RetroGame Joypad,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux, +0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +00000000526574726f53746f6e653200,RetroStone 2 Controller,a:b1,b:b0,back:b10,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Linux, +03000000341200000400000000010000,RetroUSB N64 RetroPort,+rightx:b8,+righty:b10,-rightx:b9,-righty:b11,a:b7,b:b6,dpdown:b2,dpleft:b1,dpright:b0,dpup:b3,leftshoulder:b13,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b12,start:b4,platform:Linux, +030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00001f01000000010000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00008701000011010000,Rock Candy Switch Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000c6240000fefa000000010000,Rock Candy Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000a306000023f6000011010000,Saitek Cyborg V1 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux, +03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux, +03000000a30600000cff000010010000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux, +03000000a30600000c04000011010000,Saitek P2900,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, +03000000a306000018f5000010010000,Saitek P3200 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, +03000000a30600000b04000000010000,Saitek P990 Dual Analog,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux, +03000000a306000020f6000011010000,Saitek PS2700 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +05000000e804000000a000001b010000,Samsung EIGP20,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux, +03000000a30c00002500000011010000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux, +03000000790000001100000011010000,Sega Saturn,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux, +03000000790000002201000011010000,Sega Saturn,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, +03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux, +030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000632500007505000010010000,Shanwan PS3 PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000bc2000000055000010010000,Shanwan PS3 PC ,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, +03000000250900000500000000010000,Sony PS2 pad with SmartJoy Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000005e0400008e02000073050000,Speedlink Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000020200000,SpeedLink Xeox Pro Analog,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000512000010010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,platform:Linux, +03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b10,guide:b11,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Linux, +03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000ad1b000038f0000090040000,Street Fighter IV Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000003b07000004a1000000010000,Suncom SFX Plus,a:b0,b:b2,back:b7,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux, +03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +030000008f0e00000d31000010010000,SZMY Power 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000457500000401000011010000,SZMY Power DS4 Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000457500002211000010010000,SZMY Power Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000008f0e00001431000010010000,SZMY Power PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux, +03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000020b3000010010000,Thrustmaster Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000023b3000000010000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f0400000ed0000011010000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux, +030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux, +030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, +030000004f04000004b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000026b3000002040000,Thrustmaster GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c6240000025b000002020000,Thrustmaster GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000004f04000008d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000009d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000007d0000000010000,Thrustmaster T Mini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000012b3000010010000,Thrustmaster Vibrating Gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +03000000571d00002000000010010000,Tomee SNES Adapter,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, +03000000bd12000015d0000010010000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000d814000007cd000011010000,Toodles 2008 Chimp PC PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux, +030000005e0400008e02000070050000,Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c01100000591000011010000,Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000680a00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +03000000780300000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +03000000e00d00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +03000000f00600000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000151900005678000010010000,Uniplay U6,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, +03000000790000001100000000010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux, +030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00000702000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +05000000ac0500003232000001000000,VR Box Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +05000000434f4d4d414e440000000000,VX Gaming Command Series,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +0000000058626f782033363020576900,Xbox 360 Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, +030000005e0400001907000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000014010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400009102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000000010000,Xbox 360 EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000006f0e00001304000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +0000000058626f782047616d65706100,Xbox Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000001030000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000009050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000007050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000009050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000011050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000015050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +060000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux, +03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux, +xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000120c0000100e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000101e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +# MiSTer specific default controller mappings + +#MiSTer uses a modified version of hid-playstation that exposes the microphone mute as a normal button. +#Adjust the button numbers to reflect this +030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,platform:MiSTer, +050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,platform:MiSTer, + +#Guncon 2 plug and play entries for various cores +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,b:b2,menuok:b2,menuesc:b0,start:b0,a:b1,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:PSX +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b2,menuesc:b0,rightshoulder:b2,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:NES +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,b:b2,menuok:b2,menuesc:b0,a:b0,x:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:SNES +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,b:b2,menuok:b2,menuesc:b0,a:b0,rightshoulder:b1,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:Genesis +030000009a0b00006a01000000010000,Namco GunCon 2,b:b2,menuok:b2,menuesc:b0,a:b0,rightshoulder:b1,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:MegaCD +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b2,menuesc:b0,b:b2,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:SMS +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b2,menuesc:b0,b:b2,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:ATARI7800 + +#MisterCade default mapping +03000000d0160000be10000001010000,Mister Addons MiSTer JAMMA Board,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b0,menuesc:b1,b:b3,a:b2,y:b0,x:b6,leftshoulder:b7,rightshoulder:b1,back:b8,start:b9,guide:b9,guide2:h0.4,platform:MiSTer + diff --git a/release-work/downloader-extract/files/linux/mt32-rom-data/README b/release-work/downloader-extract/files/linux/mt32-rom-data/README new file mode 100644 index 00000000..37932a2c --- /dev/null +++ b/release-work/downloader-extract/files/linux/mt32-rom-data/README @@ -0,0 +1 @@ +Put Roland MT-32 or CM-32 ROMS HERE \ No newline at end of file diff --git a/release-work/downloader-extract/files/linux/ppp_options b/release-work/downloader-extract/files/linux/ppp_options new file mode 100644 index 00000000..fdbb001d --- /dev/null +++ b/release-work/downloader-extract/files/linux/ppp_options @@ -0,0 +1,359 @@ +# /etc/ppp/options +# +# Originally created by Jim Knoble +# Modified for Debian by alvar Bray +# Modified for PPP Server setup by Christoph Lameter +# +# To quickly see what options are active in this file, use this command: +# egrep -v '#|^ *$' /etc/ppp/options + +# Specify which DNS Servers the incoming Win95 or WinNT Connection should use +# Two Servers can be remotely configured +#ms-dns 192.168.1.1 +#ms-dns 192.168.1.2 + +# Specify which WINS Servers the incoming connection Win95 or WinNT should use +# ms-wins 192.168.1.50 +# ms-wins 192.168.1.51 + +# Run the executable or shell command specified after pppd has +# terminated the link. This script could, for example, issue commands +# to the modem to cause it to hang up if hardware modem control signals +# were not available. +#disconnect "chat -- \d+++\d\c OK ath0 OK" + +# async character map -- 32-bit hex; each bit is a character +# that needs to be escaped for pppd to receive it. 0x00000001 +# represents '\x01', and 0x80000000 represents '\x1f'. +asyncmap 0 + +# Require the peer to authenticate itself before allowing network +# packets to be sent or received. +# Please do not disable this setting. It is expected to be standard in +# future releases of pppd. Use the call option (see manpage) to disable +# authentication for specific peers. +noauth + +# Specifies that certain characters should be escaped on transmission +# (regardless of whether the peer requests them to be escaped with its +# async control character map). The characters to be escaped are +# specified as a list of hex numbers separated by commas. Note that +# almost any character can be specified for the escape option, unlike +# the asyncmap option which only allows control characters to be +# specified. The characters which may not be escaped are those with hex +# values 0x20 - 0x3f or 0x5e. +#escape 11,13,ff + +# Don't use the modem control lines. +local + +# Specifies that pppd should use a UUCP-style lock on the serial device +# to ensure exclusive access to the device. +lock + +# Don't show the passwords when logging the contents of PAP packets. +# This is the default. +hide-password + +# When logging the contents of PAP packets, this option causes pppd to +# show the password string in the log message. +#show-password + +# Use the modem control lines. On Ultrix, this option implies hardware +# flow control, as for the crtscts option. (This option is not fully +# implemented.) +#modem + +# Set the MRU [Maximum Receive Unit] value to for negotiation. pppd +# will ask the peer to send packets of no more than bytes. The +# minimum MRU value is 128. The default MRU value is 1500. A value of +# 296 is recommended for slow links (40 bytes for TCP/IP header + 256 +# bytes of data). +mru 1500 + +# Set the interface netmask to , a 32 bit netmask in "decimal dot" +# notation (e.g. 255.255.255.0). +#netmask 255.255.255.0 + +# Disables the default behaviour when no local IP address is specified, +# which is to determine (if possible) the local IP address from the +# hostname. With this option, the peer will have to supply the local IP +# address during IPCP negotiation (unless it specified explicitly on the +# command line or in an options file). +#noipdefault + +# Enables the "passive" option in the LCP. With this option, pppd will +# attempt to initiate a connection; if no reply is received from the +# peer, pppd will then just wait passively for a valid LCP packet from +# the peer (instead of exiting, as it does without this option). +passive + +# With this option, pppd will not transmit LCP packets to initiate a +# connection until a valid LCP packet is received from the peer (as for +# the "passive" option with old versions of pppd). +silent + +# Don't request or allow negotiation of any options for LCP and IPCP +# (use default values). +#-all + +# Disable Address/Control compression negotiation (use default, i.e. +# address/control field disabled). +#-ac + +# Disable asyncmap negotiation (use the default asyncmap, i.e. escape +# all control characters). +#-am + +# Don't fork to become a background process (otherwise pppd will do so +# if a serial device is specified). +-detach + +# Disable IP address negotiation (with this option, the remote IP +# address must be specified with an option on the command line or in +# an options file). +#-ip + +# Disable IPCP negotiation and IP communication. This option should +# only be required if the peer is buggy and gets confused by requests +# from pppd for IPCP negotiation. +#noip + +# Disable magic number negotiation. With this option, pppd cannot +# detect a looped-back line. +#-mn + +# Disable MRU [Maximum Receive Unit] negotiation (use default, i.e. +# 1500). +#-mru + +# Disable protocol field compression negotiation (use default, i.e. +# protocol field compression disabled). +#-pc + +# Require the peer to authenticate itself using PAP. +#+pap + +# Don't agree to authenticate using PAP. +#-pap + +# Require the peer to authenticate itself using CHAP [Cryptographic +# Handshake Authentication Protocol] authentication. +#+chap + +# Don't agree to authenticate using CHAP. +#-chap + +# Disable negotiation of Van Jacobson style IP header compression (use +# default, i.e. no compression). +#-vj + +# Increase debugging level (same as -d). If this option is given, pppd +# will log the contents of all control packets sent or received in a +# readable form. The packets are logged through syslog with facility +# daemon and level debug. This information can be directed to a file by +# setting up /etc/syslog.conf appropriately (see syslog.conf(5)). (If +# pppd is compiled with extra debugging enabled, it will log messages +# using facility local2 instead of daemon). +debug + +# Append the domain name to the local host name for authentication +# purposes. For example, if gethostname() returns the name porsche, +# but the fully qualified domain name is porsche.Quotron.COM, you would +# use the domain option to set the domain name to Quotron.COM. +#domain + +# Enable debugging code in the kernel-level PPP driver. The argument n +# is a number which is the sum of the following values: 1 to enable +# general debug messages, 2 to request that the contents of received +# packets be printed, and 4 to request that the contents of transmitted +# packets be printed. +#kdebug n + +# Set the MTU [Maximum Transmit Unit] value to . Unless the peer +# requests a smaller value via MRU negotiation, pppd will request that +# the kernel networking code send data packets of no more than n bytes +# through the PPP network interface. +mtu 1500 + +# Set the name of the local system for authentication purposes to . +# This is a privileged option. With this option, pppd will use lines in the +# secrets files which have as the second field when looking for a +# secret to use in authenticating the peer. In addition, unless overridden +# with the user option, will be used as the name to send to the peer +# when authenticating the local system to the peer. (Note that pppd does +# not append the domain name to .) +#name + +# Enforce the use of the hostname as the name of the local system for +# authentication purposes (overrides the name option). +#usehostname + +# Set the assumed name of the remote system for authentication purposes +# to . +#remotename + +# Add an entry to this system's ARP [Address Resolution Protocol] +# table with the IP address of the peer and the Ethernet address of this +# system. +proxyarp + +# Use the system password database for authenticating the peer using +# PAP. Note: mgetty already provides this option. If this is specified +# then dialin from users using a script under Linux to fire up ppp wont work. +#login + +# If this option is given, pppd will send an LCP echo-request frame to the +# peer every n seconds. Normally the peer should respond to the echo-request +# by sending an echo-reply. This option can be used with the +# lcp-echo-failure option to detect that the peer is no longer connected. +lcp-echo-interval 30 + +# If this option is given, pppd will presume the peer to be dead if n +# LCP echo-requests are sent without receiving a valid LCP echo-reply. +# If this happens, pppd will terminate the connection. Use of this +# option requires a non-zero value for the lcp-echo-interval parameter. +# This option can be used to enable pppd to terminate after the physical +# connection has been broken (e.g., the modem has hung up) in +# situations where no hardware modem control lines are available. +lcp-echo-failure 4 + +# Set the LCP restart interval (retransmission timeout) to seconds +# (default 3). +#lcp-restart + +# Set the maximum number of LCP terminate-request transmissions to +# (default 3). +#lcp-max-terminate + +# Set the maximum number of LCP configure-request transmissions to +# (default 10). +#lcp-max-configure + +# Set the maximum number of LCP configure-NAKs returned before starting +# to send configure-Rejects instead to (default 10). +#lcp-max-failure + +# Set the IPCP restart interval (retransmission timeout) to +# seconds (default 3). +#ipcp-restart + +# Set the maximum number of IPCP terminate-request transmissions to +# (default 3). +#ipcp-max-terminate + +# Set the maximum number of IPCP configure-request transmissions to +# (default 10). +#ipcp-max-configure + +# Set the maximum number of IPCP configure-NAKs returned before starting +# to send configure-Rejects instead to (default 10). +#ipcp-max-failure + +# Set the PAP restart interval (retransmission timeout) to seconds +# (default 3). +#pap-restart + +# Set the maximum number of PAP authenticate-request transmissions to +# (default 10). +#pap-max-authreq + +# Set the maximum time that pppd will wait for the peer to authenticate +# itself with PAP to seconds (0 means no limit). +#pap-timeout + +# Set the CHAP restart interval (retransmission timeout for +# challenges) to seconds (default 3). +#chap-restart + +# Set the maximum number of CHAP challenge transmissions to +# (default 10). +#chap-max-challenge + +# If this option is given, pppd will rechallenge the peer every +# seconds. +#chap-interval + +# With this option, pppd will accept the peer's idea of our local IP +# address, even if the local IP address was specified in an option. +#ipcp-accept-local + +# With this option, pppd will accept the peer's idea of its (remote) IP +# address, even if the remote IP address was specified in an option. +#ipcp-accept-remote + +# Disable the IPXCP and IPX protocols. +# To let pppd pass IPX packets comment this out --- you'll probably also +# want to install ipxripd, and have the Internal IPX Network option enabled +# in your kernel. /usr/doc/HOWTO/IPX-HOWTO.gz contains more info. +noipx + +# Exit once a connection has been made and terminated. This is the default, +# unless the `persist' or `demand' option has been specified. +#nopersist + +# Do not exit after a connection is terminated; instead try to reopen +# the connection. +#persist + +# Terminate after n consecutive failed connection attempts. +# A value of 0 means no limit. The default value is 10. +#maxfail + +# Initiate the link only on demand, i.e. when data traffic is present. +# With this option, the remote IP address must be specified by the user on +# the command line or in an options file. Pppd will initially configure +# the interface and enable it for IP traffic without connecting to the peer. +# When traffic is available, pppd will connect to the peer and perform +# negotiation, authentication, etc. When this is completed, pppd will +# commence passing data packets (i.e., IP packets) across the link. +#demand + +# Specifies that pppd should disconnect if the link is idle for seconds. +# The link is idle when no data packets (i.e. IP packets) are being sent or +# received. Note: it is not advisable to use this option with the persist +# option without the demand option. If the active-filter option is given, +# data packets which are rejected by the specified activity filter also +# count as the link being idle. +#idle + +# Specifies how many seconds to wait before re-initiating the link after +# it terminates. This option only has any effect if the persist or demand +# option is used. The holdoff period is not applied if the link was +# terminated because it was idle. +#holdoff + +# Wait for up n milliseconds after the connect script finishes for a valid +# PPP packet from the peer. At the end of this time, or when a valid PPP +# packet is received from the peer, pppd will commence negotiation by +# sending its first LCP packet. The default value is 1000 (1 second). +# This wait period only applies if the connect or pty option is used. +#connect-delay + +# Packet filtering: for more information, see pppd(8) +# Any packets matching the filter expression will be interpreted as link +# activity, and will cause a "demand" connection to be activated, and reset +# the idle connection timer. (idle option) +# The filter expression is akin to that of tcpdump(1) +#active-filter + +# Serial device. Do not change! +/dev/ttyS1 + +############################################################################## + +# Speed of serial connection. Keep it commented out. It's controlled outside. +#115200 + +# Use hardware flow control (i.e. RTS/CTS) to control the flow of data +# on the serial port. +crtscts + +# Use software flow control (i.e. XON/XOFF) to control the flow of data +# on the serial port. +#xonxoff + +# You may explicitly define local and remote IPs for PPP link. +# new MiSTer releases don't require it anymore. +# IPs entered here will override automatically assigned IPs. +#192.168.1.1:192.168.1.10 diff --git a/release-work/downloader-extract/files/linux/soundfonts/README b/release-work/downloader-extract/files/linux/soundfonts/README new file mode 100644 index 00000000..cc22ff61 --- /dev/null +++ b/release-work/downloader-extract/files/linux/soundfonts/README @@ -0,0 +1 @@ +Put SF2 sounffonts here. diff --git a/release-work/downloader-extract/files/linux/u-boot.txt_example b/release-work/downloader-extract/files/linux/u-boot.txt_example new file mode 100644 index 00000000..edf5b139 --- /dev/null +++ b/release-work/downloader-extract/files/linux/u-boot.txt_example @@ -0,0 +1 @@ +v=loglevel=4 usbhid.jspoll=1 xpad.cpoll=1 diff --git a/release-work/downloader-extract/files/linux/updateboot b/release-work/downloader-extract/files/linux/updateboot new file mode 100644 index 00000000..18b7d3db --- /dev/null +++ b/release-work/downloader-extract/files/linux/updateboot @@ -0,0 +1,21 @@ +#!/bin/sh + +if [ -f /media/fat/linux/uboot.img ]; then + + echo "" + echo "Erasing u-boot saved environment" + dd if=/dev/zero of=/dev/mmcblk0 bs=512 seek=1 count=1 + echo "" + + if [ -b /dev/mmcblk0p3 ]; then + echo "Using old layout" + dd if=/media/fat/linux/uboot.img of=/dev/mmcblk0p3 + else + echo "Using new layout" + dd if=/media/fat/linux/uboot.img of=/dev/mmcblk0p2 + fi + + echo "" + echo "Done." + echo "" +fi diff --git a/release-work/downloader-extract/files/linux/zImage_dtb b/release-work/downloader-extract/files/linux/zImage_dtb new file mode 100644 index 00000000..e11984a5 Binary files /dev/null and b/release-work/downloader-extract/files/linux/zImage_dtb differ diff --git a/release-work/release-stage/files/linux/7za b/release-work/release-stage/files/linux/7za new file mode 100755 index 00000000..4dabc74f Binary files /dev/null and b/release-work/release-stage/files/linux/7za differ diff --git a/release-work/release-stage/files/linux/MidiLink.INI b/release-work/release-stage/files/linux/MidiLink.INI new file mode 100644 index 00000000..24c8a571 --- /dev/null +++ b/release-work/release-stage/files/linux/MidiLink.INI @@ -0,0 +1,64 @@ +#This is the MidiLink INI File! +#Edit with Notepad++ under Windows + +MIDILINK_PRIORITY = -20 +MUNT_OPTIONS = +MP3_VOLUME = -1 +MUNT_VOLUME = -1 +MODEM_VOLUME = -1 +FSYNTH_VOLUME = -1 +MIXER_CONTROL = Master +MUNT_ROM_PATH = /media/fat/linux/mt32-rom-data +FSYNTH_SOUNDFONT = /media/fat/linux/soundfonts/SC-55.sf2 +UDP_SERVER = 192.168.1.130 +UDP_SERVER_PORT = 1999 +UDP_SERVER_FILTER = FALSE +UDP_FLOW = 0 +TCP_SERVER_PORT = 23 +TCP_TERM_UPLOAD = /media/fat/UPLOAD +TCP_TERM_DOWNLOAD = /media/fat +TCP_TERM_MP3 = /media/fat/MP3 +TCP_TERM_MIDI = /media/fat/MIDI +TCP_TERM_SYNTH = FluidSynth +TCP_TERM_ROWS = 23 +TCP_FLOW = 3 +TCP_SOUND = TRUE +DELAYSYSEX = TRUE +#USB_SERIAL_MODULE = /media/fat/pl2303.ko + +[AO486] +MIDI_BAUD = 31250 +UDP_BAUD = 38400 +#TCP_SOUND_CONNECT = /media/fat/SOUNDS/connect_sav.wav + +[ATARIST] +TCP_BAUD = 19200 +UDP_BAUD = 31250 +UDP_BAUD_ALT = 19200 +TCP_BAUD_ALT = 19200 + +[C64] +TCP_TERM_TRANS = PETSKII +MIDI_BAUD = 2400 +TCP_BAUD = 2400 +TCP_TERM_ROWS = 24 +TCP_ATH_DELAY = 0 + +[FXCAST] +TCP_BAUD = 19200 +UDP_BAUD = 31250 + +[MINIMIG] +TCP_TERM_ROWS = 22 +USB_SERIAL_BAUD = 9600 + +[NES] +MIDI_BAUD = 31250 + +[GBMIDI] +MIDI_BAUD = 31250 +UDP_BAUD = 31250 + +[X68000] +MIDI_BAUD = 31250 +DELAYSYSEX = FALSE diff --git a/release-work/release-stage/files/linux/_samba.sh b/release-work/release-stage/files/linux/_samba.sh new file mode 100644 index 00000000..b1e64129 --- /dev/null +++ b/release-work/release-stage/files/linux/_samba.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +SAMBA_USER=root +SAMBA_PASS=1 + +#================================================================== +(echo $SAMBA_PASS; echo $SAMBA_PASS;) | smbpasswd -a -s $SAMBA_USER diff --git a/release-work/release-stage/files/linux/_user-startup.sh b/release-work/release-stage/files/linux/_user-startup.sh new file mode 100644 index 00000000..25b9f9a0 --- /dev/null +++ b/release-work/release-stage/files/linux/_user-startup.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "***" $1 "***" diff --git a/release-work/release-stage/files/linux/_wpa_supplicant.conf b/release-work/release-stage/files/linux/_wpa_supplicant.conf new file mode 100644 index 00000000..9098ed29 --- /dev/null +++ b/release-work/release-stage/files/linux/_wpa_supplicant.conf @@ -0,0 +1,8 @@ +ctrl_interface=/run/wpa_supplicant +update_config=1 +country=TW + +network={ + ssid="put_your_SSID_here" + psk="put_your_password_here" +} diff --git a/release-work/release-stage/files/linux/gamecontrollerdb/gamecontrollerdb.txt b/release-work/release-stage/files/linux/gamecontrollerdb/gamecontrollerdb.txt new file mode 100644 index 00000000..51cbeb12 --- /dev/null +++ b/release-work/release-stage/files/linux/gamecontrollerdb/gamecontrollerdb.txt @@ -0,0 +1,582 @@ +# Original source: +# Game Controller DB for SDL in 2.0.16 format +# Source: https://github.com/gabomdq/SDL_GameControllerDB + +# Modified to remove non-Linux platforms and add MiSTer specific entries +030000005e0400008e02000020010000,8BitDo Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, +03000000021000000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000151000000010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000650000011010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, +03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, +03000000022000000090000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000631000014010000,8BitDo Pro 2 Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00001030000011010000,8BitDo Pro 2 Wired Controller,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000020000000000000,8BitDo Pro 2 Wired Controller for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +06000000c82d00000020000006010000,8BitDo Pro 2 Wired Controller for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00000131000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000231000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000331000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000431000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Linux, +05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +030000003512000012ab000010010000,8BitDo SFC30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux, +030000003512000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000102800000900000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00003028000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000351000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000260000011010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001130000011010000,8BitDo Ultimate Wired,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000760000011010000,8BitDo Ultimate Wireless,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001230000011010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00001330000011010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000121000011010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00000121000000010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, +05000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +050000005e040000e002000030110000,8BitDo Zero 2,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, +05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c01100000355000011010000,Acrux Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00003901000000430000,Afterglow Prismatic Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003901000013020000,Afterglow Prismatic Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001302000000010000,Afterglow Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003901000020060000,Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000100000008200000011010000,Akishop Customs PS360,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000007c1800000006000010010000,Alienware Dual Compatible Game PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +05000000491900000204000021000000,Amazon Fire Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux, +05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, +05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, +03000000050b00000579000011010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b36,paddle1:b52,paddle2:b53,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b21,paddle1:b22,paddle2:b23,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +03000000503200000110000011010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +05000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +05000000503200000110000044010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +05000000503200000110000046010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +03000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux, +03000000503200000210000011010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000045010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000046010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:-a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux, +03000000c62400001b89000011010000,BDA MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000c21100000791000011010000,Be1 GC101 Controller 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000c31100000791000011010000,Be1 GC101 Controller 1.03,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000005e0400008e02000003030000,Be1 GC101 Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000bc2000004d50000011010000,BEITONG A1T2 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000bc2000000055000001000000,BETOP AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006b1400000209000011010000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000200e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000210e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux, +03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux, +03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000242f00009100000000010000,EasySMX ESM-9101,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, +030000006e0500000720000010010000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux, +030000007d0400000640000010010000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Linux, +03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000007e0500003703000000000000,GameCube Adapter,a:b0,b:b1,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +19000000030000000300000002030000,GameForce Controller,a:b1,b:b0,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000ac0500005b05000010010000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ac0500001a06000011010000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +190000004b4800000010000000010000,GO-Advance Controller,a:b1,b:b0,back:b10,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,leftshoulder:b4,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b13,start:b15,x:b2,y:b3,platform:Linux, +190000004b4800000010000001010000,GO-Advance Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b13,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b16,righttrigger:b15,start:b17,x:b2,y:b3,platform:Linux, +190000004b4800000011000000010000,GO-Super Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b2,y:b3,platform:Linux, +03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000007d0400000540000000010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux, +030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +06000000adde0000efbe000002010000,Hidromancer Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, +03000000c9110000f055000011010000,HJC Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000632500002605000010010000,HJDX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux, +030000000d0f00006d00000020010000,Hori EDGE 301,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:+a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00008400000011010000,Hori Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005f00000011010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005e00000011010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005001000009040000,Hori Fighting Commander OCTA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00008500000010010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00008600000002010000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00003701000013010000,Hori Fighting Stick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b3,y:b2,platform:Linux, +030000000d0f00008800000011010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00008700000011010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,rightstick:b11,righttrigger:a4,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00001000000011010000,Hori Fightstick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000003f5000033050000,Hori Fightstick VX,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b8,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00004d00000011010000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux, +030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f0000aa00000011010000,Hori Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000000d0f00001100000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00002200000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00001600000000010000,Hori Real Arcade Pro EXSE,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00008501000015010000,Hori Switch Split Pad Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00006e00000011010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006600000011010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f0000ee00000011010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006700000001010000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +050000000d0f0000f600000001000000,Horipad Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +05000000242e00000b20000001000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Linux, +03000000242e0000ff0b000011010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Linux, +03000000242e00006a38000010010000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,start:b5,leftshoulder:b2,rightshoulder:b3,leftx:a0,lefty:a1,platform:Linux, +03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000f00300008d03000011010000,HyperX Clutch,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, +050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux, +03000000120c00000500000010010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, +03000000ef0500000300000000010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, +03000000fd0500000030000000010000,InterAct GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Linux, +03000000fd0500002a26000000010000,InterAct HammerHead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, +0500000049190000020400001b010000,Ipega PG 9069,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000632500007505000011010000,Ipega PG 9099,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +0500000049190000030400001b010000,Ipega PG9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000491900000204000000000000,Ipega PG9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000300f00001001000010010000,Jess Tech Dual Analog Rumble,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000ba2200002010000001010000,Jess Technology Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux, +050000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux, +030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, +03000000bd12000003c0000010010000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000242f00002d00000011010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000242f00008a00000011010000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, +030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d040000d1ca000000000000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001dc2000014400000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001ec2000019200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001ec2000020200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000019c2000011010000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001fc2000005030000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, +030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux, +05000000380700006652000025010000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008532000010010000,Mad Catz Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000380700005032000011010000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700005082000011010000,Mad Catz Fightpad Pro PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, +03000000380700008034000011010000,Mad Catz Fightstick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008084000011010000,Mad Catz Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008433000011010000,Mad Catz Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008483000011010000,Mad Catz Fightstick TE S PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700001888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700003888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700001647000010040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000380700003847000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +030000008f0e00001330000010010000,Mayflash Controller Adapter,a:b1,b:b2,back:b8,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3~,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +03000000790000004318000010010000,Mayflash GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, +0300000079000000d218000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000242f0000f700000001010000,Mayflash Magic S Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000008f0e00001030000010010000,Mayflash Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux, +0300000025090000e803000001010000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +03000000790000000318000011010000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux, +03000000790000000018000011010000,Mayflash Wii U Pro Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000b50700001203000010010000,Mega World Logic 3 Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000780000000600000010010000,Microntek Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +030000005e0400002800000000010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Linux, +030000005e0400000300000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux, +030000005e0400000700000000010000,Microsoft SideWinder,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux, +030000005e0400000e00000000010000,Microsoft SideWinder Freestyle Pro,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, +030000005e0400002700000000010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Linux, +030000005e0400008502000000010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e0400008902000021010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e0400008e02000001000000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.1,dpleft:h0.2,dpright:h0.8,dpup:h0.4,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000004010000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000056210000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000062230000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000001010000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000dd02000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000008040000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000e302000003020000,Microsoft Xbox One Elite,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000005e040000120b00000b050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, +050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +05000000e80400006e0400001b010000,Mocute 053X M59,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000004d4f435554452d3035305800,Mocute 054X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000d6200000e589000001000000,Moga 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +05000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +03000000c62400002b89000011010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c62400001a89000000010000,MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux, +03000000790000004518000010010000,Nexilux GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux, +060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +030000009b2800008000000020020000,Nintendo Classic Controller,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux, +030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux, +03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux, +060000004e696e74656e646f20537700,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +060000007e0500000620000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b16,b:b15,back:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,platform:Linux, +03000000d620000013a7000011010000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000007e0500000920000000026803,Nintendo Switch Pro Controller,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Linux, +030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux, +05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux, +050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux, +050000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux, +05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux, +03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux, +19000000010000000200000011000000,ODROID Go 2,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux, +03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:Linux, +05000000362800000100000002010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +05000000362800000100000003010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +05000000362800000100000004010000,OUYA Controller,a:b0,b:b3,back:b14,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b16,x:b1,y:b2,platform:Linux, +03000000830500005020000010010000,Padix Rockfire PlayStation Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux, +03000000ff1100003133000010010000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e0000b802000001010000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000b802000013020000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00008001000011010000,PDP Faceoff Nintendo Switch Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00008501000011010000,PDP Nintendo Switch Fightpad Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00002801000011010000,PDP PS3 Rock Candy Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00000901000011010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000004f9000000010000,PDP Xbox 360 Versus Fighting,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000a802000023020000,PDP Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000d802000006640000,PDP Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000666600006706000000010000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, +030000004c050000da0c000011010000,PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000d9040000160f000000010000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c62400001a53000000010000,PowerA Mini Pro Ex,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000c62400001a58000001010000,PowerA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000220000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, +03000000d62000000228000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000f20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000005f1400003102000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00001402000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000008f0e00000300000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +050000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +050000004c0500006802000000800000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +05000000504c415953544154494f4e00,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +060000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +03000000c01100000140000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000c405000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000f20d000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000f20d000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +03000000300f00001211000011010000,Qanba Arcade Joystick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux, +03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000222c00000020000011010000,Qanba Drone Arcade PS4 Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux, +03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000009b2800000300000001010000,Raphnet 4nes4snes,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, +030000009b2800004200000001010000,Raphnet Dual NES Adapter,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux, +030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, +030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, +030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000321500000204000011010000,Razer Panthera PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000104000011010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000810000011010000,Razer Panthera PS4 Evo Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000010000011010000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000321500000a10000001000000,Razer Raiju Tournament Edition,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000011000011010000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000008916000000fe000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c6240000045d000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux, +190000004b4800000111000000010000,RetroGame Joypad,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux, +0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +00000000526574726f53746f6e653200,RetroStone 2 Controller,a:b1,b:b0,back:b10,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Linux, +03000000341200000400000000010000,RetroUSB N64 RetroPort,+rightx:b8,+righty:b10,-rightx:b9,-righty:b11,a:b7,b:b6,dpdown:b2,dpleft:b1,dpright:b0,dpup:b3,leftshoulder:b13,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b12,start:b4,platform:Linux, +030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00001f01000000010000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00008701000011010000,Rock Candy Switch Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000c6240000fefa000000010000,Rock Candy Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000a306000023f6000011010000,Saitek Cyborg V1 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux, +03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux, +03000000a30600000cff000010010000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux, +03000000a30600000c04000011010000,Saitek P2900,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, +03000000a306000018f5000010010000,Saitek P3200 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, +03000000a30600000b04000000010000,Saitek P990 Dual Analog,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux, +03000000a306000020f6000011010000,Saitek PS2700 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +05000000e804000000a000001b010000,Samsung EIGP20,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux, +03000000a30c00002500000011010000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux, +03000000790000001100000011010000,Sega Saturn,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux, +03000000790000002201000011010000,Sega Saturn,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, +03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux, +030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000632500007505000010010000,Shanwan PS3 PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000bc2000000055000010010000,Shanwan PS3 PC ,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, +03000000250900000500000000010000,Sony PS2 pad with SmartJoy Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000005e0400008e02000073050000,Speedlink Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000020200000,SpeedLink Xeox Pro Analog,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000512000010010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,platform:Linux, +03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b10,guide:b11,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Linux, +03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000ad1b000038f0000090040000,Street Fighter IV Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000003b07000004a1000000010000,Suncom SFX Plus,a:b0,b:b2,back:b7,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux, +03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +030000008f0e00000d31000010010000,SZMY Power 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000457500000401000011010000,SZMY Power DS4 Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000457500002211000010010000,SZMY Power Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000008f0e00001431000010010000,SZMY Power PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux, +03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000020b3000010010000,Thrustmaster Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000023b3000000010000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f0400000ed0000011010000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux, +030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux, +030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, +030000004f04000004b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000026b3000002040000,Thrustmaster GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c6240000025b000002020000,Thrustmaster GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000004f04000008d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000009d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000007d0000000010000,Thrustmaster T Mini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000012b3000010010000,Thrustmaster Vibrating Gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +03000000571d00002000000010010000,Tomee SNES Adapter,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, +03000000bd12000015d0000010010000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000d814000007cd000011010000,Toodles 2008 Chimp PC PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux, +030000005e0400008e02000070050000,Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c01100000591000011010000,Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000680a00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +03000000780300000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +03000000e00d00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +03000000f00600000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000151900005678000010010000,Uniplay U6,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, +03000000790000001100000000010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux, +030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00000702000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +05000000ac0500003232000001000000,VR Box Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +05000000434f4d4d414e440000000000,VX Gaming Command Series,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +0000000058626f782033363020576900,Xbox 360 Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, +030000005e0400001907000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000014010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400009102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000000010000,Xbox 360 EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000006f0e00001304000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +0000000058626f782047616d65706100,Xbox Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000001030000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000009050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000007050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000009050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000011050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000015050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +060000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux, +03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux, +xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000120c0000100e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000101e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +# MiSTer specific default controller mappings + +#MiSTer uses a modified version of hid-playstation that exposes the microphone mute as a normal button. +#Adjust the button numbers to reflect this +030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,platform:MiSTer, +050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,platform:MiSTer, + +#Guncon 2 plug and play entries for various cores +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,b:b2,menuok:b2,menuesc:b0,start:b0,a:b1,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:PSX +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b2,menuesc:b0,rightshoulder:b2,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:NES +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,b:b2,menuok:b2,menuesc:b0,a:b0,x:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:SNES +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,b:b2,menuok:b2,menuesc:b0,a:b0,rightshoulder:b1,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:Genesis +030000009a0b00006a01000000010000,Namco GunCon 2,b:b2,menuok:b2,menuesc:b0,a:b0,rightshoulder:b1,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:MegaCD +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b2,menuesc:b0,b:b2,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:SMS +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b2,menuesc:b0,b:b2,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:ATARI7800 + +#MisterCade default mapping +03000000d0160000be10000001010000,Mister Addons MiSTer JAMMA Board,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b0,menuesc:b1,b:b3,a:b2,y:b0,x:b6,leftshoulder:b7,rightshoulder:b1,back:b8,start:b9,guide:b9,guide2:h0.4,platform:MiSTer + diff --git a/release-work/release-stage/files/linux/mt32-rom-data/README b/release-work/release-stage/files/linux/mt32-rom-data/README new file mode 100644 index 00000000..37932a2c --- /dev/null +++ b/release-work/release-stage/files/linux/mt32-rom-data/README @@ -0,0 +1 @@ +Put Roland MT-32 or CM-32 ROMS HERE \ No newline at end of file diff --git a/release-work/release-stage/files/linux/ppp_options b/release-work/release-stage/files/linux/ppp_options new file mode 100644 index 00000000..fdbb001d --- /dev/null +++ b/release-work/release-stage/files/linux/ppp_options @@ -0,0 +1,359 @@ +# /etc/ppp/options +# +# Originally created by Jim Knoble +# Modified for Debian by alvar Bray +# Modified for PPP Server setup by Christoph Lameter +# +# To quickly see what options are active in this file, use this command: +# egrep -v '#|^ *$' /etc/ppp/options + +# Specify which DNS Servers the incoming Win95 or WinNT Connection should use +# Two Servers can be remotely configured +#ms-dns 192.168.1.1 +#ms-dns 192.168.1.2 + +# Specify which WINS Servers the incoming connection Win95 or WinNT should use +# ms-wins 192.168.1.50 +# ms-wins 192.168.1.51 + +# Run the executable or shell command specified after pppd has +# terminated the link. This script could, for example, issue commands +# to the modem to cause it to hang up if hardware modem control signals +# were not available. +#disconnect "chat -- \d+++\d\c OK ath0 OK" + +# async character map -- 32-bit hex; each bit is a character +# that needs to be escaped for pppd to receive it. 0x00000001 +# represents '\x01', and 0x80000000 represents '\x1f'. +asyncmap 0 + +# Require the peer to authenticate itself before allowing network +# packets to be sent or received. +# Please do not disable this setting. It is expected to be standard in +# future releases of pppd. Use the call option (see manpage) to disable +# authentication for specific peers. +noauth + +# Specifies that certain characters should be escaped on transmission +# (regardless of whether the peer requests them to be escaped with its +# async control character map). The characters to be escaped are +# specified as a list of hex numbers separated by commas. Note that +# almost any character can be specified for the escape option, unlike +# the asyncmap option which only allows control characters to be +# specified. The characters which may not be escaped are those with hex +# values 0x20 - 0x3f or 0x5e. +#escape 11,13,ff + +# Don't use the modem control lines. +local + +# Specifies that pppd should use a UUCP-style lock on the serial device +# to ensure exclusive access to the device. +lock + +# Don't show the passwords when logging the contents of PAP packets. +# This is the default. +hide-password + +# When logging the contents of PAP packets, this option causes pppd to +# show the password string in the log message. +#show-password + +# Use the modem control lines. On Ultrix, this option implies hardware +# flow control, as for the crtscts option. (This option is not fully +# implemented.) +#modem + +# Set the MRU [Maximum Receive Unit] value to for negotiation. pppd +# will ask the peer to send packets of no more than bytes. The +# minimum MRU value is 128. The default MRU value is 1500. A value of +# 296 is recommended for slow links (40 bytes for TCP/IP header + 256 +# bytes of data). +mru 1500 + +# Set the interface netmask to , a 32 bit netmask in "decimal dot" +# notation (e.g. 255.255.255.0). +#netmask 255.255.255.0 + +# Disables the default behaviour when no local IP address is specified, +# which is to determine (if possible) the local IP address from the +# hostname. With this option, the peer will have to supply the local IP +# address during IPCP negotiation (unless it specified explicitly on the +# command line or in an options file). +#noipdefault + +# Enables the "passive" option in the LCP. With this option, pppd will +# attempt to initiate a connection; if no reply is received from the +# peer, pppd will then just wait passively for a valid LCP packet from +# the peer (instead of exiting, as it does without this option). +passive + +# With this option, pppd will not transmit LCP packets to initiate a +# connection until a valid LCP packet is received from the peer (as for +# the "passive" option with old versions of pppd). +silent + +# Don't request or allow negotiation of any options for LCP and IPCP +# (use default values). +#-all + +# Disable Address/Control compression negotiation (use default, i.e. +# address/control field disabled). +#-ac + +# Disable asyncmap negotiation (use the default asyncmap, i.e. escape +# all control characters). +#-am + +# Don't fork to become a background process (otherwise pppd will do so +# if a serial device is specified). +-detach + +# Disable IP address negotiation (with this option, the remote IP +# address must be specified with an option on the command line or in +# an options file). +#-ip + +# Disable IPCP negotiation and IP communication. This option should +# only be required if the peer is buggy and gets confused by requests +# from pppd for IPCP negotiation. +#noip + +# Disable magic number negotiation. With this option, pppd cannot +# detect a looped-back line. +#-mn + +# Disable MRU [Maximum Receive Unit] negotiation (use default, i.e. +# 1500). +#-mru + +# Disable protocol field compression negotiation (use default, i.e. +# protocol field compression disabled). +#-pc + +# Require the peer to authenticate itself using PAP. +#+pap + +# Don't agree to authenticate using PAP. +#-pap + +# Require the peer to authenticate itself using CHAP [Cryptographic +# Handshake Authentication Protocol] authentication. +#+chap + +# Don't agree to authenticate using CHAP. +#-chap + +# Disable negotiation of Van Jacobson style IP header compression (use +# default, i.e. no compression). +#-vj + +# Increase debugging level (same as -d). If this option is given, pppd +# will log the contents of all control packets sent or received in a +# readable form. The packets are logged through syslog with facility +# daemon and level debug. This information can be directed to a file by +# setting up /etc/syslog.conf appropriately (see syslog.conf(5)). (If +# pppd is compiled with extra debugging enabled, it will log messages +# using facility local2 instead of daemon). +debug + +# Append the domain name to the local host name for authentication +# purposes. For example, if gethostname() returns the name porsche, +# but the fully qualified domain name is porsche.Quotron.COM, you would +# use the domain option to set the domain name to Quotron.COM. +#domain + +# Enable debugging code in the kernel-level PPP driver. The argument n +# is a number which is the sum of the following values: 1 to enable +# general debug messages, 2 to request that the contents of received +# packets be printed, and 4 to request that the contents of transmitted +# packets be printed. +#kdebug n + +# Set the MTU [Maximum Transmit Unit] value to . Unless the peer +# requests a smaller value via MRU negotiation, pppd will request that +# the kernel networking code send data packets of no more than n bytes +# through the PPP network interface. +mtu 1500 + +# Set the name of the local system for authentication purposes to . +# This is a privileged option. With this option, pppd will use lines in the +# secrets files which have as the second field when looking for a +# secret to use in authenticating the peer. In addition, unless overridden +# with the user option, will be used as the name to send to the peer +# when authenticating the local system to the peer. (Note that pppd does +# not append the domain name to .) +#name + +# Enforce the use of the hostname as the name of the local system for +# authentication purposes (overrides the name option). +#usehostname + +# Set the assumed name of the remote system for authentication purposes +# to . +#remotename + +# Add an entry to this system's ARP [Address Resolution Protocol] +# table with the IP address of the peer and the Ethernet address of this +# system. +proxyarp + +# Use the system password database for authenticating the peer using +# PAP. Note: mgetty already provides this option. If this is specified +# then dialin from users using a script under Linux to fire up ppp wont work. +#login + +# If this option is given, pppd will send an LCP echo-request frame to the +# peer every n seconds. Normally the peer should respond to the echo-request +# by sending an echo-reply. This option can be used with the +# lcp-echo-failure option to detect that the peer is no longer connected. +lcp-echo-interval 30 + +# If this option is given, pppd will presume the peer to be dead if n +# LCP echo-requests are sent without receiving a valid LCP echo-reply. +# If this happens, pppd will terminate the connection. Use of this +# option requires a non-zero value for the lcp-echo-interval parameter. +# This option can be used to enable pppd to terminate after the physical +# connection has been broken (e.g., the modem has hung up) in +# situations where no hardware modem control lines are available. +lcp-echo-failure 4 + +# Set the LCP restart interval (retransmission timeout) to seconds +# (default 3). +#lcp-restart + +# Set the maximum number of LCP terminate-request transmissions to +# (default 3). +#lcp-max-terminate + +# Set the maximum number of LCP configure-request transmissions to +# (default 10). +#lcp-max-configure + +# Set the maximum number of LCP configure-NAKs returned before starting +# to send configure-Rejects instead to (default 10). +#lcp-max-failure + +# Set the IPCP restart interval (retransmission timeout) to +# seconds (default 3). +#ipcp-restart + +# Set the maximum number of IPCP terminate-request transmissions to +# (default 3). +#ipcp-max-terminate + +# Set the maximum number of IPCP configure-request transmissions to +# (default 10). +#ipcp-max-configure + +# Set the maximum number of IPCP configure-NAKs returned before starting +# to send configure-Rejects instead to (default 10). +#ipcp-max-failure + +# Set the PAP restart interval (retransmission timeout) to seconds +# (default 3). +#pap-restart + +# Set the maximum number of PAP authenticate-request transmissions to +# (default 10). +#pap-max-authreq + +# Set the maximum time that pppd will wait for the peer to authenticate +# itself with PAP to seconds (0 means no limit). +#pap-timeout + +# Set the CHAP restart interval (retransmission timeout for +# challenges) to seconds (default 3). +#chap-restart + +# Set the maximum number of CHAP challenge transmissions to +# (default 10). +#chap-max-challenge + +# If this option is given, pppd will rechallenge the peer every +# seconds. +#chap-interval + +# With this option, pppd will accept the peer's idea of our local IP +# address, even if the local IP address was specified in an option. +#ipcp-accept-local + +# With this option, pppd will accept the peer's idea of its (remote) IP +# address, even if the remote IP address was specified in an option. +#ipcp-accept-remote + +# Disable the IPXCP and IPX protocols. +# To let pppd pass IPX packets comment this out --- you'll probably also +# want to install ipxripd, and have the Internal IPX Network option enabled +# in your kernel. /usr/doc/HOWTO/IPX-HOWTO.gz contains more info. +noipx + +# Exit once a connection has been made and terminated. This is the default, +# unless the `persist' or `demand' option has been specified. +#nopersist + +# Do not exit after a connection is terminated; instead try to reopen +# the connection. +#persist + +# Terminate after n consecutive failed connection attempts. +# A value of 0 means no limit. The default value is 10. +#maxfail + +# Initiate the link only on demand, i.e. when data traffic is present. +# With this option, the remote IP address must be specified by the user on +# the command line or in an options file. Pppd will initially configure +# the interface and enable it for IP traffic without connecting to the peer. +# When traffic is available, pppd will connect to the peer and perform +# negotiation, authentication, etc. When this is completed, pppd will +# commence passing data packets (i.e., IP packets) across the link. +#demand + +# Specifies that pppd should disconnect if the link is idle for seconds. +# The link is idle when no data packets (i.e. IP packets) are being sent or +# received. Note: it is not advisable to use this option with the persist +# option without the demand option. If the active-filter option is given, +# data packets which are rejected by the specified activity filter also +# count as the link being idle. +#idle + +# Specifies how many seconds to wait before re-initiating the link after +# it terminates. This option only has any effect if the persist or demand +# option is used. The holdoff period is not applied if the link was +# terminated because it was idle. +#holdoff + +# Wait for up n milliseconds after the connect script finishes for a valid +# PPP packet from the peer. At the end of this time, or when a valid PPP +# packet is received from the peer, pppd will commence negotiation by +# sending its first LCP packet. The default value is 1000 (1 second). +# This wait period only applies if the connect or pty option is used. +#connect-delay + +# Packet filtering: for more information, see pppd(8) +# Any packets matching the filter expression will be interpreted as link +# activity, and will cause a "demand" connection to be activated, and reset +# the idle connection timer. (idle option) +# The filter expression is akin to that of tcpdump(1) +#active-filter + +# Serial device. Do not change! +/dev/ttyS1 + +############################################################################## + +# Speed of serial connection. Keep it commented out. It's controlled outside. +#115200 + +# Use hardware flow control (i.e. RTS/CTS) to control the flow of data +# on the serial port. +crtscts + +# Use software flow control (i.e. XON/XOFF) to control the flow of data +# on the serial port. +#xonxoff + +# You may explicitly define local and remote IPs for PPP link. +# new MiSTer releases don't require it anymore. +# IPs entered here will override automatically assigned IPs. +#192.168.1.1:192.168.1.10 diff --git a/release-work/release-stage/files/linux/soundfonts/README b/release-work/release-stage/files/linux/soundfonts/README new file mode 100644 index 00000000..cc22ff61 --- /dev/null +++ b/release-work/release-stage/files/linux/soundfonts/README @@ -0,0 +1 @@ +Put SF2 sounffonts here. diff --git a/release-work/release-stage/files/linux/u-boot.txt_example b/release-work/release-stage/files/linux/u-boot.txt_example new file mode 100644 index 00000000..edf5b139 --- /dev/null +++ b/release-work/release-stage/files/linux/u-boot.txt_example @@ -0,0 +1 @@ +v=loglevel=4 usbhid.jspoll=1 xpad.cpoll=1 diff --git a/release-work/release-stage/files/linux/updateboot b/release-work/release-stage/files/linux/updateboot new file mode 100644 index 00000000..18b7d3db --- /dev/null +++ b/release-work/release-stage/files/linux/updateboot @@ -0,0 +1,21 @@ +#!/bin/sh + +if [ -f /media/fat/linux/uboot.img ]; then + + echo "" + echo "Erasing u-boot saved environment" + dd if=/dev/zero of=/dev/mmcblk0 bs=512 seek=1 count=1 + echo "" + + if [ -b /dev/mmcblk0p3 ]; then + echo "Using old layout" + dd if=/media/fat/linux/uboot.img of=/dev/mmcblk0p3 + else + echo "Using new layout" + dd if=/media/fat/linux/uboot.img of=/dev/mmcblk0p2 + fi + + echo "" + echo "Done." + echo "" +fi diff --git a/release-work/release-stage/files/linux/zImage_dtb b/release-work/release-stage/files/linux/zImage_dtb new file mode 100644 index 00000000..e11984a5 Binary files /dev/null and b/release-work/release-stage/files/linux/zImage_dtb differ diff --git a/release-work/stock-extract/files/linux/MidiLink.INI b/release-work/stock-extract/files/linux/MidiLink.INI new file mode 100644 index 00000000..24c8a571 --- /dev/null +++ b/release-work/stock-extract/files/linux/MidiLink.INI @@ -0,0 +1,64 @@ +#This is the MidiLink INI File! +#Edit with Notepad++ under Windows + +MIDILINK_PRIORITY = -20 +MUNT_OPTIONS = +MP3_VOLUME = -1 +MUNT_VOLUME = -1 +MODEM_VOLUME = -1 +FSYNTH_VOLUME = -1 +MIXER_CONTROL = Master +MUNT_ROM_PATH = /media/fat/linux/mt32-rom-data +FSYNTH_SOUNDFONT = /media/fat/linux/soundfonts/SC-55.sf2 +UDP_SERVER = 192.168.1.130 +UDP_SERVER_PORT = 1999 +UDP_SERVER_FILTER = FALSE +UDP_FLOW = 0 +TCP_SERVER_PORT = 23 +TCP_TERM_UPLOAD = /media/fat/UPLOAD +TCP_TERM_DOWNLOAD = /media/fat +TCP_TERM_MP3 = /media/fat/MP3 +TCP_TERM_MIDI = /media/fat/MIDI +TCP_TERM_SYNTH = FluidSynth +TCP_TERM_ROWS = 23 +TCP_FLOW = 3 +TCP_SOUND = TRUE +DELAYSYSEX = TRUE +#USB_SERIAL_MODULE = /media/fat/pl2303.ko + +[AO486] +MIDI_BAUD = 31250 +UDP_BAUD = 38400 +#TCP_SOUND_CONNECT = /media/fat/SOUNDS/connect_sav.wav + +[ATARIST] +TCP_BAUD = 19200 +UDP_BAUD = 31250 +UDP_BAUD_ALT = 19200 +TCP_BAUD_ALT = 19200 + +[C64] +TCP_TERM_TRANS = PETSKII +MIDI_BAUD = 2400 +TCP_BAUD = 2400 +TCP_TERM_ROWS = 24 +TCP_ATH_DELAY = 0 + +[FXCAST] +TCP_BAUD = 19200 +UDP_BAUD = 31250 + +[MINIMIG] +TCP_TERM_ROWS = 22 +USB_SERIAL_BAUD = 9600 + +[NES] +MIDI_BAUD = 31250 + +[GBMIDI] +MIDI_BAUD = 31250 +UDP_BAUD = 31250 + +[X68000] +MIDI_BAUD = 31250 +DELAYSYSEX = FALSE diff --git a/release-work/stock-extract/files/linux/_samba.sh b/release-work/stock-extract/files/linux/_samba.sh new file mode 100644 index 00000000..b1e64129 --- /dev/null +++ b/release-work/stock-extract/files/linux/_samba.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +SAMBA_USER=root +SAMBA_PASS=1 + +#================================================================== +(echo $SAMBA_PASS; echo $SAMBA_PASS;) | smbpasswd -a -s $SAMBA_USER diff --git a/release-work/stock-extract/files/linux/_user-startup.sh b/release-work/stock-extract/files/linux/_user-startup.sh new file mode 100644 index 00000000..25b9f9a0 --- /dev/null +++ b/release-work/stock-extract/files/linux/_user-startup.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "***" $1 "***" diff --git a/release-work/stock-extract/files/linux/_wpa_supplicant.conf b/release-work/stock-extract/files/linux/_wpa_supplicant.conf new file mode 100644 index 00000000..9098ed29 --- /dev/null +++ b/release-work/stock-extract/files/linux/_wpa_supplicant.conf @@ -0,0 +1,8 @@ +ctrl_interface=/run/wpa_supplicant +update_config=1 +country=TW + +network={ + ssid="put_your_SSID_here" + psk="put_your_password_here" +} diff --git a/release-work/stock-extract/files/linux/gamecontrollerdb/gamecontrollerdb.txt b/release-work/stock-extract/files/linux/gamecontrollerdb/gamecontrollerdb.txt new file mode 100644 index 00000000..51cbeb12 --- /dev/null +++ b/release-work/stock-extract/files/linux/gamecontrollerdb/gamecontrollerdb.txt @@ -0,0 +1,582 @@ +# Original source: +# Game Controller DB for SDL in 2.0.16 format +# Source: https://github.com/gabomdq/SDL_GameControllerDB + +# Modified to remove non-Linux platforms and add MiSTer specific entries +030000005e0400008e02000020010000,8BitDo Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, +03000000021000000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000151000000010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000650000011010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, +03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, +03000000022000000090000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000631000014010000,8BitDo Pro 2 Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00001030000011010000,8BitDo Pro 2 Wired Controller,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000020000000000000,8BitDo Pro 2 Wired Controller for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +06000000c82d00000020000006010000,8BitDo Pro 2 Wired Controller for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00000131000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000231000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000331000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000431000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Linux, +05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +030000003512000012ab000010010000,8BitDo SFC30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux, +030000003512000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000102800000900000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00003028000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000351000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000260000011010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001130000011010000,8BitDo Ultimate Wired,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000760000011010000,8BitDo Ultimate Wireless,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00001230000011010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00001330000011010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000121000011010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00000121000000010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, +05000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +050000005e040000e002000030110000,8BitDo Zero 2,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, +05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c01100000355000011010000,Acrux Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00003901000000430000,Afterglow Prismatic Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003901000013020000,Afterglow Prismatic Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001302000000010000,Afterglow Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003901000020060000,Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000100000008200000011010000,Akishop Customs PS360,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000007c1800000006000010010000,Alienware Dual Compatible Game PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +05000000491900000204000021000000,Amazon Fire Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux, +05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, +05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, +03000000050b00000579000011010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b36,paddle1:b52,paddle2:b53,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b21,paddle1:b22,paddle2:b23,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +03000000503200000110000011010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +05000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +05000000503200000110000044010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +05000000503200000110000046010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, +03000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux, +03000000503200000210000011010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000045010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000046010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +05000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:-a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux, +03000000c62400001b89000011010000,BDA MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000c21100000791000011010000,Be1 GC101 Controller 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000c31100000791000011010000,Be1 GC101 Controller 1.03,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000005e0400008e02000003030000,Be1 GC101 Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000bc2000004d50000011010000,BEITONG A1T2 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000bc2000000055000001000000,BETOP AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006b1400000209000011010000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000200e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000210e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux, +03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux, +03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000242f00009100000000010000,EasySMX ESM-9101,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, +030000006e0500000720000010010000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux, +030000007d0400000640000010010000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Linux, +03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000007e0500003703000000000000,GameCube Adapter,a:b0,b:b1,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, +19000000030000000300000002030000,GameForce Controller,a:b1,b:b0,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000ac0500005b05000010010000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ac0500001a06000011010000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +190000004b4800000010000000010000,GO-Advance Controller,a:b1,b:b0,back:b10,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,leftshoulder:b4,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b13,start:b15,x:b2,y:b3,platform:Linux, +190000004b4800000010000001010000,GO-Advance Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b13,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b16,righttrigger:b15,start:b17,x:b2,y:b3,platform:Linux, +190000004b4800000011000000010000,GO-Super Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b2,y:b3,platform:Linux, +03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000007d0400000540000000010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux, +030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +06000000adde0000efbe000002010000,Hidromancer Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, +03000000c9110000f055000011010000,HJC Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000632500002605000010010000,HJDX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux, +030000000d0f00006d00000020010000,Hori EDGE 301,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:+a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00008400000011010000,Hori Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005f00000011010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005e00000011010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005001000009040000,Hori Fighting Commander OCTA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00008500000010010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00008600000002010000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00003701000013010000,Hori Fighting Stick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b3,y:b2,platform:Linux, +030000000d0f00008800000011010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00008700000011010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,rightstick:b11,righttrigger:a4,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00001000000011010000,Hori Fightstick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000003f5000033050000,Hori Fightstick VX,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b8,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00004d00000011010000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux, +030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f0000aa00000011010000,Hori Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000000d0f00001100000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00002200000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00001600000000010000,Hori Real Arcade Pro EXSE,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00008501000015010000,Hori Switch Split Pad Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00006e00000011010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006600000011010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f0000ee00000011010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006700000001010000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +050000000d0f0000f600000001000000,Horipad Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +05000000242e00000b20000001000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Linux, +03000000242e0000ff0b000011010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Linux, +03000000242e00006a38000010010000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,start:b5,leftshoulder:b2,rightshoulder:b3,leftx:a0,lefty:a1,platform:Linux, +03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000f00300008d03000011010000,HyperX Clutch,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, +050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux, +03000000120c00000500000010010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, +03000000ef0500000300000000010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, +03000000fd0500000030000000010000,InterAct GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Linux, +03000000fd0500002a26000000010000,InterAct HammerHead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, +0500000049190000020400001b010000,Ipega PG 9069,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000632500007505000011010000,Ipega PG 9099,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +0500000049190000030400001b010000,Ipega PG9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000491900000204000000000000,Ipega PG9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000300f00001001000010010000,Jess Tech Dual Analog Rumble,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000ba2200002010000001010000,Jess Technology Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux, +050000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux, +030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, +03000000bd12000003c0000010010000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000242f00002d00000011010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000242f00008a00000011010000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, +030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d040000d1ca000000000000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001dc2000014400000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001ec2000019200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001ec2000020200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000019c2000011010000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001fc2000005030000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, +030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux, +05000000380700006652000025010000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008532000010010000,Mad Catz Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000380700005032000011010000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700005082000011010000,Mad Catz Fightpad Pro PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, +03000000380700008034000011010000,Mad Catz Fightstick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008084000011010000,Mad Catz Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008433000011010000,Mad Catz Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008483000011010000,Mad Catz Fightstick TE S PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700001888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700003888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700001647000010040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000380700003847000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +030000008f0e00001330000010010000,Mayflash Controller Adapter,a:b1,b:b2,back:b8,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3~,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +03000000790000004318000010010000,Mayflash GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, +0300000079000000d218000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000242f0000f700000001010000,Mayflash Magic S Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000008f0e00001030000010010000,Mayflash Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux, +0300000025090000e803000001010000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +03000000790000000318000011010000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux, +03000000790000000018000011010000,Mayflash Wii U Pro Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000b50700001203000010010000,Mega World Logic 3 Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000780000000600000010010000,Microntek Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +030000005e0400002800000000010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Linux, +030000005e0400000300000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux, +030000005e0400000700000000010000,Microsoft SideWinder,a:b0,b:b1,back:b8,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux, +030000005e0400000e00000000010000,Microsoft SideWinder Freestyle Pro,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, +030000005e0400002700000000010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Linux, +030000005e0400008502000000010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e0400008902000021010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e0400008e02000001000000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.1,dpleft:h0.2,dpright:h0.8,dpup:h0.4,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000004010000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000056210000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000062230000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000001010000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000dd02000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000008040000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000e302000003020000,Microsoft Xbox One Elite,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000005e040000120b00000b050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, +050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +05000000e80400006e0400001b010000,Mocute 053X M59,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000004d4f435554452d3035305800,Mocute 054X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000d6200000e589000001000000,Moga 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +05000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +03000000c62400002b89000011010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c62400001a89000000010000,MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux, +03000000790000004518000010010000,Nexilux GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux, +060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +030000009b2800008000000020020000,Nintendo Classic Controller,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux, +030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux, +03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux, +060000004e696e74656e646f20537700,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +060000007e0500000620000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b16,b:b15,back:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,platform:Linux, +03000000d620000013a7000011010000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000007e0500000920000000026803,Nintendo Switch Pro Controller,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Linux, +030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux, +05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux, +050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux, +050000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, +03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux, +05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux, +03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux, +19000000010000000200000011000000,ODROID Go 2,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux, +03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:Linux, +05000000362800000100000002010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +05000000362800000100000003010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +05000000362800000100000004010000,OUYA Controller,a:b0,b:b3,back:b14,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b16,x:b1,y:b2,platform:Linux, +03000000830500005020000010010000,Padix Rockfire PlayStation Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux, +03000000ff1100003133000010010000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e0000b802000001010000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000b802000013020000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00008001000011010000,PDP Faceoff Nintendo Switch Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00008501000011010000,PDP Nintendo Switch Fightpad Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00002801000011010000,PDP PS3 Rock Candy Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00000901000011010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000004f9000000010000,PDP Xbox 360 Versus Fighting,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000a802000023020000,PDP Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e0000d802000006640000,PDP Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000666600006706000000010000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, +030000004c050000da0c000011010000,PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000d9040000160f000000010000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c62400001a53000000010000,PowerA Mini Pro Ex,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000c62400001a58000001010000,PowerA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000220000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, +03000000d62000000228000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d62000000f20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000005f1400003102000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00001402000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000008f0e00000300000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +050000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +050000004c0500006802000000800000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +05000000504c415953544154494f4e00,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +060000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +03000000c01100000140000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000c405000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000f20d000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000f20d000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +03000000300f00001211000011010000,Qanba Arcade Joystick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux, +03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000222c00000020000011010000,Qanba Drone Arcade PS4 Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux, +03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000009b2800000300000001010000,Raphnet 4nes4snes,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, +030000009b2800004200000001010000,Raphnet Dual NES Adapter,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux, +030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, +030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, +030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000321500000204000011010000,Razer Panthera PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000104000011010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000810000011010000,Razer Panthera PS4 Evo Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000010000011010000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000321500000a10000001000000,Razer Raiju Tournament Edition,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000011000011010000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000008916000000fe000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c6240000045d000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux, +190000004b4800000111000000010000,RetroGame Joypad,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux, +0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +00000000526574726f53746f6e653200,RetroStone 2 Controller,a:b1,b:b0,back:b10,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Linux, +03000000341200000400000000010000,RetroUSB N64 RetroPort,+rightx:b8,+righty:b10,-rightx:b9,-righty:b11,a:b7,b:b6,dpdown:b2,dpleft:b1,dpright:b0,dpup:b3,leftshoulder:b13,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b12,start:b4,platform:Linux, +030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00001f01000000010000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00008701000011010000,Rock Candy Switch Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000c6240000fefa000000010000,Rock Candy Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000a306000023f6000011010000,Saitek Cyborg V1 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux, +03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux, +03000000a30600000cff000010010000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux, +03000000a30600000c04000011010000,Saitek P2900,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, +03000000a306000018f5000010010000,Saitek P3200 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, +03000000a30600000b04000000010000,Saitek P990 Dual Analog,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux, +03000000a306000020f6000011010000,Saitek PS2700 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +05000000e804000000a000001b010000,Samsung EIGP20,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux, +03000000a30c00002500000011010000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux, +03000000790000001100000011010000,Sega Saturn,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux, +03000000790000002201000011010000,Sega Saturn,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, +03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux, +030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000632500007505000010010000,Shanwan PS3 PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000bc2000000055000010010000,Shanwan PS3 PC ,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, +03000000250900000500000000010000,Sony PS2 pad with SmartJoy Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000005e0400008e02000073050000,Speedlink Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000020200000,SpeedLink Xeox Pro Analog,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, +03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000512000010010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,platform:Linux, +03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b10,guide:b11,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Linux, +03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000ad1b000038f0000090040000,Street Fighter IV Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000003b07000004a1000000010000,Suncom SFX Plus,a:b0,b:b2,back:b7,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux, +03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +030000008f0e00000d31000010010000,SZMY Power 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000457500000401000011010000,SZMY Power DS4 Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000457500002211000010010000,SZMY Power Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000008f0e00001431000010010000,SZMY Power PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux, +03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000020b3000010010000,Thrustmaster Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000023b3000000010000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f0400000ed0000011010000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux, +030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux, +030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, +030000004f04000004b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000026b3000002040000,Thrustmaster GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c6240000025b000002020000,Thrustmaster GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000004f04000008d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000009d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000007d0000000010000,Thrustmaster T Mini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000012b3000010010000,Thrustmaster Vibrating Gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +03000000571d00002000000010010000,Tomee SNES Adapter,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, +03000000bd12000015d0000010010000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000d814000007cd000011010000,Toodles 2008 Chimp PC PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux, +030000005e0400008e02000070050000,Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c01100000591000011010000,Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000680a00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +03000000780300000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +03000000e00d00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +03000000f00600000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, +030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000151900005678000010010000,Uniplay U6,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, +03000000790000001100000000010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux, +030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00000702000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +05000000ac0500003232000001000000,VR Box Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +05000000434f4d4d414e440000000000,VX Gaming Command Series,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +0000000058626f782033363020576900,Xbox 360 Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, +030000005e0400001907000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000014010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400009102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000000010000,Xbox 360 EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000006f0e00001304000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +0000000058626f782047616d65706100,Xbox Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000001030000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b000009050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000007050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000009050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000011050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000130b000015050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +060000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux, +03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux, +xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000120c0000100e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000101e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +# MiSTer specific default controller mappings + +#MiSTer uses a modified version of hid-playstation that exposes the microphone mute as a normal button. +#Adjust the button numbers to reflect this +030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,platform:MiSTer, +050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,platform:MiSTer, + +#Guncon 2 plug and play entries for various cores +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,b:b2,menuok:b2,menuesc:b0,start:b0,a:b1,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:PSX +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b2,menuesc:b0,rightshoulder:b2,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:NES +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,b:b2,menuok:b2,menuesc:b0,a:b0,x:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:SNES +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,b:b2,menuok:b2,menuesc:b0,a:b0,rightshoulder:b1,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:Genesis +030000009a0b00006a01000000010000,Namco GunCon 2,b:b2,menuok:b2,menuesc:b0,a:b0,rightshoulder:b1,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:MegaCD +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b2,menuesc:b0,b:b2,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:SMS +030000009a0b00006a01000000010000,Namco GunCon 2,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b2,menuesc:b0,b:b2,start:b5,guide:h0.4,guide2:b5,platform:MiSTer,mistercore:ATARI7800 + +#MisterCade default mapping +03000000d0160000be10000001010000,Mister Addons MiSTer JAMMA Board,dpright:h0.2,dpleft:h0.8,dpdown:h0.4,dpup:h0.1,menuok:b0,menuesc:b1,b:b3,a:b2,y:b0,x:b6,leftshoulder:b7,rightshoulder:b1,back:b8,start:b9,guide:b9,guide2:h0.4,platform:MiSTer + diff --git a/release-work/stock-extract/files/linux/mt32-rom-data/README b/release-work/stock-extract/files/linux/mt32-rom-data/README new file mode 100644 index 00000000..37932a2c --- /dev/null +++ b/release-work/stock-extract/files/linux/mt32-rom-data/README @@ -0,0 +1 @@ +Put Roland MT-32 or CM-32 ROMS HERE \ No newline at end of file diff --git a/release-work/stock-extract/files/linux/ppp_options b/release-work/stock-extract/files/linux/ppp_options new file mode 100644 index 00000000..fdbb001d --- /dev/null +++ b/release-work/stock-extract/files/linux/ppp_options @@ -0,0 +1,359 @@ +# /etc/ppp/options +# +# Originally created by Jim Knoble +# Modified for Debian by alvar Bray +# Modified for PPP Server setup by Christoph Lameter +# +# To quickly see what options are active in this file, use this command: +# egrep -v '#|^ *$' /etc/ppp/options + +# Specify which DNS Servers the incoming Win95 or WinNT Connection should use +# Two Servers can be remotely configured +#ms-dns 192.168.1.1 +#ms-dns 192.168.1.2 + +# Specify which WINS Servers the incoming connection Win95 or WinNT should use +# ms-wins 192.168.1.50 +# ms-wins 192.168.1.51 + +# Run the executable or shell command specified after pppd has +# terminated the link. This script could, for example, issue commands +# to the modem to cause it to hang up if hardware modem control signals +# were not available. +#disconnect "chat -- \d+++\d\c OK ath0 OK" + +# async character map -- 32-bit hex; each bit is a character +# that needs to be escaped for pppd to receive it. 0x00000001 +# represents '\x01', and 0x80000000 represents '\x1f'. +asyncmap 0 + +# Require the peer to authenticate itself before allowing network +# packets to be sent or received. +# Please do not disable this setting. It is expected to be standard in +# future releases of pppd. Use the call option (see manpage) to disable +# authentication for specific peers. +noauth + +# Specifies that certain characters should be escaped on transmission +# (regardless of whether the peer requests them to be escaped with its +# async control character map). The characters to be escaped are +# specified as a list of hex numbers separated by commas. Note that +# almost any character can be specified for the escape option, unlike +# the asyncmap option which only allows control characters to be +# specified. The characters which may not be escaped are those with hex +# values 0x20 - 0x3f or 0x5e. +#escape 11,13,ff + +# Don't use the modem control lines. +local + +# Specifies that pppd should use a UUCP-style lock on the serial device +# to ensure exclusive access to the device. +lock + +# Don't show the passwords when logging the contents of PAP packets. +# This is the default. +hide-password + +# When logging the contents of PAP packets, this option causes pppd to +# show the password string in the log message. +#show-password + +# Use the modem control lines. On Ultrix, this option implies hardware +# flow control, as for the crtscts option. (This option is not fully +# implemented.) +#modem + +# Set the MRU [Maximum Receive Unit] value to for negotiation. pppd +# will ask the peer to send packets of no more than bytes. The +# minimum MRU value is 128. The default MRU value is 1500. A value of +# 296 is recommended for slow links (40 bytes for TCP/IP header + 256 +# bytes of data). +mru 1500 + +# Set the interface netmask to , a 32 bit netmask in "decimal dot" +# notation (e.g. 255.255.255.0). +#netmask 255.255.255.0 + +# Disables the default behaviour when no local IP address is specified, +# which is to determine (if possible) the local IP address from the +# hostname. With this option, the peer will have to supply the local IP +# address during IPCP negotiation (unless it specified explicitly on the +# command line or in an options file). +#noipdefault + +# Enables the "passive" option in the LCP. With this option, pppd will +# attempt to initiate a connection; if no reply is received from the +# peer, pppd will then just wait passively for a valid LCP packet from +# the peer (instead of exiting, as it does without this option). +passive + +# With this option, pppd will not transmit LCP packets to initiate a +# connection until a valid LCP packet is received from the peer (as for +# the "passive" option with old versions of pppd). +silent + +# Don't request or allow negotiation of any options for LCP and IPCP +# (use default values). +#-all + +# Disable Address/Control compression negotiation (use default, i.e. +# address/control field disabled). +#-ac + +# Disable asyncmap negotiation (use the default asyncmap, i.e. escape +# all control characters). +#-am + +# Don't fork to become a background process (otherwise pppd will do so +# if a serial device is specified). +-detach + +# Disable IP address negotiation (with this option, the remote IP +# address must be specified with an option on the command line or in +# an options file). +#-ip + +# Disable IPCP negotiation and IP communication. This option should +# only be required if the peer is buggy and gets confused by requests +# from pppd for IPCP negotiation. +#noip + +# Disable magic number negotiation. With this option, pppd cannot +# detect a looped-back line. +#-mn + +# Disable MRU [Maximum Receive Unit] negotiation (use default, i.e. +# 1500). +#-mru + +# Disable protocol field compression negotiation (use default, i.e. +# protocol field compression disabled). +#-pc + +# Require the peer to authenticate itself using PAP. +#+pap + +# Don't agree to authenticate using PAP. +#-pap + +# Require the peer to authenticate itself using CHAP [Cryptographic +# Handshake Authentication Protocol] authentication. +#+chap + +# Don't agree to authenticate using CHAP. +#-chap + +# Disable negotiation of Van Jacobson style IP header compression (use +# default, i.e. no compression). +#-vj + +# Increase debugging level (same as -d). If this option is given, pppd +# will log the contents of all control packets sent or received in a +# readable form. The packets are logged through syslog with facility +# daemon and level debug. This information can be directed to a file by +# setting up /etc/syslog.conf appropriately (see syslog.conf(5)). (If +# pppd is compiled with extra debugging enabled, it will log messages +# using facility local2 instead of daemon). +debug + +# Append the domain name to the local host name for authentication +# purposes. For example, if gethostname() returns the name porsche, +# but the fully qualified domain name is porsche.Quotron.COM, you would +# use the domain option to set the domain name to Quotron.COM. +#domain + +# Enable debugging code in the kernel-level PPP driver. The argument n +# is a number which is the sum of the following values: 1 to enable +# general debug messages, 2 to request that the contents of received +# packets be printed, and 4 to request that the contents of transmitted +# packets be printed. +#kdebug n + +# Set the MTU [Maximum Transmit Unit] value to . Unless the peer +# requests a smaller value via MRU negotiation, pppd will request that +# the kernel networking code send data packets of no more than n bytes +# through the PPP network interface. +mtu 1500 + +# Set the name of the local system for authentication purposes to . +# This is a privileged option. With this option, pppd will use lines in the +# secrets files which have as the second field when looking for a +# secret to use in authenticating the peer. In addition, unless overridden +# with the user option, will be used as the name to send to the peer +# when authenticating the local system to the peer. (Note that pppd does +# not append the domain name to .) +#name + +# Enforce the use of the hostname as the name of the local system for +# authentication purposes (overrides the name option). +#usehostname + +# Set the assumed name of the remote system for authentication purposes +# to . +#remotename + +# Add an entry to this system's ARP [Address Resolution Protocol] +# table with the IP address of the peer and the Ethernet address of this +# system. +proxyarp + +# Use the system password database for authenticating the peer using +# PAP. Note: mgetty already provides this option. If this is specified +# then dialin from users using a script under Linux to fire up ppp wont work. +#login + +# If this option is given, pppd will send an LCP echo-request frame to the +# peer every n seconds. Normally the peer should respond to the echo-request +# by sending an echo-reply. This option can be used with the +# lcp-echo-failure option to detect that the peer is no longer connected. +lcp-echo-interval 30 + +# If this option is given, pppd will presume the peer to be dead if n +# LCP echo-requests are sent without receiving a valid LCP echo-reply. +# If this happens, pppd will terminate the connection. Use of this +# option requires a non-zero value for the lcp-echo-interval parameter. +# This option can be used to enable pppd to terminate after the physical +# connection has been broken (e.g., the modem has hung up) in +# situations where no hardware modem control lines are available. +lcp-echo-failure 4 + +# Set the LCP restart interval (retransmission timeout) to seconds +# (default 3). +#lcp-restart + +# Set the maximum number of LCP terminate-request transmissions to +# (default 3). +#lcp-max-terminate + +# Set the maximum number of LCP configure-request transmissions to +# (default 10). +#lcp-max-configure + +# Set the maximum number of LCP configure-NAKs returned before starting +# to send configure-Rejects instead to (default 10). +#lcp-max-failure + +# Set the IPCP restart interval (retransmission timeout) to +# seconds (default 3). +#ipcp-restart + +# Set the maximum number of IPCP terminate-request transmissions to +# (default 3). +#ipcp-max-terminate + +# Set the maximum number of IPCP configure-request transmissions to +# (default 10). +#ipcp-max-configure + +# Set the maximum number of IPCP configure-NAKs returned before starting +# to send configure-Rejects instead to (default 10). +#ipcp-max-failure + +# Set the PAP restart interval (retransmission timeout) to seconds +# (default 3). +#pap-restart + +# Set the maximum number of PAP authenticate-request transmissions to +# (default 10). +#pap-max-authreq + +# Set the maximum time that pppd will wait for the peer to authenticate +# itself with PAP to seconds (0 means no limit). +#pap-timeout + +# Set the CHAP restart interval (retransmission timeout for +# challenges) to seconds (default 3). +#chap-restart + +# Set the maximum number of CHAP challenge transmissions to +# (default 10). +#chap-max-challenge + +# If this option is given, pppd will rechallenge the peer every +# seconds. +#chap-interval + +# With this option, pppd will accept the peer's idea of our local IP +# address, even if the local IP address was specified in an option. +#ipcp-accept-local + +# With this option, pppd will accept the peer's idea of its (remote) IP +# address, even if the remote IP address was specified in an option. +#ipcp-accept-remote + +# Disable the IPXCP and IPX protocols. +# To let pppd pass IPX packets comment this out --- you'll probably also +# want to install ipxripd, and have the Internal IPX Network option enabled +# in your kernel. /usr/doc/HOWTO/IPX-HOWTO.gz contains more info. +noipx + +# Exit once a connection has been made and terminated. This is the default, +# unless the `persist' or `demand' option has been specified. +#nopersist + +# Do not exit after a connection is terminated; instead try to reopen +# the connection. +#persist + +# Terminate after n consecutive failed connection attempts. +# A value of 0 means no limit. The default value is 10. +#maxfail + +# Initiate the link only on demand, i.e. when data traffic is present. +# With this option, the remote IP address must be specified by the user on +# the command line or in an options file. Pppd will initially configure +# the interface and enable it for IP traffic without connecting to the peer. +# When traffic is available, pppd will connect to the peer and perform +# negotiation, authentication, etc. When this is completed, pppd will +# commence passing data packets (i.e., IP packets) across the link. +#demand + +# Specifies that pppd should disconnect if the link is idle for seconds. +# The link is idle when no data packets (i.e. IP packets) are being sent or +# received. Note: it is not advisable to use this option with the persist +# option without the demand option. If the active-filter option is given, +# data packets which are rejected by the specified activity filter also +# count as the link being idle. +#idle + +# Specifies how many seconds to wait before re-initiating the link after +# it terminates. This option only has any effect if the persist or demand +# option is used. The holdoff period is not applied if the link was +# terminated because it was idle. +#holdoff + +# Wait for up n milliseconds after the connect script finishes for a valid +# PPP packet from the peer. At the end of this time, or when a valid PPP +# packet is received from the peer, pppd will commence negotiation by +# sending its first LCP packet. The default value is 1000 (1 second). +# This wait period only applies if the connect or pty option is used. +#connect-delay + +# Packet filtering: for more information, see pppd(8) +# Any packets matching the filter expression will be interpreted as link +# activity, and will cause a "demand" connection to be activated, and reset +# the idle connection timer. (idle option) +# The filter expression is akin to that of tcpdump(1) +#active-filter + +# Serial device. Do not change! +/dev/ttyS1 + +############################################################################## + +# Speed of serial connection. Keep it commented out. It's controlled outside. +#115200 + +# Use hardware flow control (i.e. RTS/CTS) to control the flow of data +# on the serial port. +crtscts + +# Use software flow control (i.e. XON/XOFF) to control the flow of data +# on the serial port. +#xonxoff + +# You may explicitly define local and remote IPs for PPP link. +# new MiSTer releases don't require it anymore. +# IPs entered here will override automatically assigned IPs. +#192.168.1.1:192.168.1.10 diff --git a/release-work/stock-extract/files/linux/soundfonts/README b/release-work/stock-extract/files/linux/soundfonts/README new file mode 100644 index 00000000..cc22ff61 --- /dev/null +++ b/release-work/stock-extract/files/linux/soundfonts/README @@ -0,0 +1 @@ +Put SF2 sounffonts here. diff --git a/release-work/stock-extract/files/linux/u-boot.txt_example b/release-work/stock-extract/files/linux/u-boot.txt_example new file mode 100644 index 00000000..edf5b139 --- /dev/null +++ b/release-work/stock-extract/files/linux/u-boot.txt_example @@ -0,0 +1 @@ +v=loglevel=4 usbhid.jspoll=1 xpad.cpoll=1 diff --git a/release-work/stock-extract/files/linux/updateboot b/release-work/stock-extract/files/linux/updateboot new file mode 100644 index 00000000..18b7d3db --- /dev/null +++ b/release-work/stock-extract/files/linux/updateboot @@ -0,0 +1,21 @@ +#!/bin/sh + +if [ -f /media/fat/linux/uboot.img ]; then + + echo "" + echo "Erasing u-boot saved environment" + dd if=/dev/zero of=/dev/mmcblk0 bs=512 seek=1 count=1 + echo "" + + if [ -b /dev/mmcblk0p3 ]; then + echo "Using old layout" + dd if=/media/fat/linux/uboot.img of=/dev/mmcblk0p3 + else + echo "Using new layout" + dd if=/media/fat/linux/uboot.img of=/dev/mmcblk0p2 + fi + + echo "" + echo "Done." + echo "" +fi diff --git a/release-work/stock-extract/files/linux/zImage_dtb b/release-work/stock-extract/files/linux/zImage_dtb new file mode 100644 index 00000000..8fbdb0bc Binary files /dev/null and b/release-work/stock-extract/files/linux/zImage_dtb differ diff --git a/release-work/stock_release.7z.verified b/release-work/stock_release.7z.verified new file mode 100644 index 00000000..fce992aa --- /dev/null +++ b/release-work/stock_release.7z.verified @@ -0,0 +1 @@ +e5bea8413adc249f420e08a48e5cdab9b8c5da04bf52d81dc5261f0f350adf66 diff --git a/release-work/ver/MiSTer.version b/release-work/ver/MiSTer.version new file mode 100644 index 00000000..c2e09a76 --- /dev/null +++ b/release-work/ver/MiSTer.version @@ -0,0 +1 @@ +260904 \ No newline at end of file diff --git a/renovate.json b/renovate.json index 2b34fa9d..20e95abc 100644 --- a/renovate.json +++ b/renovate.json @@ -41,7 +41,7 @@ "a regex manager has no reason to skip. That model was validated by replaying it", "over the tree at e66b46b, where it reproduces the recorded 18/19 exactly.", "SINCE THE FRAGMENT SPLIT (2026-09): the 6.18 kernel manager matches ONE file,", - "configs/fragments/de10nano.fragment, whose only occurrence of the symbol is the", + "configs/mister_de10nano_defconfig, whose only occurrence of the symbol is the", "setting itself (the kernel-only stack shares that file, so the second defconfig", "and its match are gone). By the model above that is fileCount 22 / depCount 22", "(the 6.18 manager went from 2 files / 3 matches to 1 / 1) -- DERIVED, not", @@ -141,9 +141,9 @@ }, { "customType": "regex", - "description": "Bump the pinned 6.18.y kernel (BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE), constrained to the current longterm line by the custom datasource above. Since the 2026-09 fragment split the pin lives in exactly ONE file, configs/fragments/de10nano.fragment: the shipped image's stack and the kernel-only stack every kernel variant builds on both include that fragment (configs/fragments/stacks.mk), so there is no mirrored copy to bump alongside it any more. (Before the split BOTH configs/mister_de10nano_defconfig and configs/mister_kernel_defconfig were listed, because a manager covering only the main one bumped half the repo and left the copy behind -- which is exactly what happened on the 6.18.38 -> 6.18.39 bump and was caught, loudly, by the lockstep check. That failure mode is gone by construction; scripts/check-kernel-defconfig-sync.sh now guards the construction instead.) configs/mister_rt.fragment and configs/fragments/de25nano.fragment carry the same SYMBOL but are deliberately NOT matched here: both pin the 7.2 line (the rt fragment has its own manager below; the DE25 pin is unmanaged today). The companion tarball hash (board/mister/de10nano/patches/linux/linux.hash) is NOT updated here -- it comes from kernel.org's own signed sha256sums.asc; see .github/workflows/renovate-hash-sync.yml. CI (build.yml, pull_request-triggered) then proves the carried Linux patches still apply against the bumped source -- see docs/renovate.md and PLAN.md \u00a713.", + "description": "Bump the pinned 6.18.y kernel (BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE), constrained to the current longterm line by the custom datasource above. Since ADR 0030 (2026-09-11) the pin lives in exactly ONE file, configs/mister_de10nano_defconfig (the committed Buildroot defconfig; the fragment stacks are gone): the shipped image's stack and the kernel-only stack every kernel variant builds on both include that fragment (configs/fragments/stacks.mk), so there is no mirrored copy to bump alongside it any more. (Before the split BOTH configs/mister_de10nano_defconfig and configs/mister_kernel_defconfig were listed, because a manager covering only the main one bumped half the repo and left the copy behind -- which is exactly what happened on the 6.18.38 -> 6.18.39 bump and was caught, loudly, by the lockstep check. That failure mode is gone by construction; scripts/check-kernel-defconfig-sync.sh now guards the construction instead.) configs/mister_rt.fragment and configs/fragments/de25nano.fragment carry the same SYMBOL but are deliberately NOT matched here: both pin the 7.2 line (the rt fragment has its own manager below; the DE25 pin is unmanaged today). The companion tarball hash (board/mister/de10nano/patches/linux/linux.hash) is NOT updated here -- it comes from kernel.org's own signed sha256sums.asc; see .github/workflows/renovate-hash-sync.yml. CI (build.yml, pull_request-triggered) then proves the carried Linux patches still apply against the bumped source -- see docs/renovate.md and PLAN.md \u00a713.", "managerFilePatterns": [ - "/^configs/fragments/de10nano\\.fragment$/" + "/^configs/mister_de10nano_defconfig$/" ], "matchStrings": [ "BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE=\"(?[\\d.]+)\"" @@ -154,12 +154,12 @@ }, { "customType": "regex", - "description": "Bump the RT/beta kernel pin (BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE in configs/mister_rt.fragment), which tracks the 7.2 line rather than 6.18.y -- see docs/rt-beta-kernel.md and ADR 0021. Kept as a SEPARATE manager from the 6.18 one above, with its own datasource and its own depName, because the two must never be able to propose each other's version: the fragment carries the identical Kconfig symbol, so a single shared manager would hand one datasource the other's currentValue. UPDATED 2026-08-17, when 7.2 released and this pin crossed the -rc boundary (7.2-rc7 -> 7.2); the depName went `kernel-mainline-rt` -> `kernel-rt-7.2` because the old one now describes a line this pin deliberately no longer follows. Renaming a depName orphans any open branch under the old name and starts a fresh dependency-dashboard entry -- that was accepted as a one-off cost, not overlooked. THE matchString MUST ACCEPT THREE FORMS and the reason is a silent-failure trap: `7.2-rc7` (history, and the shape it would return to if a human ever repoints this at an -rc), `7.2` (a two-component release -- what kernel.org actually publishes for a .0), and `7.2.1` (every later point release on this line). The three-component alternative is not hypothetical padding: the moment 7.2.1 lands and Renovate writes it here, a matchString that only accepted two components would stop matching its own output, extract zero deps, and silently leave the pin unmanaged forever -- validator-clean and invisible, exactly the failure mode this file's header describes. THE COMPANION HASH IS NOW AUTO-REFRESHED, which reverses what this description said until 2026-08-17: linux-7.2.tar.xz is an ordinary release tarball covered by kernel.org's PGP-signed sha256sums.asc, so scripts/hash-sync-kernel.sh handles this pin as its `rt` case and a routine 7.2.y bump PR can go green on its own. That script REFUSES any value containing `-rc` (kernel.org signs no manifest for a cgit snapshot, so such a hash can only be hand-written TOFU) and leaves the line untouched, so the build fails closed at the kernel download rather than blessing an unexamined snapshot -- see linux.hash's own header and docs/ci.md#renovate-hash-sync-not-automated. allowedVersions below keeps -rc out of this manager's reach in the first place; the script's refusal is the second line of defense for a hand edit.", + "description": "Bump the RT/beta kernel pin (BR2_PACKAGE_LINUX_RT_VERSION in configs/mister_de10nano_defconfig since ADR 0030 -- the variant is package/linux-rt, a second kernel package of the image configuration; its hash is package/linux-rt/linux-rt.hash), which tracks the 7.2 line rather than 6.18.y -- see docs/rt-beta-kernel.md and ADR 0021. Kept as a SEPARATE manager from the 6.18 one above, with its own datasource and its own depName, because the two must never be able to propose each other's version: the fragment carries the identical Kconfig symbol, so a single shared manager would hand one datasource the other's currentValue. UPDATED 2026-08-17, when 7.2 released and this pin crossed the -rc boundary (7.2-rc7 -> 7.2); the depName went `kernel-mainline-rt` -> `kernel-rt-7.2` because the old one now describes a line this pin deliberately no longer follows. Renaming a depName orphans any open branch under the old name and starts a fresh dependency-dashboard entry -- that was accepted as a one-off cost, not overlooked. THE matchString MUST ACCEPT THREE FORMS and the reason is a silent-failure trap: `7.2-rc7` (history, and the shape it would return to if a human ever repoints this at an -rc), `7.2` (a two-component release -- what kernel.org actually publishes for a .0), and `7.2.1` (every later point release on this line). The three-component alternative is not hypothetical padding: the moment 7.2.1 lands and Renovate writes it here, a matchString that only accepted two components would stop matching its own output, extract zero deps, and silently leave the pin unmanaged forever -- validator-clean and invisible, exactly the failure mode this file's header describes. THE COMPANION HASH IS NOW AUTO-REFRESHED, which reverses what this description said until 2026-08-17: linux-7.2.tar.xz is an ordinary release tarball covered by kernel.org's PGP-signed sha256sums.asc, so scripts/hash-sync-kernel.sh handles this pin as its `rt` case and a routine 7.2.y bump PR can go green on its own. That script REFUSES any value containing `-rc` (kernel.org signs no manifest for a cgit snapshot, so such a hash can only be hand-written TOFU) and leaves the line untouched, so the build fails closed at the kernel download rather than blessing an unexamined snapshot -- see linux.hash's own header and docs/ci.md#renovate-hash-sync-not-automated. allowedVersions below keeps -rc out of this manager's reach in the first place; the script's refusal is the second line of defense for a hand edit.", "managerFilePatterns": [ - "/^configs/mister_rt\\.fragment$/" + "/^configs/mister_de10nano_defconfig$/" ], "matchStrings": [ - "BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE=\"(?\\d+\\.\\d+(?:\\.\\d+)?(?:-rc\\d+)?)\"" + "BR2_PACKAGE_LINUX_RT_VERSION=\"(?\\d+\\.\\d+(?:\\.\\d+)?(?:-rc\\d+)?)\"" ], "depNameTemplate": "kernel-rt-7.2", "datasourceTemplate": "custom.kernelStable72", diff --git a/scripts/check-abi.sh b/scripts/check-abi.sh index 2fccfb9b..997bcc21 100755 --- a/scripts/check-abi.sh +++ b/scripts/check-abi.sh @@ -383,7 +383,7 @@ fi # A-25 — depmod must have regenerated modules.alias at image build, or udev # cannot autoload a driver by modalias. Since ADR 0021's 2026-07-18 amendment # the rootfs may legitimately carry MORE than one kernel-version tree (the -# main 6.18 one plus kernel variants merged in via work/extra-modules-overlay, +# main 6.18 one plus kernel variants built in the same tree (package/linux-rt), # e.g. the RT beta's 7.2 tree) — every tree present must be depmod'd, because # whichever kernel boots consults its own tree. At least one is required; a # local main-only build with exactly one is equally legitimate, so exactly-2 diff --git a/scripts/check-config-fragments.sh b/scripts/check-config-fragments.sh deleted file mode 100755 index 4cf51399..00000000 --- a/scripts/check-config-fragments.sh +++ /dev/null @@ -1,503 +0,0 @@ -#!/usr/bin/env bash -# -# check-config-fragments.sh — regenerate every Buildroot configuration from -# its fragment stack and prove the stack means what it says -# (docs/buildroot-config.md §1, §11). -# -# The monolithic defconfigs were split into configs/fragments/ (stacks.mk -# lists which fragments make which configuration). merge_config.sh + -# olddefconfig is a forgiving pipeline: a fragment can redefine a symbol an -# earlier one set (merge_config.sh only WARNS), and olddefconfig silently -# drops any symbol whose dependencies are unmet or whose name no longer -# exists in this Buildroot. Neither is an error at build time, both ship a -# different image than the fragments describe. This script turns each into a -# CI failure, and pins the resolved DE10 configuration with a golden hash so -# any drift — a Buildroot bump changing a default underneath us, a fragment -# edit with an unexpected knock-on — fails until the hash is deliberately -# updated with a commit that explains why. -# -# What it asserts, per stack (de10nano, de10nano-kernel, de25nano, -# initramfs-de10nano, initramfs-de25nano, and -# de10nano-kernel + configs/mister_.fragment for every kernel -# variant): -# (a) NO REDEFINITION between fragments: a symbol defined by two fragments -# of one stack (same value or not) is a layering smell — a symbol set -# in common and overridden per board should have been board-only. -# Checked from the fragment text (independent of merge_config.sh's -# output format) AND merge_config.sh's own "redefined" warnings are -# captured and must be empty. The ONE designed exception is a kernel -# variant's fragment overriding the kernel version + patch dir -# (mister_rt.fragment) — ALLOWED_OVERRIDES below, per variant. -# (b) EVERY FRAGMENT SYMBOL SURVIVES olddefconfig: each `BR2_X=val` line -# must appear verbatim in the resolved .config, and each -# `# BR2_X is not set` must resolve to exactly that line (a typo'd -# symbol name is absent from the resolved config in EITHER form, and -# kconfig says nothing). This is what catches a dropped symbol (unmet -# dependency, renamed option after a Buildroot bump, typo) that kconfig -# would otherwise discard silently — the DE25 bring-up's -# fragment-vs-resolved comparison, made permanent. -# (c) RESOLVED-LEVEL LOCKSTEP: the de10nano and de10nano-kernel resolved -# configs agree on every symbol except a named list of designed -# divergences (packages, init/shell choice, rootfs image types, system -# configuration, package-driven glibc gconv copy). The text-level half -# of this guarantee (scripts/check-kernel-defconfig-sync.sh) runs -# without a Buildroot tree; this half is what proves the shared -# fragments still resolve identically once package selects are in play. -# (d) GOLDEN HASH: sha256 of the NORMALISED resolved .config equals the -# value recorded in configs/fragments/golden.sha256 for the pinned -# Buildroot version. Normalisation keeps only the SET symbols -# (`BR2_X=...`), and drops what legitimately varies by host or checkout -# (see normalise_config) plus the two kernel-version symbols Renovate -# moves weekly (BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE and kconfig's -# derived BR2_LINUX_KERNEL_VERSION — their landing is already proved by -# (b)), so the hash is stable across machines and across routine -# kernel bumps of every pin (6.18.y, the rt 7.2.y pin, the DE25 pin) -# and moves ONLY when the resolved configuration really changes. -# olddefconfig is also run with the HOST inputs pinned to canonical -# values (HOSTARCH, HOSTCC_VERSION — Buildroot derives BR2_HOSTARCH, -# BR2_HOST_GCC_AT_LEAST_* and every host-gated package from them), so -# the resolved config the check reasons about is a pure function of -# (fragments, Buildroot version), never of the machine running it. -# Two outcomes: a MISMATCH against a recorded line is a failure (the -# configuration drifted; if intended, --update-golden and commit with -# the reason). NO line at all for the pinned Buildroot version is a -# ::warning, not a failure — a Buildroot bump changes defaults and is -# expected to move every hash; the check prints the new lines ready to -# paste, .github/workflows/renovate-hash-sync.yml case 8 commits them -# on a Renovate bump PR, and the build is allowed to proceed so the -# bump PR still proves it builds. -# (f) STAGE-1 ARCH LOCKSTEP: every symbol an initramfs- fragment -# sets is set to the same value in .fragment (text-level, over -# the stripped fragments). The stage-1 cpio is built by its own stack, -# which cannot include the board fragment (that carries the kernel -# stanza), so the arch/ABI + headers-series lines are restated -- and -# a restated line that drifts builds a stage 1 for the wrong target. -# -# Cost: needs the pinned Buildroot tree (fetched/unpacked by `make -# buildroot-unpack` if absent — a 10 MB download, no compile beyond -# Buildroot's own kconfig `conf` binary) and runs olddefconfig once per stack. -# Seconds locally; a minute or two on a cold CI runner. No toolchain, no -# packages, no image. -# -# Usage: scripts/check-config-fragments.sh [--update-golden] [--keep] [STACK...] -# STACK limit to the named stack(s) (de10nano, de10nano-kernel, -# de25nano, or a kernel variant name such as rt); default: all. -# --update-golden rewrite configs/fragments/golden.sha256 from the current -# resolved configs instead of asserting against it. -# --keep leave output-config-check/ in place for inspection (it is -# always left in place on failure). -# CHECK_CONFIG_BR_DIR= use an already-unpacked Buildroot tree -# instead of the wrapper's work/buildroot (tests, CI fixtures). -# CHECK_CONFIG_HOSTARCH / CHECK_CONFIG_HOSTCC_VERSION override the pinned -# host inputs (self-tests only: the golden must NOT move). -# -# It also guards the hard-coded fragment PATHS outside stacks.mk (§ "path -# consumers" below): a fragment rename with stacks.mk updated would otherwise -# pass every check while action.yml's hashFiles() lists, renovate.json's -# managerFilePatterns and the scripts that read a pin by filename all went -# silently stale. -# -# Exit: 0 = every stack passes; 1 = an assertion failed; 2 = usage/IO error. - -set -euo pipefail -export LC_ALL=C - -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -# shellcheck source=scripts/lib/board-expectations.sh -. "$ROOT/scripts/lib/board-expectations.sh" -# shellcheck source=scripts/lib/config-stacks.sh -. "$ROOT/scripts/lib/config-stacks.sh" - -GOLDEN="$ROOT/configs/fragments/golden.sha256" -CHECK_DIR="$ROOT/output-config-check" - -# Canonical host inputs for olddefconfig (see (d) above). Buildroot computes -# both with `:=` from the real host compiler; a command-line assignment -# overrides that. x86_64 + GCC 14 is what the CI runners and the developer -# hosts have had since the 2026.05 bump; the values only have to be FIXED, -# not true, for the resolved config to be host-independent. -PIN_HOSTARCH="${CHECK_CONFIG_HOSTARCH:-x86_64}" -PIN_HOSTCC_VERSION="${CHECK_CONFIG_HOSTCC_VERSION:-14}" - -# Per-variant allowlist for (a): symbols a kernel variant's fragment is -# EXPECTED to redefine on top of the kernel-only stack. Anything else a -# variant redefines is a failure, so a variant that starts overriding, say, -# the toolchain has to come here and say so. -declare -A ALLOWED_OVERRIDES=( - [rt]="BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE BR2_LINUX_KERNEL_PATCH" -) - -# Designed divergences for (c): symbol-name PREFIXES on which the resolved -# de10nano and de10nano-kernel configs may differ. Everything else must be -# identical. Keep this list short and specific — it is the definition of -# "what a kernel variant is allowed not to share with the image". -LOCKSTEP_DIVERGENCE_PREFIXES=" -BR2_PACKAGE_ -BR2_INIT_ -BR2_SYSTEM_ -BR2_ROOTFS_OVERLAY -BR2_ROOTFS_POST_BUILD_SCRIPT -BR2_ROOTFS_DEVICE_CREATION_ -BR2_TARGET_ROOTFS_ -BR2_TARGET_GENERIC_ -BR2_TARGET_TZ_ -BR2_TARGET_LOCALTIME -BR2_GENERATE_LOCALE -BR2_TOOLCHAIN_GLIBC_GCONV_LIBS_ -BR2_GDB_VERSION -BR2_DEFCONFIG -" - -UPDATE_GOLDEN=false -KEEP=false -only=() -while [ "$#" -gt 0 ]; do - case "$1" in - --update-golden) UPDATE_GOLDEN=true ;; - --keep) KEEP=true ;; - -h|--help) sed -n '2,/^$/p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; - -*) echo "check-config-fragments: unknown option '$1'" >&2; exit 2 ;; - *) only+=("$1") ;; - esac - shift -done - -die() { echo "check-config-fragments: FATAL: $*" >&2; exit 2; } -fail() { echo "FAIL: $*" >&2; rc=1; } -rc=0 - -[ -f "$CONFIG_STACKS_MK" ] || die "missing $CONFIG_STACKS_MK" - -# --- Buildroot tree ----------------------------------------------------------- -# The wrapper Makefile owns fetching/verifying/unpacking the pinned tarball; -# reuse it rather than re-implementing the hash check here. `buildroot-unpack` -# has no hostshim prerequisite and olddefconfig needs none (Buildroot's -# dependencies.sh only runs for build targets). -BR_DIR="${CHECK_CONFIG_BR_DIR:-$ROOT/work/buildroot}" -if [ -z "${CHECK_CONFIG_BR_DIR:-}" ]; then - make -C "$ROOT" --no-print-directory buildroot-unpack >/dev/null || die "make buildroot-unpack failed" -fi -[ -x "$BR_DIR/support/kconfig/merge_config.sh" ] || die "no merge_config.sh under $BR_DIR" -BR_VERSION=$(sed -n -e 's/[[:space:]]*$//' -e 's/^BUILDROOT_VERSION[[:space:]]*?=[[:space:]]*//p' "$ROOT/Makefile" | head -1) -[ -n "$BR_VERSION" ] || die "could not read BUILDROOT_VERSION from Makefile" - -# --- Stack registry ----------------------------------------------------------- -# stacks.mk's stacks, plus one synthetic stack per kernel variant fragment -# (configs/mister_.fragment layered on the kernel-only stack — the same -# registry .github/actions/buildroot-build and scripts/list-kernel-variants.sh -# use). Order: stacks.mk order, then variants sorted by name. -declare -A STACK_FILES=() -stack_order=() -while IFS= read -r var; do - [ -n "$var" ] || continue - label=$(config_stack_label "$var") - STACK_FILES[$label]=$(config_stack_files "$var" | tr '\n' ' ') - stack_order+=("$label") -done < <(config_stack_vars) -[ -n "${STACK_FILES[de10nano-kernel]+set}" ] || die "stacks.mk defines no DE10NANO_KERNEL stack — kernel variants have no base" -shopt -s nullglob -for f in "$ROOT"/configs/mister_*.fragment; do - name="${f#"$ROOT"/configs/mister_}"; name="${name%.fragment}" - STACK_FILES[$name]="${STACK_FILES[de10nano-kernel]}$f " - stack_order+=("$name") -done -shopt -u nullglob - -if [ "${#only[@]}" -gt 0 ]; then - for s in "${only[@]}"; do - [ -n "${STACK_FILES[$s]+set}" ] || die "unknown stack '$s' (known: ${stack_order[*]})" - done - stack_order=("${only[@]}") -fi - -# --- Normalisation for the golden hash ---------------------------------------- -# Keep: every SET symbol (`BR2_X=...`). `# BR2_X is not set` lines are -# dropped from the hash — losslessly for drift detection, since a symbol that -# flips on shows up as a new set line and one that flips off as a vanished -# set line, and the not-set list is exactly where host-gated symbols (a -# package `depends on BR2_HOSTARCH = ...`, a host-gcc floor) appear or -# disappear between machines. Then drop the set symbols that legitimately -# vary by host or checkout even with the host inputs pinned: -# BR2_HOSTARCH, BR2_HOST_GCC_VERSION, BR2_HOST_GCC_AT_LEAST_* the build host -# BR2_PACKAGE_*_ARCH_SUPPORTS, BR2_PACKAGE_HOST_GO_BIN_HOST_ARCH, -# BR2_PACKAGE_PROVIDES_HOST_RUSTC HOSTARCH-derived -# BR2_PACKAGE_(HOST_)GOBJECT_INTROSPECTION, BR2_PACKAGE_HOST_QEMU*, -# BR2_PACKAGE_LIBGLIB2_BOOTSTRAP, BR2_PACKAGE_PYTHON_GOBJECT `depends on -# BR2_HOST_GCC_AT_LEAST_*` consumers that are =y here (measured: these -# are the only set lines that move between HOSTCC_VERSION 5/9/14 — -# the fragment lines among them are still proved by (b)) -# BR2_VERSION, BR2_EXTERNAL_MISTER_* git-describe / absolute path -# BR2_DEFCONFIG savedefconfig's output path -# BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE, BR2_LINUX_KERNEL_VERSION the Renovate- -# managed kernel pin and kconfig's copy of it (landing proved by (b)) -# Everything else is the configuration. -normalise_config() { - grep -E '^BR2_[A-Za-z0-9_]+=' "$1" \ - | grep -vE '^(BR2_HOSTARCH|BR2_HOST_GCC_VERSION|BR2_HOST_GCC_AT_LEAST_|BR2_VERSION=|BR2_EXTERNAL_MISTER_|BR2_DEFCONFIG=|BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE=|BR2_LINUX_KERNEL_VERSION=)' \ - | grep -vE '^(BR2_PACKAGE_[A-Z0-9_]+_ARCH_SUPPORTS=|BR2_PACKAGE_HOST_GO_BIN_HOST_ARCH=|BR2_PACKAGE_PROVIDES_HOST_RUSTC=)' \ - | grep -vE '^(BR2_PACKAGE_GOBJECT_INTROSPECTION=|BR2_PACKAGE_HOST_GOBJECT_INTROSPECTION=|BR2_PACKAGE_HOST_QEMU|BR2_PACKAGE_LIBGLIB2_BOOTSTRAP=|BR2_PACKAGE_PYTHON_GOBJECT=)' -} - -golden_has_version() { # any line recorded for BR_VERSION at all? - [ -f "$GOLDEN" ] && awk -v v="$BR_VERSION" '$1 == v { found = 1 } END { exit !found }' "$GOLDEN" -} - -golden_lookup() { # $1 = stack -> recorded hash for BR_VERSION, or empty - [ -f "$GOLDEN" ] || return 0 - awk -v v="$BR_VERSION" -v s="$1" '$1 == v && $2 == s { print $3 }' "$GOLDEN" | head -1 -} - -# --- Per-stack work ----------------------------------------------------------- -declare -A NEW_GOLDEN=() -declare -A RESOLVED=() -missing_golden=0 -for stack in "${stack_order[@]}"; do - # shellcheck disable=SC2206 # the file list is space-separated on purpose - files=(${STACK_FILES[$stack]}) - echo "==> $stack: ${files[*]#"$ROOT"/}" - for f in "${files[@]}"; do - [ -f "$f" ] || die "$stack: missing fragment $f" - done - odir="$CHECK_DIR/$stack" - rm -rf "$odir"; mkdir -p "$odir" - - # (a) text-level redefinition check, fragment by fragment in merge order. - declare -A seen=() - # shellcheck disable=SC2086 # word splitting of the allowlist is intended - allowed=" ${ALLOWED_OVERRIDES[$stack]:-} " - for f in "${files[@]}"; do - while IFS= read -r line; do - [ -n "$line" ] || continue - sym=$(config_line_symbol "$line") - if [ -n "${seen[$sym]+set}" ]; then - case "$allowed" in - *" $sym "*) ;; - *) fail "$stack: ${f#"$ROOT"/} redefines $sym, already defined by ${seen[$sym]#"$ROOT"/}. A symbol belongs in exactly one fragment of a stack (docs/buildroot-config.md §1); a kernel variant may override only what ALLOWED_OVERRIDES in $(basename "$0") lists." ;; - esac - fi - seen[$sym]="$f" - done < <(config_strip_fragment "$f") - done - unset seen - - # Merge (Buildroot's own tool, the same call the Makefile makes), keeping - # its stdout so its own redefinition warnings can be asserted empty too. - # TMPDIR: merge_config.sh mktemp's under it; keep that inside our dir. - if ! (cd "$BR_DIR" && TMPDIR="$odir" KCONFIG_CONFIG="$odir/.config" \ - ./support/kconfig/merge_config.sh -m -O "$odir" "${files[@]}") >"$odir/merge.log" 2>&1; then - cat "$odir/merge.log" >&2 - die "$stack: merge_config.sh failed" - fi - if grep -q 'is redefined by fragment' "$odir/merge.log"; then - while IFS= read -r sym; do - case "$allowed" in - *" $sym "*) ;; - *) fail "$stack: merge_config.sh reports $sym redefined (see $odir/merge.log)" ;; - esac - done < <(sed -n 's/^Value of \([A-Za-z0-9_]*\) is redefined by fragment .*/\1/p' "$odir/merge.log") - fi - - if ! make -C "$BR_DIR" O="$odir" BR2_EXTERNAL="$ROOT" BR2_DL_DIR="$ROOT/dl" \ - HOSTARCH="$PIN_HOSTARCH" HOSTCC_VERSION="$PIN_HOSTCC_VERSION" \ - olddefconfig >"$odir/olddefconfig.log" 2>&1; then - cat "$odir/olddefconfig.log" >&2 - die "$stack: olddefconfig failed" - fi - resolved="$odir/.config" - RESOLVED[$stack]="$resolved" - - # (b) every effective fragment line survives. "Effective" = the LAST - # definition in merge order, so an allowed variant override is checked - # against the override's value, not the base's. - declare -A effective=() - for f in "${files[@]}"; do - while IFS= read -r line; do - [ -n "$line" ] || continue - effective[$(config_line_symbol "$line")]="$line" - done < <(config_strip_fragment "$f") - done - dropped=0 - for sym in "${!effective[@]}"; do - line="${effective[$sym]}" - case "$line" in - "# "*" is not set") - # The symbol must come back as EXACTLY this line. `=y`/`=m` - # means the not-set was overridden by a select or default; - # absent in both forms means kconfig never heard of the name - # (typo, or the option no longer exists in this Buildroot). - if ! grep -qxF -- "$line" "$resolved"; then - actual=$(grep -E "^(# )?$sym( is not set|=)" "$resolved" || echo "") - fail "$stack: fragment says '$line' but the resolved .config has $actual" - dropped=$((dropped + 1)) - fi - ;; - *) - if ! grep -qxF -- "$line" "$resolved"; then - actual=$(grep -E "^(# )?$sym( is not set|=)" "$resolved" || echo "") - fail "$stack: '$line' did not survive olddefconfig; resolved: $actual" - dropped=$((dropped + 1)) - fi - ;; - esac - done - echo " ${#effective[@]} fragment symbol(s) checked against the resolved .config, $dropped dropped" - unset effective - - # (d) golden hash of the normalised resolved config. - normalise_config "$resolved" >"$odir/normalised.config" - hash=$(sha256sum "$odir/normalised.config" | cut -d' ' -f1) - NEW_GOLDEN[$stack]="$hash" - if [ "$UPDATE_GOLDEN" = false ]; then - want=$(golden_lookup "$stack") - if [ -z "$want" ] && ! golden_has_version; then - # A Buildroot bump: nothing recorded for this version yet. Warn, - # print the line, let the build proceed (see (d) in the header). - echo "::warning::$stack: no golden hash recorded for Buildroot $BR_VERSION in ${GOLDEN#"$ROOT"/} -- a Buildroot bump. Expected line: '$BR_VERSION $stack $hash'. renovate-hash-sync.yml case 8 commits it on a Renovate PR; by hand: '$(basename "$0") --update-golden', then commit with what changed." - missing_golden=$((missing_golden + 1)) - elif [ -z "$want" ]; then - fail "$stack: ${GOLDEN#"$ROOT"/} records Buildroot $BR_VERSION for other stacks but has no line for '$stack' (a new stack, or a deleted line). Run '$(basename "$0") --update-golden' and commit the new line with the reason." - elif [ "$want" != "$hash" ]; then - fail "$stack: resolved configuration DRIFTED — sha256 of the normalised .config is $hash, golden says $want (${GOLDEN#"$ROOT"/}). If the change is intended, run '$(basename "$0") --update-golden' and commit the new hash with a message saying what changed and why; the normalised config is at ${odir#"$ROOT"/}/normalised.config for diffing against the previous good run." - else - echo " golden hash matches ($hash)" - fi - fi -done - -# (c) resolved-level lockstep between the image and the kernel-only base. -if [ -n "${RESOLVED[de10nano]+set}" ] && [ -n "${RESOLVED[de10nano-kernel]+set}" ]; then - div=$(diff \ - <(normalise_config "${RESOLVED[de10nano]}" | sort) \ - <(normalise_config "${RESOLVED[de10nano-kernel]}" | sort) \ - | sed -n 's/^[<>] //p' | sed -e 's/^# \(BR2_[A-Za-z0-9_]*\) is not set$/\1/' -e 's/=.*$//' | sort -u || true) - bad="" - while IFS= read -r sym; do - [ -n "$sym" ] || continue - ok=false - while IFS= read -r pfx; do - [ -n "$pfx" ] || continue - case "$sym" in "$pfx"*) ok=true; break ;; esac - done <<< "$LOCKSTEP_DIVERGENCE_PREFIXES" - [ "$ok" = true ] || bad="$bad $sym" - done <<< "$div" - if [ -n "$bad" ]; then - fail "resolved-level lockstep: de10nano and de10nano-kernel differ on:$bad — outside the designed divergences (LOCKSTEP_DIVERGENCE_PREFIXES in $(basename "$0")). A variant kernel would be built with different toolchain/kernel settings than the image (docs/buildroot-config.md §4)." - else - echo "==> resolved-level lockstep: de10nano and de10nano-kernel agree on every symbol outside the designed divergences ($(printf '%s\n' "$div" | grep -c . ) differing symbols, all allowed)" - fi -elif [ "${#only[@]}" -eq 0 ]; then - fail "resolved-level lockstep: de10nano or de10nano-kernel stack missing from stacks.mk" -fi - -# (f) stage-1 arch lockstep. Each initramfs- fragment restates the -# board's arch/ABI + headers-series lines (a stage-1 stack cannot include -# .fragment itself: that carries the kernel stanza). The restated -# values must be the board's: a CPU-tuning or headers-series change made in -# .fragment and not here would build a stage 1 for a different target -# than the kernel it is embedded in. Text-level, over the stripped fragments, -# and symmetric in what it demands -- every symbol the initramfs- -# fragment sets must be set to the same value in .fragment. (Symbols -# the board sets and stage 1 does not are fine: stage 1 needs no kernel.) -if [ "${#only[@]}" -eq 0 ]; then - for var in $(config_stack_vars); do - case "$var" in INITRAMFS_*) ;; *) continue ;; esac - board_var="${var#INITRAMFS_}" - board_lc=$(config_stack_label "$board_var") - ir_frag="$CONFIG_FRAGMENT_DIR/initramfs-$board_lc.fragment" - board_frag="$CONFIG_FRAGMENT_DIR/$board_lc.fragment" - [ -f "$ir_frag" ] || { fail "stage-1 arch lockstep: $var names no initramfs-$board_lc.fragment"; continue; } - [ -f "$board_frag" ] || { fail "stage-1 arch lockstep: $var has no board fragment $board_lc.fragment to agree with"; continue; } - bad="" - while IFS= read -r line; do - [ -n "$line" ] || continue - sym=$(config_line_symbol "$line") - if ! config_strip_fragment "$board_frag" | grep -qxF -- "$line"; then - bad="$bad $sym" - fi - done < <(config_strip_fragment "$ir_frag") - if [ -n "$bad" ]; then - fail "stage-1 arch lockstep: initramfs-$board_lc.fragment sets$bad differently from (or absent in) $board_lc.fragment -- the stage-1 cpio must be built for the same arch/ABI and headers series as the kernel it is embedded in; change both files in one commit" - else - echo "==> stage-1 arch lockstep: initramfs-$board_lc.fragment agrees with $board_lc.fragment on every symbol it sets ($(config_strip_fragment "$ir_frag" | grep -c .))" - fi - done -fi - -# --- Path consumers outside stacks.mk ----------------------------------------- -# stacks.mk is the source of truth for WHICH fragments exist, but several -# consumers must name fragment files literally and cannot read it: -# GitHub's hashFiles() (action.yml's two dl-cache keys), Renovate's -# managerFilePatterns, the workflow path filter, and the scripts that read a -# pin off one fragment by filename. A rename that updates stacks.mk passes -# (a)-(d) while all of those go stale. Two asserts: -# 1. every `configs/fragments/` token in the code/CI surface -# (Makefile, scripts/, .github/, renovate.json -- not docs, which may -# legitimately name history) must exist in the tree; -# 2. action.yml's hashFiles() list containing de10nano-image must equal the -# DE10NANO stack's files, and the one containing kernel-only must equal -# the DE10NANO_KERNEL stack's (the format('mister_{0}.fragment') item is -# the variant's own fragment and is skipped). -if [ "${#only[@]}" -eq 0 ]; then - action="$ROOT/.github/actions/buildroot-build/action.yml" - while IFS= read -r tok; do - [ -n "$tok" ] || continue - if [ ! -e "$ROOT/$tok" ]; then - fail "path consumer: '$tok' is named in the code/CI surface but does not exist -- a fragment was renamed or moved without updating every consumer ($(grep -rlF -- "$tok" "$ROOT/Makefile" "$ROOT/scripts" "$ROOT/.github" "$ROOT/renovate.json" | sed "s|^$ROOT/||" | tr '\n' ' '))" - fi - done < <(grep -rhoE 'configs/fragments/[A-Za-z0-9_.\\-]+' "$ROOT/Makefile" "$ROOT/scripts" "$ROOT/.github" "$ROOT/renovate.json" \ - | sed -e 's/\\*\././g' -e 's/[.,:;)]*$//' | sort -u) - if [ -f "$action" ]; then - check_hashfiles() { # $1 = stack var, $2 = distinguishing fragment name - local want got - want=$(config_stack_files "$1" | sed "s|^$ROOT/||" | sort | tr '\n' ' ') - got=$(grep -oE "hashFiles\([^)]*configs/fragments/$2\.fragment[^)]*\)" "$action" \ - | grep -oE "'configs/fragments/[^']+'" | tr -d "'" | sort -u | tr '\n' ' ') - if [ -z "$got" ]; then - fail "path consumer: $action has no hashFiles() list naming configs/fragments/$2.fragment -- the dl-cache key for the $(config_stack_label "$1") stack is gone" - elif [ "$got" != "$want" ]; then - fail "path consumer: $action's hashFiles() list for the $(config_stack_label "$1") stack is [$got] but stacks.mk says [$want] -- keep the two in step (hashFiles cannot read stacks.mk)" - fi - } - check_hashfiles DE10NANO de10nano-image - check_hashfiles DE10NANO_KERNEL kernel-only - else - fail "path consumer: $action not found" - fi -fi - -# --- Golden file -------------------------------------------------------------- -if [ "$UPDATE_GOLDEN" = true ]; then - { - echo "# configs/fragments/golden.sha256 — sha256 of each stack's NORMALISED resolved" - echo "# .config for the pinned Buildroot version (scripts/check-config-fragments.sh" - echo "# (d); docs/buildroot-config.md §11). Regenerate ONLY with" - echo "# scripts/check-config-fragments.sh --update-golden" - echo "# and say in the commit message what changed and why. Columns:" - echo "# " - for stack in "${stack_order[@]}"; do - printf '%s %s %s\n' "$BR_VERSION" "$stack" "${NEW_GOLDEN[$stack]}" - done - # Keep other stacks' lines for this version and every other version's - # lines untouched, so a partial run cannot delete what it did not check. - if [ -f "$GOLDEN" ]; then - awk -v v="$BR_VERSION" -v keep=" ${stack_order[*]} " ' - /^#/ { next } - NF == 3 && !($1 == v && index(keep, " " $2 " ")) { print } - ' "$GOLDEN" - fi - } | awk '/^#/ || !seen[$0]++' >"$GOLDEN.tmp" - mv "$GOLDEN.tmp" "$GOLDEN" - echo "==> wrote ${GOLDEN#"$ROOT"/}" -fi - -if [ "$rc" -eq 0 ]; then - [ "$KEEP" = true ] || rm -rf "$CHECK_DIR" - if [ "$missing_golden" -gt 0 ]; then - echo "check-config-fragments: OK with $missing_golden WARNING(s) — ${#stack_order[@]} stack(s) regenerate cleanly from their fragments, but ${GOLDEN#"$ROOT"/} has no lines for Buildroot $BR_VERSION yet (see the warnings above)" - else - echo "check-config-fragments: OK — ${#stack_order[@]} stack(s) regenerate cleanly from their fragments (Buildroot $BR_VERSION)" - fi -else - echo "check-config-fragments: FAILED — resolved configs left under ${CHECK_DIR#"$ROOT"/}/ for inspection" >&2 -fi -exit "$rc" diff --git a/scripts/check-defconfigs.sh b/scripts/check-defconfigs.sh new file mode 100755 index 00000000..5941ea62 --- /dev/null +++ b/scripts/check-defconfigs.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash +# check-defconfigs.sh -- every configs/mister_*_defconfig loads, is canonical, +# and every profile `select` really lands. +# +# What it asserts, per defconfig (the way upstream Buildroot's own CI checks +# its defconfigs: `make _defconfig` then support/scripts/check-dotconfig.py): +# (a) LOADS: `make _defconfig` succeeds in a scratch O= dir. +# (b) EVERY LINE SURVIVES: check-dotconfig.py -- each BR2_ line of the +# committed defconfig is present verbatim in the resolved .config, so a +# symbol that kconfig silently dropped (unmet dependency, retired symbol +# after a Buildroot bump -- the DE25 glibc->uClibc regression of the +# 2026.08 bump was exactly this) FAILS instead of vanishing. +# (c) CANONICAL: `make savedefconfig` reproduces the committed file's BR2_ +# lines exactly (order aside), so the file is Buildroot's own minimal +# form and a review diff is the real change. Comment lines are free. +# (d) PROFILES LAND: for every package/mister-*/Config.in profile the +# defconfig enables, every `select` in it is `=y` in the resolved +# config. kconfig ignores a `select` of a `choice` member SILENTLY +# (the zlib provider was caught this way, ADR 0030 §5.7); this makes +# that a failure. +# (e) SHARED REMAINDER: the symbols both boards must agree on (the old +# `common` layer) carry the same value in every board defconfig. +# +# usage: scripts/check-defconfigs.sh [--keep] [name ...] +# name a defconfig basename without the _defconfig suffix (mister_de10nano); +# default: every configs/mister_*_defconfig. +# Needs the pinned Buildroot tree (make buildroot-unpack); no toolchain. +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +BR_DIR="$ROOT/work/buildroot" +CHECK_DIR="$ROOT/output-config-check" +KEEP=false +rc=0 +fail() { echo "FAIL: $*" >&2; rc=1; } + +only=() +while [ $# -gt 0 ]; do + case "$1" in + --keep) KEEP=true ;; + -h|--help) sed -n '2,30p' "$0"; exit 0 ;; + *) only+=("$1") ;; + esac + shift +done + +[ -f "$BR_DIR/Makefile" ] || make -C "$ROOT" --no-print-directory buildroot-unpack +[ -x "$ROOT/work/.hostshim/install" ] && export PATH="$ROOT/work/.hostshim:$PATH" + +# Symbols every board defconfig must agree on (the retired `common` layer). +SHARED_SYMBOLS="BR2_TOOLCHAIN_BUILDROOT_CXX BR2_DOWNLOAD_FORCE_CHECK_HASHES BR2_LINUX_KERNEL BR2_LINUX_KERNEL_CUSTOM_VERSION BR2_LINUX_KERNEL_DTS_SUPPORT BR2_REPRODUCIBLE BR2_ROOTFS_MERGED_USR" + +names=() +if [ "${#only[@]}" -gt 0 ]; then + names=("${only[@]}") +else + for f in "$ROOT"/configs/mister_*_defconfig; do + n=$(basename "$f" _defconfig); names+=("$n") + done +fi + +br_make() { make -s -C "$BR_DIR" O="$1" BR2_EXTERNAL="$ROOT" BR2_DL_DIR="$ROOT/dl" "${@:2}"; } + +declare -A BOARD_VALUES +for name in "${names[@]}"; do + defconfig="$ROOT/configs/${name}_defconfig" + [ -f "$defconfig" ] || { fail "$name: $defconfig does not exist"; continue; } + odir="$CHECK_DIR/$name"; rm -rf "$odir"; mkdir -p "$odir" + echo "==> $name" + # (a) + if ! br_make "$odir" "${name}_defconfig" >"$odir/load.log" 2>&1; then + fail "$name: 'make ${name}_defconfig' failed -- see ${odir#"$ROOT"/}/load.log"; continue + fi + # (b) + if ! python3 "$BR_DIR/support/scripts/check-dotconfig.py" "$odir/.config" "$defconfig" >"$odir/dotconfig.log" 2>&1; then + fail "$name: a defconfig line did not survive into the resolved .config (kconfig dropped it silently -- unmet dependency, or a symbol retired by a Buildroot bump):"; sed 's/^/ /' "$odir/dotconfig.log" >&2 + else + echo " every defconfig line survives in the resolved .config ($(grep -c -E '^(BR2_[A-Za-z0-9_]+=|# BR2_[A-Za-z0-9_]+ is not set$)' "$defconfig") lines)" + fi + # (c) + if br_make "$odir" savedefconfig BR2_DEFCONFIG="$odir/saved.defconfig" >"$odir/save.log" 2>&1; then + if ! diff <(grep -E '^(BR2_[A-Za-z0-9_]+=|# BR2_[A-Za-z0-9_]+ is not set$)' "$defconfig" | sort) <(grep -E '^(BR2_[A-Za-z0-9_]+=|# BR2_[A-Za-z0-9_]+ is not set$)' "$odir/saved.defconfig" | sort) >"$odir/canonical.diff"; then + fail "$name: not canonical -- 'make savedefconfig' differs from the committed file (< committed, > canonical). Replace the file's BR2_ lines with the canonical set:"; sed 's/^/ /' "$odir/canonical.diff" >&2 + else + echo " canonical (savedefconfig reproduces it)" + fi + else + fail "$name: savedefconfig failed -- see ${odir#"$ROOT"/}/save.log" + fi + # (d) + for cfgin in "$ROOT"/package/mister-*/Config.in; do + sym=$(sed -n 's/^config \(BR2_PACKAGE_MISTER_[A-Z_]*\)$/\1/p' "$cfgin" | head -1) + [ -n "$sym" ] || continue + grep -qx "$sym=y" "$odir/.config" || continue + missing="" + while IFS= read -r sel; do + grep -qx "$sel=y" "$odir/.config" || missing="$missing $sel" + done < <(sed -n 's/^[[:space:]]*select \(BR2_[A-Za-z0-9_]*\)[[:space:]]*$/\1/p' "$cfgin") + if [ -n "$missing" ]; then + fail "$name: profile $sym is enabled but these selects did not land:$missing -- a select of a kconfig 'choice' member is ignored silently (move the line into the defconfig), or the package's own dependencies are unmet on this board (${cfgin#"$ROOT"/})" + else + echo " profile $sym: every select landed ($(grep -c '^[[:space:]]*select ' "$cfgin"))" + fi + done + # collect for (e) + for s in $SHARED_SYMBOLS; do + v=$(grep -E "^$s=|^# $s is not set" "$odir/.config" | head -1 || true) + BOARD_VALUES["$name:$s"]="$v" + done +done + +# (e) +first="" +for name in "${names[@]}"; do + [ -f "$ROOT/configs/${name}_defconfig" ] || continue + case "$name" in mister_installer) continue ;; esac # the installer cpio is not a board image + if [ -z "$first" ]; then first="$name"; continue; fi + for s in $SHARED_SYMBOLS; do + if [ "${BOARD_VALUES[$first:$s]:-}" != "${BOARD_VALUES[$name:$s]:-}" ]; then + fail "shared remainder: $s differs between $first ('${BOARD_VALUES[$first:$s]:-unset}') and $name ('${BOARD_VALUES[$name:$s]:-unset}') -- both boards must agree on it (docs/buildroot-config.md)" + fi + done +done +[ -n "$first" ] && echo "==> shared remainder: $(echo "$SHARED_SYMBOLS" | wc -w) symbols agree across the board defconfigs" + +if [ "$rc" -eq 0 ]; then + [ "$KEEP" = true ] || rm -rf "$CHECK_DIR" + echo "check-defconfigs: OK -- ${#names[@]} defconfig(s) load, are canonical, and every profile select lands" +else + echo "check-defconfigs: FAILED -- resolved configs left under ${CHECK_DIR#"$ROOT"/}/ for inspection" >&2 +fi +exit "$rc" diff --git a/scripts/check-export-tree.sh b/scripts/check-export-tree.sh index 7423c8ee..b3705082 100755 --- a/scripts/check-export-tree.sh +++ b/scripts/check-export-tree.sh @@ -93,16 +93,11 @@ export LC_ALL=C # (shellcheck SC2155), and the rest of scripts/ avoids that pattern. REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" readonly REPO_ROOT -ROOT="$REPO_ROOT" -readonly ROOT -# shellcheck source=scripts/lib/config-stacks.sh -. "$REPO_ROOT/scripts/lib/config-stacks.sh" # The same stack scripts/export-kernel-tree.sh exports, for the same reason: since the # 2026-09 fragment split no single fragment holds both the kernel pin and the package # selections, and reading one file gives a confidently wrong answer. See that script's # STACK_FILES note. -readonly CHECK_STACK=DE10NANO readonly ALIAS_DTB='intel/socfpga/socfpga_cyclone5_de10_nano.dtb' readonly VANILLA_DTB='intel/socfpga/socfpga_cyclone5_de10nano.dtb' @@ -185,16 +180,15 @@ git -C "$export_dir" rev-parse --git-dir >/dev/null 2>&1 || # mapfile, not an unquoted $(...): word-splitting a path list is a bug waiting for the # first directory with a space in it, and shellcheck flags it (SC2046). -mapfile -t stack_files < <(config_stack_files "$CHECK_STACK") -((${#stack_files[@]})) || - die "no ${CHECK_STACK}_FRAGMENTS line in $REPO_ROOT/configs/fragments/stacks.mk" +stack_files=("$REPO_ROOT/configs/mister_de10nano_defconfig") +[ -f "${stack_files[0]}" ] || die "no ${stack_files[0]}" # All stack files in merge order, `tail -1` last: kconfig's own last-definition-wins rule, # so a symbol moved between fragments still resolves to the value the image is built with. pinned_version="$(sed -n 's/^BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="\([^"]*\)".*$/\1/p' \ "${stack_files[@]}" | tail -1)" [[ -n $pinned_version ]] || - die "BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE not set in the $(config_stack_label "$CHECK_STACK") stack" + die "BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE not set in the DE10 defconfig" tag="mister-$pinned_version" git -C "$export_dir" rev-parse --verify --quiet "refs/tags/$tag" >/dev/null || diff --git a/scripts/check-kernel-defconfig-sync.sh b/scripts/check-kernel-defconfig-sync.sh deleted file mode 100755 index 4b337bd1..00000000 --- a/scripts/check-kernel-defconfig-sync.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env bash -# -# check-kernel-defconfig-sync.sh — lockstep assertion between the kernel-only -# base configuration and the main image configuration (docs/rt-beta-kernel.md -# §2, ADR 0021 as amended 2026-07-18, docs/buildroot-config.md §1/§4). -# -# HISTORY, because the name predates the layout. Until the fragment split -# (2026-09, docs/buildroot-config.md) configs/mister_kernel_defconfig was a -# hand-mirrored COPY of configs/mister_de10nano_defconfig's toolchain and -# kernel stanzas, and this script compared the two FILES. Both files are gone. -# Today the shipped image and the kernel-only base are two STACKS of -# fragments (configs/fragments/stacks.mk: `common de10nano de10nano-image` -# and `common de10nano kernel-only`) that share the toolchain/kernel -# fragments BY CONSTRUCTION — so the value-drift this script was written for -# can no longer happen by forgetting to mirror an edit. What CAN still happen, -# and what this script now guards, is a toolchain/kernel symbol landing in a -# fragment only ONE stack uses (BR2_KERNEL_HEADERS_6_19=y added to -# de10nano-image.fragment, say): kconfig would accept it, the image and the -# variant kernels would be built by different toolchains, and nothing at build -# time would say so. The comparison is therefore now done over the MERGED -# TEXT of each stack, exactly as it was over the two files, plus one new -# structural assert (0). It stays cheap enough to run before any cache or -# build work: it reads a handful of tracked files and nothing else. -# -# What it asserts, over the merged (comment-stripped) text of the two stacks: -# 0. STRUCTURE: every symbol in a toolchain/kernel family (the BOARD row's -# arch families + the common families + the kernel/patch families named -# below) is defined in a fragment BOTH stacks use. That is the -# "shared by construction" property made checkable. -# 1. Every BR2_ symbol DEFINED IN BOTH stacks carries the identical value. -# Symbols defined in only one stack are fine by design (the kernel stack -# has no packages; the image stack has no BR2_INIT_NONE). -# 2. Sentinel presence: the kernel stack still carries the symbols no -# rewrite of it may lose (arch, CPU, headers series, toolchain C++) — -# the same fail-loud-on-degenerate-input posture as the toolchain -# fingerprint in .github/actions/buildroot-build/action.yml. -# 3. Family name-set equality: kconfig CHOICE symbols encode their value in -# the symbol NAME (BR2_KERNEL_HEADERS_6_18 vs _6_19, BR2_cortex_a9 vs -# _a7), so a headers or CPU bump on one side DROPS the old name and adds a -# new one — no symbol exists in both to disagree, and check 1 alone -# provably passes on exactly that drift. For each family such a choice -# lives in, the set of defined symbol names must therefore be identical. -# -# Comments are stripped with the SAME sed idiom as that action's fingerprint -# step. That stripping also drops `# BR2_FOO is not set` lines — NOT because -# they are comments to kconfig (they are not: `conf` parses them as an -# explicit =n, and kernel-only.fragment's `# BR2_PACKAGE_BUSYBOX is not set` -# is LOAD-BEARING exactly that way — do not "clean them up") — but because a -# symbol deliberately =n in one stack while set in the other is a DESIGNED -# divergence here (the kernel-only stack suppresses what the image wants, -# BusyBox being the live example), so comparing them would make this check -# cry wolf; the sentinel and family-set asserts guard against a stanza -# vanishing or drifting by rename instead. Values are split on the FIRST '=' -# only: several values legitimately contain '=' (the ext2 MKFS_OPTIONS). -# -# The RESOLVED-config half of the same guarantee (that the two stacks still -# agree after olddefconfig, package-driven selects included) lives in -# scripts/check-config-fragments.sh, which needs a Buildroot tree and so runs -# later in CI. This script is the one that runs before any cache restore. -# -# Where this runs: -# * .github/actions/buildroot-build — for every variant != main, before any -# cache restore, so drift dies in seconds instead of 2 hours in. -# * build.yml's `lint-config` job — next to lint-kernel-patches.sh and -# check-config-fragments.sh. -# * By hand: scripts/check-kernel-defconfig-sync.sh (no arguments). -# BOARD= (or a single positional ) selects which board's -# EXPECTATION ROW the asserts below use; it does NOT change which two -# stacks are compared. The compared pair is fixed to the DE10 stacks -# named in stacks.mk (there is no DE25 kernel-only stack yet), so -# BOARD=de25nano today asserts aarch64 expectations against the DE10 -# pair and fails, as it should: it is a table self-test, not a DE25 -# lockstep check. -# -# BOARD selects the per-board sentinel/family tables in scripts/lib/ -# board-expectations.sh (docs/de25-readiness-ledger.md §5.2) — an optional -# $1 wins over the BOARD env var if both are given. Defaults to "de10nano"; -# none of the call sites above pass either today. An unrecognized BOARD is a -# usage error (exit 2 below), never a silent fallback to an existing row. -# -# Exit: 0 = in lockstep; 1 = drift, a one-sided choice bump, a missing -# sentinel, or a family symbol in a one-stack fragment; 2 = usage/IO error -# (including an unrecognized BOARD). - -set -euo pipefail -export LC_ALL=C - -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" - -# shellcheck source=scripts/lib/board-expectations.sh -. "$ROOT/scripts/lib/board-expectations.sh" -# shellcheck source=scripts/lib/config-stacks.sh -. "$ROOT/scripts/lib/config-stacks.sh" - -# The two stacks compared. Fixed on purpose (see the header); the fragment -# lists themselves come from stacks.mk, never from here. -MAIN_STACK=DE10NANO -KERNEL_STACK=DE10NANO_KERNEL - -# Families whose symbols must live in a fragment shared by both stacks, on -# top of the BOARD arch row and the common row from board-expectations.sh: -# the kernel stanza and the patch/hash registry. BR2_LINUX_KERNEL covers -# every BR2_LINUX_KERNEL_* symbol (version, patch dir, config file, image -# format, DTS) — any one of them differing between the image and a variant -# kernel is exactly the "built from different sources" failure ADR 0021 -# describes. -SHARED_ONLY_FAMILIES="BR2_LINUX_KERNEL BR2_GLOBAL_PATCH_DIR" - -# $1 (if given) wins over the BOARD env var; both fall back to "de10nano". -BOARD="${1:-${BOARD:-de10nano}}" -# Both tables are checked, not just the first one the script happens to read: -# a board row added to one table and forgotten in the other would otherwise -# surface as a bare `set -u` unbound-variable trace at the later expansion -# instead of a usage error naming the board and the table. -for table in BOARD_ARCH_SENTINELS BOARD_ARCH_FAMILIES; do - if ! declare -n _tbl="$table" 2>/dev/null || [ -z "${_tbl[$BOARD]+set}" ]; then - echo "check-kernel-defconfig-sync: FATAL: unknown board '$BOARD' -- scripts/lib/board-expectations.sh's $table has no row for it. Known boards: ${!BOARD_ARCH_SENTINELS[*]}" >&2 - exit 2 - fi -done -unset -n _tbl - -[ -f "$CONFIG_STACKS_MK" ] || { echo "check-kernel-defconfig-sync: FATAL: missing $CONFIG_STACKS_MK" >&2; exit 2; } - -mapfile -t main_files < <(config_stack_files "$MAIN_STACK") -mapfile -t kernel_files < <(config_stack_files "$KERNEL_STACK") -if [ "${#main_files[@]}" -eq 0 ] || [ "${#kernel_files[@]}" -eq 0 ]; then - echo "check-kernel-defconfig-sync: FATAL: ${MAIN_STACK}_FRAGMENTS or ${KERNEL_STACK}_FRAGMENTS is empty/missing in configs/fragments/stacks.mk" >&2 - exit 2 -fi -for f in "${main_files[@]}" "${kernel_files[@]}"; do - [ -f "$f" ] || { echo "check-kernel-defconfig-sync: FATAL: missing $f (named in configs/fragments/stacks.mk)" >&2; exit 2; } -done - -# Strip comments/blank lines, keep only BR2_ symbol assignments. Same idiom as -# the toolchain-fingerprint step (action.yml): a '#' that begins a line or -# follows whitespace starts a comment; no legitimate value carries a bare '#'. -strip_config() { - sed -e 's/^[[:space:]]*#.*$//' -e 's/[[:space:]]\+#.*$//' -e 's/[[:space:]]*$//' "$@" \ - | grep '^BR2_' || true -} - -main_stripped=$(strip_config "${main_files[@]}") -kernel_stripped=$(strip_config "${kernel_files[@]}") - -rc=0 - -# --- 0. Structure: family symbols only in fragments BOTH stacks use --------- -# Shared = present in both lists (by path). A family symbol found in any -# other fragment is a toolchain/kernel decision one stack would not see. -shared_files=() -for f in "${main_files[@]}"; do - for g in "${kernel_files[@]}"; do - [ "$f" = "$g" ] && shared_files+=("$f") - done -done -if [ "${#shared_files[@]}" -eq 0 ]; then - echo "FAIL: the $(config_stack_label "$MAIN_STACK") and $(config_stack_label "$KERNEL_STACK") stacks share no fragment at all --" >&2 - echo " the kernel-only base can no longer be in lockstep with the image by construction." >&2 - rc=1 -fi -is_shared() { local s; for s in "${shared_files[@]}"; do [ "$s" = "$1" ] && return 0; done; return 1; } -# shellcheck disable=SC2086 # word splitting over the merged family list is intended -for f in "${main_files[@]}" "${kernel_files[@]}"; do - is_shared "$f" && continue - for family in ${BOARD_ARCH_FAMILIES[$BOARD]} $BOARD_COMMON_FAMILIES $SHARED_ONLY_FAMILIES; do - hits=$(strip_config "$f" | sed -n "s/^\(${family}[A-Za-z0-9_]*\)=.*/\1/p") - [ -n "$hits" ] || continue - echo "FAIL: ${f#"$ROOT"/} defines toolchain/kernel symbol(s) $(printf '%s' "$hits" | tr '\n' ' ')" >&2 - echo " but only ONE of the two stacks uses that fragment. Such symbols belong in a" >&2 - echo " fragment both configs/fragments/stacks.mk stacks list (common or de10nano)," >&2 - echo " or the image and the variant kernels are built from different settings." >&2 - rc=1 - done -done - -# --- 2. Sentinels: a degenerate kernel stack must not pass ------------------ -# (an empty or mis-stripped stack would trivially satisfy the "no symbol -# disagrees" check below — same reasoning as the fingerprint's BR2_arm assert). -# Merge order is BOARD's arch row first, then the common row — this -# reproduces, for BOARD=de10nano, the exact former literal list in the same -# order (scripts/lib/board-expectations.sh, §5.3). -# shellcheck disable=SC2086 # word splitting over the merged symbol list is intended -for must in ${BOARD_ARCH_SENTINELS[$BOARD]} $BOARD_COMMON_SENTINELS; do - if ! printf '%s\n' "$kernel_stripped" | grep -q "^${must}"; then - echo "FAIL: sentinel '${must}' is absent from the $(config_stack_label "$KERNEL_STACK") stack --" >&2 - echo " the kernel-only toolchain stanza has been lost or renamed; see" >&2 - echo " configs/fragments/de10nano.fragment and docs/buildroot-config.md §3." >&2 - rc=1 - fi -done - -# --- 1. Value comparison over the symbols both stacks define --------------- -# awk keyed on the symbol name (text before the FIRST '='), values compared -# verbatim. Output: one "SYMBOL | main-value | kernel-value" line per mismatch. -mismatches=$(awk ' - BEGIN { FS = "" } - { - eq = index($0, "=") - if (eq == 0) next - sym = substr($0, 1, eq - 1) - val = substr($0, eq + 1) - if (NR == FNR) { main[sym] = val; next } - if ((sym in main) && main[sym] != val) - printf "%s\n main: %s=%s\n kernel: %s=%s\n", sym, sym, main[sym], sym, val - } -' <(printf '%s\n' "$main_stripped") <(printf '%s\n' "$kernel_stripped")) - -if [ -n "$mismatches" ]; then - echo "FAIL: the $(config_stack_label "$KERNEL_STACK") stack disagrees with the $(config_stack_label "$MAIN_STACK") stack." >&2 - echo "Every BR2_ symbol defined in BOTH stacks must carry the identical value:" >&2 - printf '%s\n' "$mismatches" >&2 - echo "" >&2 - echo "A symbol both stacks need belongs in a SHARED fragment (common or de10nano), defined" >&2 - echo "once -- see configs/fragments/stacks.mk and docs/buildroot-config.md §1." >&2 - rc=1 -fi - -# --- 3. Family name-set comparison: choice symbols drift by RENAME, not value - -# The comparison above is blind to a kconfig CHOICE bump (header §3): switch the -# image stack to BR2_KERNEL_HEADERS_6_19=y or BR2_cortex_a7=y and the old -# name simply stops being defined in both — zero shared symbols disagree, -# and both scenarios were demonstrated to sail through check 1 alone. So for -# each family a choice lives in, assert the SET of defined symbol names matches -# exactly. The designed one-sided symbols (BR2_INIT_NONE, packages, rootfs -# types) share none of these prefixes, so they stay exempt. Both-sides-empty -# degenerates to equal sets — that hole is what the presence sentinels above -# close. -# shellcheck disable=SC2086 # word splitting over the merged symbol list is intended -for family in ${BOARD_ARCH_FAMILIES[$BOARD]} $BOARD_COMMON_FAMILIES; do - main_names=$(printf '%s\n' "$main_stripped" | sed -n "s/^\(${family}[A-Za-z0-9_]*\)=.*/\1/p" | sort) - kernel_names=$(printf '%s\n' "$kernel_stripped" | sed -n "s/^\(${family}[A-Za-z0-9_]*\)=.*/\1/p" | sort) - if [ "$main_names" != "$kernel_names" ]; then - echo "FAIL: the ${family}* symbol-name sets differ between the two stacks." >&2 - echo "A choice symbol carries its value in its NAME, so a bump/rename on one side" >&2 - echo "is invisible to the shared-value comparison — define it once, in a shared fragment:" >&2 - echo " main: $(printf '%s' "${main_names:-}" | tr '\n' ' ')" >&2 - echo " kernel: $(printf '%s' "${kernel_names:-}" | tr '\n' ' ')" >&2 - rc=1 - fi -done - -shared=$(awk ' - BEGIN { FS = "" } - { - eq = index($0, "=") - if (eq == 0) next - sym = substr($0, 1, eq - 1) - if (NR == FNR) { main[sym] = 1; next } - if (sym in main) n++ - } - END { print n + 0 } -' <(printf '%s\n' "$main_stripped") <(printf '%s\n' "$kernel_stripped")) - -if [ "$rc" -eq 0 ]; then - echo "check-kernel-defconfig-sync: OK — $(config_stack_label "$MAIN_STACK") and $(config_stack_label "$KERNEL_STACK") stacks share ${#shared_files[@]} fragment(s); $shared shared BR2_ symbol(s) agree, all sentinels present, choice-family name sets match, every toolchain/kernel family symbol lives in a shared fragment." -fi -exit "$rc" diff --git a/scripts/check-kernel-fragment-noop.sh b/scripts/check-kernel-fragment-noop.sh deleted file mode 100755 index 5837eea1..00000000 --- a/scripts/check-kernel-fragment-noop.sh +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env bash -# -# check-kernel-fragment-noop.sh — prove that the shared MiSTer kernel fragment -# changes NOTHING on the board whose kernel config it was extracted from. -# -# WHY THIS EXISTS -# --------------- -# board/mister/common/linux-mister.fragment is the arch-neutral MiSTer driver -# and feature set: input/HID, Bluetooth, Wi-Fi, USB, sound, filesystems, -# netfilter, LEDs. It was extracted from the DE10-Nano's kernel config and is -# consumed today by the DE25-Nano, which layers it on top of its own minimal -# arm64 base (board/mister/de25nano/linux.config). -# -# The whole value of that arrangement rests on ONE claim: every line in the -# fragment is byte-identical to the corresponding line in the DE10's resolved -# kernel config. That is what makes "both boards have the same driver support" -# checkable, and it is what will let the DE10 adopt the fragment later with a -# provable zero-delta instead of a leap of faith. -# -# A claim that is only asserted in a comment decays. This script is the claim, -# executed. It is designed to be run against a *configured kernel build tree*, -# so it belongs AFTER a kernel build, not in a lint job (see docs/ci.md notes -# in docs/de25-kernel-config.md §10). -# -# HOW IT WORKS — and why it runs kconfig twice -# -------------------------------------------- -# Naively one would merge the fragment onto the tree's .config, resolve, and -# diff against the tree's .config. That has a false-positive: resolving a config -# outside Buildroot's environment cannot reproduce toolchain-derived string -# symbols exactly (CONFIG_CC_VERSION_TEXT comes from `$(CC) --version` run -# through kconfig's $(shell,...) and comes back empty here). So instead: -# -# CONTROL : tree/.config -> olddefconfig -> control/.config -# TEST : tree/.config + fragment (merge) -> olddefconfig -> test/.config -# -# Both runs use exactly the same kconfig binary, srctree, ARCH and compiler, so -# every environment-derived difference cancels. The fragment is a no-op if and -# only if control/.config and test/.config are byte-identical. -# -# It also fails on any merge_config.sh "is redefined by fragment" line. Note the -# gotcha those lines carry: merge_config resolves a symbol's new value with -# `grep -w CONFIG_ `, which matches PROSE as well as settings, so -# a comment in the fragment that names a symbol the fragment also sets produces -# a FALSE redefinition warning. Rule 5 in the fragment's header forbids that; -# this check is what enforces it. -# -# USAGE -# scripts/check-kernel-fragment-noop.sh [--tree DIR] [--fragment FILE] [--keep] -# -# With no arguments it binds to THE kernel tree under output/build/linux-[0-9]* -# — the same "never the first glob match" discipline the Makefile's `rt` recipe -# uses: `linux-[0-9]*` so linux-firmware-*/linux-headers-*/linux-pam-* cannot -# match, zero trees is fatal, and MORE than one tree is fatal too, because a -# stale sibling left by a kernel bump sorts first often enough that picking one -# blindly would validate the wrong kernel and false-pass. -# -# Exit codes: 0 = fragment is a no-op. 1 = drift, or the check could not run. -# -set -euo pipefail - -PROG=${0##*/} -REPO_ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) - -TREE="" -FRAGMENT="$REPO_ROOT/board/mister/common/linux-mister.fragment" -KEEP=0 - -die() { printf '%s: FATAL: %s\n' "$PROG" "$1" >&2; exit 1; } - -usage() { - cat >&2 <<-EOF - usage: $PROG [--tree DIR] [--fragment FILE] [--keep] - - --tree DIR configured kernel build tree to check against. - Default: the unique output/build/linux-[0-9]*/ . - --fragment FILE kernel config fragment to prove is a no-op. - Default: board/mister/common/linux-mister.fragment - --keep keep the scratch directory (prints its path). - EOF - exit 1 -} - -while [ $# -gt 0 ]; do - case "$1" in - --tree) [ $# -ge 2 ] || usage; TREE=$2; shift 2 ;; - --fragment) [ $# -ge 2 ] || usage; FRAGMENT=$2; shift 2 ;; - --keep) KEEP=1; shift ;; - -h|--help) usage ;; - *) printf '%s: unknown argument: %s\n' "$PROG" "$1" >&2; usage ;; - esac -done - -[ -f "$FRAGMENT" ] || die "fragment does not exist: $FRAGMENT" -# Canonicalise now: merge_config.sh runs after a `cd` into the scratch dir, -# where a relative --fragment path would no longer resolve. -FRAGMENT=$(readlink -f "$FRAGMENT") - -# --- bind to THE kernel tree, fail closed on zero or many -------------------- -if [ -z "$TREE" ]; then - # shellcheck disable=SC2207 # paths here are Buildroot-generated, no spaces - trees=($(ls -d "$REPO_ROOT"/output/build/linux-[0-9]*/ 2>/dev/null || true)) - if [ ${#trees[@]} -eq 0 ]; then - printf '%s: FATAL: no kernel tree under %s\n' \ - "$PROG" "$REPO_ROOT/output/build/linux-[0-9]*/" >&2 - printf ' This check needs a CONFIGURED kernel tree; it cannot run on a\n' >&2 - printf ' clean checkout. Build the DE10 image first (make all), or pass\n' >&2 - printf ' --tree DIR.\n' >&2 - exit 1 - elif [ ${#trees[@]} -gt 1 ]; then - printf '%s: FATAL: %d kernel trees under %s/output/build/ -- cannot tell which\n' \ - "$PROG" "${#trees[@]}" "$REPO_ROOT" >&2 - printf ' one is current:\n' >&2 - printf ' %s\n' "${trees[@]}" >&2 - printf ' A stale sibling appears when the kernel version is bumped without\n' >&2 - printf ' discarding the old tree; validating its .config would prove the\n' >&2 - printf ' fragment against the WRONG kernel. Remove the stale tree, or pass\n' >&2 - printf ' --tree DIR explicitly.\n' >&2 - exit 1 - fi - TREE=${trees[0]} -fi -TREE=${TREE%/} -[ -d "$TREE" ] || die "not a directory: $TREE" -# Absolute, because both kconfig runs below execute with cwd inside the scratch -# directory -- a relative --tree would silently resolve to nothing there. -TREE=$(cd -- "$TREE" && pwd) - -CONF="$TREE/scripts/kconfig/conf" -MERGE="$TREE/scripts/kconfig/merge_config.sh" -BASE_CONFIG="$TREE/.config" - -[ -f "$BASE_CONFIG" ] || die "$TREE has no .config -- the tree is not configured." -[ -x "$CONF" ] || die "$CONF is missing or not executable -- the tree was never built." -[ -x "$MERGE" ] || die "$MERGE is missing." - -# --- derive ARCH and version from the .config's generated header ------------- -# e.g. "# Linux/arm 6.18.48 Kernel Configuration" -header=$(sed -n 's|^# Linux/\([a-z0-9_]*\) \([^ ]*\) Kernel Configuration$|\1 \2|p' \ - "$BASE_CONFIG" | head -n1) -[ -n "$header" ] || die "cannot read the arch/version header from $BASE_CONFIG" -ARCH=${header% *} -KERNELVERSION=${header#* } - -# --- find the cross compiler the tree was built with, if we can -------------- -# Only used so that toolchain-derived symbols resolve the same way in BOTH -# runs; since the two runs are compared to each other, a fallback is harmless. -CC_BIN=${CC:-} -LD_BIN=${LD:-} -if [ -z "$CC_BIN" ]; then - host_bin=$(cd -- "$TREE/../.." 2>/dev/null && pwd)/host/bin - for candidate in "$host_bin"/*-linux-*-gcc; do - [ -x "$candidate" ] || continue - CC_BIN=$candidate - LD_BIN=${candidate%-gcc}-ld - break - done -fi -[ -n "$CC_BIN" ] || CC_BIN=gcc -[ -n "$LD_BIN" ] || LD_BIN=ld - -WORK=$(mktemp -d -t kfragnoop.XXXXXXXX) -# shellcheck disable=SC2329 # invoked indirectly, by the EXIT trap below -cleanup() { [ "$KEEP" -eq 1 ] || rm -rf "$WORK"; } -trap cleanup EXIT -mkdir -p "$WORK/control" "$WORK/test" - -export ARCH SRCARCH="$ARCH" KERNELVERSION -# srctree is how kconfig's `conf` finds the top-level Kconfig (and every -# `source`d file) when run from a directory other than the kernel tree: -# zconf_fopen() retries a relative path under $srctree. That is why the two -# olddefconfig runs below can `cd` into scratch dirs that contain only a -# .config and still name a bare "Kconfig". -export srctree="$TREE" -export CC="$CC_BIN" LD="$LD_BIN" -export HOSTCC=${HOSTCC:-gcc} HOSTCXX=${HOSTCXX:-g++} - -printf '%s: tree %s\n' "$PROG" "$TREE" -printf '%s: arch %s (kernel %s)\n' "$PROG" "$ARCH" "$KERNELVERSION" -printf '%s: fragment %s\n' "$PROG" "$FRAGMENT" -printf '\n' - -# --- CONTROL: resolve the tree's own config, untouched ----------------------- -cp -- "$BASE_CONFIG" "$WORK/control/.config" -( cd "$WORK/control" && "$CONF" --olddefconfig Kconfig ) > "$WORK/control.log" 2>&1 \ - || { cat "$WORK/control.log" >&2; die "control olddefconfig failed"; } - -# --- TEST: same config with the fragment merged in --------------------------- -cp -- "$BASE_CONFIG" "$WORK/test/base.config" -printf '===== merge_config.sh -m =====\n' -( cd "$WORK/test" && "$MERGE" -m -O "$WORK/test" base.config "$FRAGMENT" ) \ - > "$WORK/merge.log" 2>&1 || { cat "$WORK/merge.log" >&2; die "merge_config.sh failed"; } -cat "$WORK/merge.log" -printf '===== end merge_config.sh =====\n\n' - -( cd "$WORK/test" && "$CONF" --olddefconfig Kconfig ) > "$WORK/test.log" 2>&1 \ - || { cat "$WORK/test.log" >&2; die "test olddefconfig failed"; } - -status=0 - -if grep -q 'is redefined by fragment' "$WORK/merge.log"; then - printf '%s: FAIL: merge_config.sh reported a REDEFINITION.\n' "$PROG" >&2 - grep -n 'is redefined by fragment' "$WORK/merge.log" >&2 - printf ' Either the fragment genuinely disagrees with %s,\n' "$BASE_CONFIG" >&2 - printf ' or a COMMENT in the fragment names a symbol the fragment also sets\n' >&2 - printf ' (merge_config greps prose too -- rule 5 in the fragment header).\n' >&2 - status=1 -fi - -if ! diff -u "$WORK/control/.config" "$WORK/test/.config" > "$WORK/drift.diff"; then - printf '%s: FAIL: the fragment CHANGES the resolved config of this tree.\n' "$PROG" >&2 - printf ' Every line of %s must be\n' "$FRAGMENT" >&2 - printf ' byte-identical to the corresponding line in this board resolved\n' >&2 - printf ' config, or the two boards no longer share one driver set.\n' >&2 - printf ' --- control (tree as built) vs test (tree + fragment) ---\n' >&2 - cat "$WORK/drift.diff" >&2 - status=1 -fi - -if [ "$status" -eq 0 ]; then - printf '%s: PASS: fragment is a no-op on %s\n' "$PROG" "$TREE" - printf '%s: zero redefinitions, resolved config identical.\n' "$PROG" -fi - -if [ "$KEEP" -eq 1 ]; then - printf '%s: scratch kept at %s\n' "$PROG" "$WORK" -fi - -exit "$status" diff --git a/scripts/ci-tests.sh b/scripts/ci-tests.sh index c7e30ede..7ae655c0 100755 --- a/scripts/ci-tests.sh +++ b/scripts/ci-tests.sh @@ -21,11 +21,10 @@ # must run, qemu-user against output/target as the sysroot. # # Usage: scripts/ci-tests.sh [build-dir] -# build-dir defaults to "output" (repo-root-relative). Only the image-contract -# scripts and the Phase-3 artifact checks honor an override -- the Makefile-based -# initramfs checks and scripts/test-initramfs.sh use Buildroot's own fixed -# output/ + output-initramfs/ layout (Makefile: OUTPUT_DIR := $(CURDIR)/output, -# not parameterized) and are SKIPPED with an explicit reason if build-dir differs. +# build-dir defaults to "output" (repo-root-relative). The image-contract +# scripts and the artifact checks honor an override; scripts/test-initramfs.sh +# reads the stage-1 cpio from the fixed output/images/ path (the package +# installs it there). # # Output: one PASS/FAIL/SKIP line per check (grouped by phase/subsystem), full # detail from called scripts shown inline, then a summary. SKIP never fails the @@ -70,8 +69,6 @@ case "$BUILD_DIR_ARG" in /*) BUILD_DIR="$BUILD_DIR_ARG" ;; *) BUILD_DIR="$ROOT/$BUILD_DIR_ARG" ;; esac -IS_DEFAULT_OUTPUT=0 -[ "$BUILD_DIR" = "$ROOT/output" ] && IS_DEFAULT_OUTPUT=1 IMAGES="$BUILD_DIR/images" TARGET="$BUILD_DIR/target" @@ -84,7 +81,7 @@ LINUX_IMG="$IMAGES/linux.img" # rootfs may also carry kernel-VARIANT trees (e.g. the RT beta's 7.2.0 — that # example read "7.2.0-rc3*" until the pin reached 7.2 final on 2026-08-17; it # is illustrative either way, nothing here globs on it, -# merged in via work/extra-modules-overlay), and those are deliberately out of +# built by package/linux-rt in the same tree), and those are deliberately out of # scope here — their depmod health is asserted by check-abi.sh A-25 (every # tree), and their presence in CI by build.yml's merged-kver assert. Do not # "fix" these checks to glob across all trees; they would then pass on the @@ -107,10 +104,10 @@ LINUX_IMG="$IMAGES/linux.img" # symbol verbatim would otherwise match too -- the exact bug fixed in the # hash-sync workflow (#42). KVER=$(sed -n 's/^BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="\([^"]*\)".*$/\1/p' \ - "$ROOT/configs/fragments/de10nano.fragment" | tail -1) + "$ROOT/configs/mister_de10nano_defconfig" | tail -1) if [ -z "$KVER" ]; then echo "FATAL: could not read BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE from" >&2 - echo " $ROOT/configs/fragments/de10nano.fragment" >&2 + echo " $ROOT/configs/mister_de10nano_defconfig" >&2 exit 1 fi @@ -265,23 +262,28 @@ run_script "check-size-budget.sh" "$ROOT/scripts/check-size-budget.sh" "$LINUX_I section "Initramfs (P1.10-P1.12, A7)" # ============================================================================= -if [ "$IS_DEFAULT_OUTPUT" -eq 1 ]; then - printf -- '--- check-initramfs (Makefile: main kernel .config has CONFIG_BLK_DEV_INITRD / CONFIG_INITRAMFS_SOURCE) ---\n' - if ( cd "$ROOT" && make --no-print-directory check-initramfs ); then - pass "check-initramfs (main kernel config)" - else - fail "check-initramfs (main kernel config)" - fi - - printf -- '--- initramfs-verify (Makefile: required BusyBox applets + /init + /dev/console present in the cpio, ash -n parses /init) ---\n' - if ( cd "$ROOT" && make --no-print-directory initramfs-verify ); then - pass "initramfs-verify (cpio applet/structure check)" - else - fail "initramfs-verify (cpio applet/structure check)" - fi -else - skip "check-initramfs (main kernel config)" "Makefile's OUTPUT_DIR is fixed to ./output, not parameterized; build dir here is $BUILD_DIR" - skip "initramfs-verify (cpio applet/structure check)" "same fixed-OUTPUT_DIR reason" +# Since ADR 0030 the cpio is package/mister-initramfs (images/mister-initramfs.cpio) +# and the kernel embeds it through linux/linux-ext-mister-initramfs.mk, which +# fails the kernel's kconfig-fixup if the cpio is absent. What is left to assert +# here is the ARTIFACT: the built kernel config really names that cpio (I1/I2), +# and the cpio is the one next to it. verify.sh's applet/structure checks ran +# inside the package build and failed it if anything was wrong. +INITRAMFS_CPIO="$BUILD_DIR/images/mister-initramfs.cpio" +printf -- '--- initramfs embedding (kernel .config: CONFIG_BLK_DEV_INITRD=y, CONFIG_INITRAMFS_SOURCE=images/mister-initramfs.cpio) ---\n' +# The main kernel tree, uniqueness-guarded like every other kernel-tree glob +# in this suite (linux-[0-9]* excludes linux-firmware-*/linux-headers-*). +_ir_kc=("$BUILD_DIR"/build/linux-[0-9]*/.config) +KCFG="${_ir_kc[0]}" +if [ "${#_ir_kc[@]}" -ne 1 ] || [ ! -f "$KCFG" ]; then + fail "initramfs embedding" "expected exactly one $BUILD_DIR/build/linux-[0-9]*/.config, found ${#_ir_kc[@]}" +elif [ ! -f "$INITRAMFS_CPIO" ]; then + fail "initramfs embedding" "no $INITRAMFS_CPIO -- package/mister-initramfs did not build" +elif ! grep -qx 'CONFIG_BLK_DEV_INITRD=y' "$KCFG"; then + fail "initramfs embedding" "CONFIG_BLK_DEV_INITRD is not y in $KCFG" +elif ! grep -q "^CONFIG_INITRAMFS_SOURCE=\".*/mister-initramfs.cpio\"" "$KCFG"; then + fail "initramfs embedding" "CONFIG_INITRAMFS_SOURCE in $KCFG does not name mister-initramfs.cpio: $(grep '^CONFIG_INITRAMFS_SOURCE=' "$KCFG" || echo '(unset -- the kernel has NO initramfs and will panic on the FAT root)')" +else + pass "initramfs embedding ($(grep '^CONFIG_INITRAMFS_SOURCE=' "$KCFG"), cpio $(stat -c %s "$INITRAMFS_CPIO") bytes)" fi if [ "${CI_TESTS_SKIP_QEMU_SYSTEM:-0}" = "1" ]; then @@ -298,23 +300,39 @@ else fi fi -# The DE25-Nano's stage 1: the SAME /init built for aarch64 (`make -# de25-initramfs`, ADR 0029 D11), checked the same two ways -- the Makefile's -# structural cpio assertions and the eight QEMU cases, on qemu-system-aarch64. -# Gated on the cpio EXISTING rather than on a board flag: this suite runs -# against a DE10 image, and a tree that has never built the DE25 stage 1 has -# nothing to check here -- but one that has must not skip it silently. -DE25_INITRAMFS_CPIO="$ROOT/output-initramfs-de25/images/rootfs.cpio" -if [ ! -f "$DE25_INITRAMFS_CPIO" ]; then - skip "de25-initramfs-verify (aarch64 cpio applet/structure check)" "no $DE25_INITRAMFS_CPIO -- 'make de25-initramfs' not run in this tree" - skip "test-initramfs.sh --board de25nano (aarch64 QEMU boot test, 8 cases)" "same: no DE25 stage-1 cpio built" -else - printf -- '--- de25-initramfs-verify (Makefile: the DE10 initramfs-verify assertions, on the aarch64 cpio under qemu-aarch64) ---\n' - if ( cd "$ROOT" && make --no-print-directory de25-initramfs-verify ); then - pass "de25-initramfs-verify (aarch64 cpio applet/structure check)" +# The same /init on the DE10's RT kernel series (7.2.y): the three cases that +# exercise the exfat driver, because 7.x exfat is iomap-based and board patch +# 0031 (Samsung-format symlinks, ADR 0019) is a separate re-anchored copy +# there (linux-patches-beta/). Its only other executions are aarch64 (the +# DE25 leg); the DE10-Nano runs it as 32-bit ARM, and the first field `ln -s` +# on an RT-booted board Oopsed (2026-09-11) on the pre-rewrite copy. Gated +# like the DE10 leg; a second multi_v7 kernel build, cached under +# work/test-initramfs-rt*. +if [ "${CI_TESTS_SKIP_QEMU_SYSTEM:-0}" = "1" ]; then + skip "test-initramfs.sh --kernel rt (32-bit QEMU boot test on the RT kernel, exfat cases)" "CI_TESTS_SKIP_QEMU_SYSTEM=1" +elif ! have qemu-system-arm; then + skip "test-initramfs.sh --kernel rt (32-bit QEMU boot test on the RT kernel, exfat cases)" "qemu-system-arm not found on PATH" +elif ! grep -q '^BR2_PACKAGE_LINUX_RT=y$' "$ROOT/configs/mister_de10nano_defconfig"; then + skip "test-initramfs.sh --kernel rt (32-bit QEMU boot test on the RT kernel, exfat cases)" "BR2_PACKAGE_LINUX_RT is not enabled in configs/mister_de10nano_defconfig" +else + printf -- '--- test-initramfs.sh --kernel rt: exfat fsck-request symlink ---\n' + printf ' (builds/reuses a second QEMU test kernel at the RT pin -- can take several minutes)\n' + if "$ROOT/scripts/test-initramfs.sh" --kernel rt exfat fsck-request symlink; then + pass "test-initramfs.sh --kernel rt (32-bit QEMU boot test on the RT kernel, 3 exfat cases)" else - fail "de25-initramfs-verify (aarch64 cpio applet/structure check)" + fail "test-initramfs.sh --kernel rt (32-bit QEMU boot test on the RT kernel, 3 exfat cases)" "one or more of the 3 cases failed -- see output above" fi +fi + +# The DE25-Nano's stage 1: the SAME package built for aarch64 by the DE25 +# configuration -- once its stack enables BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS +# (ADR 0029 D11 keeps that off until a board has booted). Gated on the cpio +# EXISTING rather than on a board flag: a tree that has not built it has +# nothing to check here, but one that has must not skip it silently. +DE25_INITRAMFS_CPIO="$ROOT/output-de25/images/mister-initramfs.cpio" +if [ ! -f "$DE25_INITRAMFS_CPIO" ]; then + skip "test-initramfs.sh --board de25nano (aarch64 QEMU boot test, 8 cases)" "no $DE25_INITRAMFS_CPIO -- the DE25 stack does not build package/mister-initramfs (D11)" +else if [ "${CI_TESTS_SKIP_QEMU_SYSTEM:-0}" = "1" ]; then skip "test-initramfs.sh --board de25nano (aarch64 QEMU boot test, 8 cases)" "CI_TESTS_SKIP_QEMU_SYSTEM=1" elif ! have qemu-system-aarch64; then diff --git a/scripts/export-kernel-tree.sh b/scripts/export-kernel-tree.sh index 0100e5ca..4386808e 100755 --- a/scripts/export-kernel-tree.sh +++ b/scripts/export-kernel-tree.sh @@ -196,14 +196,7 @@ readonly HASH_FILE="$REPO_ROOT/board/mister/de10nano/patches/linux/linux.hash" # MiSTer image ships, and the kernel-only stack deliberately selects no packages at all # (stacks.mk: `image-common` is in every image stack and no kernel-only one), so reading # it would reintroduce exactly the zero-drivers bug from the other direction. -readonly EXPORT_STACK=DE10NANO -# config-stacks.sh addresses the repo through $ROOT; this script uses $REPO_ROOT. Same -# directory, two names, because the helper is shared with scripts that predate this one. -ROOT="$REPO_ROOT" -readonly ROOT -# shellcheck source=scripts/lib/config-stacks.sh -. "$REPO_ROOT/scripts/lib/config-stacks.sh" # Committer identity for the generated commits. Patch AUTHORS are preserved by `git am`; # this only says who mechanically produced the tree, and it must be explicit so the @@ -217,13 +210,9 @@ say() { printf '\n=== %s\n' "$*"; } # Resolved AFTER die(), which it uses. STACK_FILES is the merge-ordered list of fragment # files that make up the exported board's configuration; every read of a pinned value # below goes through all of them, last definition winning, exactly as kconfig would. -mapfile -t STACK_FILES < <(config_stack_files "$EXPORT_STACK") +STACK_FILES=("$REPO_ROOT/configs/mister_de10nano_defconfig") readonly STACK_FILES -((${#STACK_FILES[@]})) || - die "no ${EXPORT_STACK}_FRAGMENTS line in $REPO_ROOT/configs/fragments/stacks.mk" -for _frag in "${STACK_FILES[@]}"; do - [[ -f $_frag ]] || die "fragment named by stacks.mk does not exist: $_frag" -done +[ -f "${STACK_FILES[0]}" ] || die "no ${STACK_FILES[0]} -- the DE10 defconfig is the single source of the kernel pin (ADR 0030)" unset _frag # Only set when we download rather than use the dl/ cache. Cleaned on exit: it holds a @@ -332,7 +321,7 @@ resolve_br_path() { version="$(defconfig_value BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE)" [[ -n $version ]] || - die "BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE not set in the $(config_stack_label "$EXPORT_STACK") stack: + die "BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE not set in the DE10 defconfig: ${STACK_FILES[*]}" patch_dir="$(resolve_br_path "$(defconfig_value BR2_LINUX_KERNEL_PATCH)")" @@ -1086,11 +1075,11 @@ mapfile -t enabled_kmods < <( ) ((${#enabled_kmods[@]})) || die "detected zero kernel-module packages in the -$(config_stack_label "$EXPORT_STACK") fragment stack: +DE10 defconfig (configs/mister_de10nano_defconfig): ${STACK_FILES[*]} That is almost certainly a parsing bug in this script rather than the truth — the image ships xone and the Realtek WiFi drivers. Refusing to export a tree missing them. -If a fragment moved, fix configs/fragments/stacks.mk or this script's EXPORT_STACK; +If the defconfig moved, fix STACK_FILES in this script; do NOT relax this check." # Announce what will actually be vendored, not what was detected: the two differ diff --git a/scripts/fetch-buildroot.sh b/scripts/fetch-buildroot.sh new file mode 100755 index 00000000..001cd883 --- /dev/null +++ b/scripts/fetch-buildroot.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# fetch-buildroot.sh -- download, hash-verify and unpack the pinned Buildroot. +# +# usage: scripts/fetch-buildroot.sh +# scripts/fetch-buildroot.sh --verify-only +# scripts/fetch-buildroot.sh --showsig +# +# The wrapper Makefile's $(BR_STAMP) rule calls this. Buildroot is never +# vendored (TASKS.md standing rule 1); the tarball lands in , is +# verified BEFORE unpacking against , and is unpacked to . +# Idempotent: an unpacked tree of the same version is left alone with no +# network access. +# +# WHERE THE HASH COMES FROM. must be transcribed from Buildroot's +# GPG-clearsigned release manifest, never from a downloaded tarball: +# https://buildroot.org/downloads/buildroot-.tar.gz.sign +# `--showsig ` prints it. scripts/hash-sync-buildroot.sh does the +# transcription on a Renovate bump. Do NOT "fix" a mismatch below by pasting +# the actual hash into the Makefile -- that blesses whatever bytes arrived. +set -euo pipefail + +url_for() { echo "https://buildroot.org/downloads/buildroot-$1.tar.gz"; } + +if [ "${1:-}" = "--showsig" ]; then + [ $# -eq 2 ] || { echo "usage: $0 --showsig " >&2; exit 2; } + echo "==> $(url_for "$2").sign" + exec curl -fsSL "$(url_for "$2").sign" +fi +verify_only=false +if [ "${1:-}" = "--verify-only" ]; then verify_only=true; shift; set -- "$@" /nonexistent; fi +[ $# -eq 4 ] || { echo "usage: $0 [--verify-only] []" >&2; exit 2; } +version=$1 sha256=$2 dl_dir=$3 br_dir=$4 +tarball="$dl_dir/buildroot-$version.tar.gz" + +for t in curl tar sha256sum; do + command -v "$t" >/dev/null 2>&1 || { echo "FATAL: required tool '$t' not found in PATH" >&2; exit 1; } +done + +if [ "$verify_only" = false ] && [ -f "$br_dir/Makefile" ] && grep -qx "export BR2_VERSION := $version" "$br_dir/Makefile"; then + echo "==> Buildroot $version already present at $br_dir" + exit 0 +fi + +mkdir -p "$dl_dir" +if [ ! -f "$tarball" ]; then + echo "==> Downloading Buildroot $version" + # .tmp then rename: an interrupted transfer never parks a truncated tarball at the real path. + curl -fSL --retry 3 -o "$tarball.tmp" "$(url_for "$version")" + mv "$tarball.tmp" "$tarball" +fi + +echo "==> Verifying SHA-256 of $tarball" +if ! echo "$sha256 $tarball" | sha256sum -c - >/dev/null 2>&1; then + cat >&2 < SHA-256 OK ($sha256)" +[ "$verify_only" = false ] || exit 0 + +echo "==> Unpacking Buildroot $version to $br_dir" +rm -rf "$br_dir" +mkdir -p "$br_dir" +tar -C "$br_dir" --strip-components=1 -xf "$tarball" diff --git a/scripts/fetch-sdcard-payload.sh b/scripts/fetch-sdcard-payload.sh index d1d718cd..070f2ecb 100755 --- a/scripts/fetch-sdcard-payload.sh +++ b/scripts/fetch-sdcard-payload.sh @@ -49,7 +49,7 @@ # SDCARD_CORES=1 scripts/fetch-sdcard-payload.sh # # STAGE_DIR precedence: $1 wins over $STAGE_DIR wins over the default -# "/output-sdcard-stage" (mirrors the output-rt/output-initramfs +# "/output-sdcard-stage" (mirrors the output-installer # naming the top-level Makefile already uses for per-stage build dirs). # # Result: /mister-payload/ populated per docs/verification/ diff --git a/scripts/hash-sync-golden.sh b/scripts/hash-sync-golden.sh deleted file mode 100755 index 53873096..00000000 --- a/scripts/hash-sync-golden.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env bash -# -# hash-sync-golden.sh — renovate-hash-sync case 8: on a Buildroot bump, -# record the new version's golden config hashes -# (configs/fragments/golden.sha256) so the bump PR is complete on its own. -# -# WHY. scripts/check-config-fragments.sh (d) pins the sha256 of every fragment -# stack's normalised resolved .config per BUILDROOT_VERSION. A Buildroot bump -# changes Kconfig defaults, so it is EXPECTED to move every hash; the check -# therefore treats "no line for this Buildroot version" as a ::warning, not a -# failure, so the automated bump PR still gets its build. This case is what -# turns that warning back into a recorded line: it runs the check's own -# --update-golden against the freshly bumped tree and the workflow commits the -# result alongside the BUILDROOT_SHA256 transcription case 6 just made. -# -# WHAT IT RUNS, AND FROM WHERE. Unlike the other cases this one deliberately -# executes the TARGET BRANCH's scripts/check-config-fragments.sh (through the -# target branch's Makefile: `make buildroot-unpack` fetches + hash-verifies the -# NEW tarball using the hash case 6 wrote), not a copy from .hash-sync-tools: -# the golden file's format and normalisation rules are defined by the check -# script in the same tree, and a golden written by a different version of the -# rules would be wrong by construction. A branch that predates the fragment -# split has no such script and is skipped. -# -# WHEN IT WRITES. Only when golden.sha256 has NO line at all for the tree's -# BUILDROOT_VERSION (a bump). If lines exist, any mismatch is real drift and -# is lint-config's to fail on -- this case must never bless it, so it records -# `skipped` and leaves the file alone. A kernel bump does not move the golden -# (the kernel version symbols are excluded from the normalisation), so on the -# weekly kernel PRs this case is a no-op. -# -# Cost: one 10 MB tarball download plus Buildroot's kconfig `conf` build and -# one olddefconfig per stack -- no toolchain, no package, no compile. -# -# Exit: always 0 on a handled path, same as every other case (see -# hash-sync-kernel.sh's header for why); a non-zero exit is a bug here. - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=scripts/lib/hash-sync-common.sh -. "$SCRIPT_DIR/lib/hash-sync-common.sh" - -OUTCOME_PIN="golden" -CHANGED_VAR="GOLDEN_CHANGED" - -REPO_ROOT="${1:-$(cd "$SCRIPT_DIR/.." && pwd)}" -[ -d "$REPO_ROOT" ] || { echo "::error::REPO_ROOT '$REPO_ROOT' is not a directory" >&2; exit 2; } - -: "${HASH_SYNC_OUTCOMES_FILE:?HASH_SYNC_OUTCOMES_FILE must be set}" - -main() { - cd "$REPO_ROOT" - - local outcomes_file - outcomes_file="$(hash_sync_resolve_outcomes_file "$HASH_SYNC_OUTCOMES_FILE")" - - local check="scripts/check-config-fragments.sh" - local golden="configs/fragments/golden.sha256" - if [ ! -x "$check" ] || [ ! -f "$golden" ]; then - echo "::notice::$check or $golden not in this checkout (pre-fragment-split branch) -- skipping $OUTCOME_PIN" - hash_sync_record "$outcomes_file" "$OUTCOME_PIN" skipped "$check or $golden not in this checkout" - hash_sync_set_env "$CHANGED_VAR" 0 - exit 0 - fi - - local ver - ver=$(sed -n -e 's/[[:space:]]*$//' -e 's/^BUILDROOT_VERSION[[:space:]]*?=[[:space:]]*//p' Makefile | head -1) - if [ -z "$ver" ]; then - echo "::error::could not extract BUILDROOT_VERSION from Makefile" >&2 - hash_sync_record "$outcomes_file" "$OUTCOME_PIN" failed "could not extract BUILDROOT_VERSION from Makefile" - hash_sync_set_env "$CHANGED_VAR" 0 - exit 0 - fi - - if awk -v v="$ver" '$1 == v { found = 1 } END { exit !found }' "$golden"; then - echo "==> $OUTCOME_PIN: $golden already records Buildroot $ver -- nothing to add (drift, if any, is lint-config's to report, never this case's to bless)" - hash_sync_record "$outcomes_file" "$OUTCOME_PIN" already "golden already recorded for Buildroot $ver" - hash_sync_set_env "$CHANGED_VAR" 0 - exit 0 - fi - - echo "==> $OUTCOME_PIN: no golden lines for Buildroot $ver -- regenerating" - # buildroot-unpack fetches and hash-verifies the NEW tarball with the - # BUILDROOT_SHA256 case 6 just transcribed; if that failed or was skipped, - # this fails closed too and the PR stays red at the same place. - if ! make --no-print-directory buildroot-unpack; then - echo "::warning::make buildroot-unpack failed for Buildroot $ver -- leaving $golden untouched (lint-config will warn, not fail)" - hash_sync_record "$outcomes_file" "$OUTCOME_PIN" skipped "make buildroot-unpack failed for Buildroot $ver" - hash_sync_set_env "$CHANGED_VAR" 0 - exit 0 - fi - if ! "$check" --update-golden; then - # --update-golden still runs (a)-(c); a failure there is a real - # fragment problem the PR must fix, not something to paper over. - echo "::warning::$check --update-golden reported failures -- $golden NOT committed; see the check's output" - git checkout -- "$golden" 2>/dev/null || true - hash_sync_record "$outcomes_file" "$OUTCOME_PIN" skipped "$check failed under Buildroot $ver" - hash_sync_set_env "$CHANGED_VAR" 0 - exit 0 - fi - - if git diff --quiet -- "$golden"; then - hash_sync_record "$outcomes_file" "$OUTCOME_PIN" already "golden unchanged" - hash_sync_set_env "$CHANGED_VAR" 0 - else - echo "Updated $golden:" - git --no-pager diff -- "$golden" - hash_sync_record "$outcomes_file" "$OUTCOME_PIN" refreshed "recorded golden hashes for Buildroot $ver" - hash_sync_set_env "$CHANGED_VAR" 1 - fi -} - -main "$@" diff --git a/scripts/hash-sync-kernel.sh b/scripts/hash-sync-kernel.sh index 8fd4c689..3fccb9f7 100755 --- a/scripts/hash-sync-kernel.sh +++ b/scripts/hash-sync-kernel.sh @@ -11,7 +11,7 @@ # --pin=stable the 6.18.y longterm kernel that the SHIPPED image runs. # Version read from configs/fragments/de10nano.fragment. # --pin=rt the RT/beta kernel variant (docs/rt-beta-kernel.md). -# Version read from configs/mister_rt.fragment. +# Version read from configs/mister_de10nano_defconfig. # # WHY `rt` EXISTS NOW, HAVING BEEN FORBIDDEN BEFORE -- read this before # "restoring" the old prohibition, because the change is deliberate and the old @@ -198,12 +198,19 @@ done # rt pin gets its own, which the .yml's gate must OR in (it does). case "$PIN" in stable) - VERSION_FILE="configs/fragments/de10nano.fragment" + VERSION_FILE="configs/mister_de10nano_defconfig" + VERSION_SYMBOL="BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE" + HASH_FILE="board/mister/de10nano/patches/linux/linux.hash" OUTCOME_PIN="kernel" CHANGED_VAR="PATCH_HASH_CHANGED" ;; rt) - VERSION_FILE="configs/mister_rt.fragment" + # Since ADR 0030 Phase C the RT variant is package/linux-rt: its pin is + # BR2_PACKAGE_LINUX_RT_VERSION in the DE10 image fragment and its hash + # file is the package's own (same signed-manifest rule). + VERSION_FILE="configs/mister_de10nano_defconfig" + VERSION_SYMBOL="BR2_PACKAGE_LINUX_RT_VERSION" + HASH_FILE="package/linux-rt/linux-rt.hash" OUTCOME_PIN="kernel-rt" CHANGED_VAR="RT_PATCH_HASH_CHANGED" ;; @@ -225,7 +232,7 @@ main() { outcomes_file="$(hash_sync_resolve_outcomes_file "$HASH_SYNC_OUTCOMES_FILE")" local defconfig="$VERSION_FILE" - local linuxhash="board/mister/de10nano/patches/linux/linux.hash" + local linuxhash="$HASH_FILE" if [ ! -f "$defconfig" ] || [ ! -f "$linuxhash" ]; then echo "::warning::$defconfig or $linuxhash not found in this checkout -- skipping $OUTCOME_PIN" @@ -251,7 +258,7 @@ main() { # explicit empty-check below would never run and the failure would be # silent. Swallowing the status lets that check emit its diagnostic instead. local kver - kver=$(grep -oE '^BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="[^"]+"' "$defconfig" \ + kver=$(grep -oE "^${VERSION_SYMBOL}=\"[^\"]+\"" "$defconfig" \ | sed -E 's/.*"([^"]+)"/\1/' | tail -1 || true) if [ -z "$kver" ]; then echo "::error::could not extract BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE from $defconfig" >&2 diff --git a/scripts/hostshim.sh b/scripts/hostshim.sh new file mode 100755 index 00000000..33449de6 --- /dev/null +++ b/scripts/hostshim.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# hostshim.sh -- make sure Buildroot sees a GNU `install`. +# +# usage: scripts/hostshim.sh +# +# Buildroot refuses to build when /usr/bin/install is uutils coreutils +# (support/dependencies/dependencies.sh; https://github.com/uutils/coreutils/issues/12166), +# which Debian/Ubuntu's coreutils-from-uutils installs as the default while +# shipping GNU's as `gnuinstall`. Upstream's advice is update-alternatives, +# which needs root and mutates the developer's machine. Instead: a directory +# holding one `install` symlink to a GNU install, which the Makefile prepends +# to PATH for Buildroot only. A no-op on a host whose install is already GNU +# (prints nothing, creates nothing); fails loudly when no GNU install exists. +# CI runs it as a fail-fast check before spending hours on a build. +set -euo pipefail +shim_dir=${1:?usage: hostshim.sh } +if install --version 2>/dev/null | grep -q 'GNU coreutils'; then + exit 0 +fi +gnu=$(command -v gnuinstall 2>/dev/null || true) +if [ -z "$gnu" ]; then + cat >&2 <&1 | head -1) +Buildroot refuses to build with it and no GNU 'install' was found to substitute. +Install GNU coreutils, e.g.: sudo apt-get install gnu-coreutils # provides /usr/bin/gnuinstall +MSG + exit 1 +fi +mkdir -p "$shim_dir" +ln -sf "$gnu" "$shim_dir/install" +echo "==> host 'install' is not GNU; shimming $gnu into PATH for Buildroot" diff --git a/scripts/lib/board-expectations.sh b/scripts/lib/board-expectations.sh deleted file mode 100644 index bb90dcb1..00000000 --- a/scripts/lib/board-expectations.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env bash -# -# scripts/lib/board-expectations.sh — per-board expected-symbol tables for -# the arch/toolchain guards in scripts/check-kernel-defconfig-sync.sh and -# .github/actions/buildroot-build/action.yml. Not directly executable; -# sourced, same convention as scripts/lib/hash-sync-common.sh and -# scripts/ci-lib.sh (see either file's own header for the sourcing shape: -# a repo-root-relative `source scripts/lib/board-expectations.sh` from a -# workflow/composite-action `run:` block, or -# `. "$SCRIPT_DIR/lib/board-expectations.sh"` from another script under -# scripts/, resolved off ${BASH_SOURCE[0]}, not CWD). -# -# docs/de25-readiness-ledger.md §5.2 is this file's spec; §5.3-§5.4 explain -# each row, §5.7 the fail-closed properties both consumers must preserve. -# -# Adding a board means adding a row to EVERY array below — there is -# deliberately no fallback row and no wildcard match. An inference from an -# existing row (e.g. "this board is also aarch64, so reuse that row") is -# exactly the failure this design forbids: a missing row must be a loud -# error, never a silent, possibly-wrong inherited guess. See §5.2's "Why an -# explicit BOARD string key, not something derived". -# -# Both consumers key on an explicit BOARD string (env var or argument), -# defaulting to "de10nano" — NOT derived from a defconfig filename stem -# (that conflates the board axis with the variant axis -# .github/actions/buildroot-build/action.yml already has) and NOT derived -# by reading BR2_arm vs BR2_aarch64 back out of a defconfig and picking a -# generic row (that would let a future board silently inherit an existing -# one). Each row is an affirmative, reviewed claim. -# -# shellcheck disable=SC2034 # every name below (BOARD_COMMON_SENTINELS, -# BOARD_COMMON_FAMILIES, BOARD_ARCH_SENTINELS, BOARD_ARCH_FAMILIES, -# BOARD_FINGERPRINT_SENTINELS) is read by the sourcing consumers -# (scripts/check-kernel-defconfig-sync.sh, .github/actions/ -# buildroot-build/action.yml), not by this file itself, so shellcheck's -# single-file analysis can't see the use. - -# Arch-independent sentinels/families every board shares (KERNEL_HEADERS is a -# choice under package/linux-headers, TOOLCHAIN_BUILDROOT_CXX is under -# package/gcc — neither varies by board, so neither is duplicated per row). -BOARD_COMMON_SENTINELS="BR2_KERNEL_HEADERS BR2_TOOLCHAIN_BUILDROOT_CXX" -BOARD_COMMON_FAMILIES="BR2_KERNEL_HEADERS BR2_TOOLCHAIN_BUILDROOT_" - -# Sentinel symbols check-kernel-defconfig-sync.sh's `for must in ...` assert -# requires present in the kernel-only fragment stack (configs/fragments/ -# stacks.mk DE10NANO_KERNEL_FRAGMENTS; before the 2026-09 fragment split, in -# configs/mister_kernel_defconfig). -# Merge order for a consumer is ARCH ROW FIRST, then BOARD_COMMON_SENTINELS — -# see that script for why the order matters (byte-identity with today's -# literal list, so docs/de25-readiness-ledger.md §5.6's migration check is -# meaningful). -declare -A BOARD_ARCH_SENTINELS=( - [de10nano]="BR2_arm BR2_cortex_a9" - # [V] — matches configs/fragments/de25nano.fragment (D2.1, 2026-09-02): - # BR2_aarch64=y and BR2_cortex_a76_a55=y are its arch/CPU choices. - # Change this row in the same commit as any change to those two lines. - [de25nano]="BR2_aarch64 BR2_cortex_a76_a55" -) - -# Family PREFIXES for the `for family in ...` symbol-name-set assert (its -# :129, pre-change) — see that script's header §3 for why a kconfig CHOICE -# needs a name-set comparison, not a value comparison. Same arch-row-first, -# then BOARD_COMMON_FAMILIES merge order as the sentinels above. -declare -A BOARD_ARCH_FAMILIES=( - [de10nano]="BR2_arm BR2_ARM_ BR2_cortex" - # [V] — checked against configs/fragments/de25nano.fragment (2026-09-02): - # it sets BR2_aarch64 and BR2_cortex_a76_a55 and no BR2_ARM_* symbol at - # all (AArch64 has no such knobs in Buildroot). BR2_ARM_ is carried over - # so that an aarch64 defconfig populating none of it is a legitimate - # empty-set match, not a failure; both 32- and 64-bit cores share the - # BR2_cortex_* namespace. - [de25nano]="BR2_aarch64 BR2_ARM_ BR2_cortex" -) - -# Toolchain-fingerprint sentinel PATTERNS for -# .github/actions/buildroot-build/action.yml's `for must in ...` assert (its -# :190-195, pre-change) — grep -q patterns against the stripped fingerprint, -# not plain symbol names (hence the leading '^'). -declare -A BOARD_FINGERPRINT_SENTINELS=( - [de10nano]="^BR2_arm ^BR2_cortex" - # [V] — configs/fragments/de25nano.fragment sets BR2_aarch64=y and - # BR2_cortex_a76_a55=y (2026-09-02). - [de25nano]="^BR2_aarch64 ^BR2_cortex" -) diff --git a/scripts/lib/config-stacks.sh b/scripts/lib/config-stacks.sh deleted file mode 100644 index 99bf12ab..00000000 --- a/scripts/lib/config-stacks.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env bash -# -# scripts/lib/config-stacks.sh — read configs/fragments/stacks.mk and strip -# fragment files. Not directly executable; sourced (same convention as -# scripts/lib/board-expectations.sh) by scripts/check-kernel-defconfig-sync.sh -# and scripts/check-config-fragments.sh. The sourcing script must have set -# ROOT to the repository root first. -# -# stacks.mk is the SINGLE source of truth for which fragments make up which -# Buildroot configuration; the top-level Makefile `include`s it and this file -# parses the same `_FRAGMENTS := a b c` lines with sed, so a stack -# can never be defined one way for `make` and another for the checks. Keep -# stacks.mk to that one-line-per-stack shape (docs/buildroot-config.md §1). - -# shellcheck disable=SC2034 # read by the sourcing scripts -CONFIG_STACKS_MK="$ROOT/configs/fragments/stacks.mk" -CONFIG_FRAGMENT_DIR="$ROOT/configs/fragments" - -# Every `` name defined in stacks.mk (DE10NANO, DE10NANO_KERNEL, ...). -config_stack_vars() { - sed -n 's/^\([A-Z0-9_]*\)_FRAGMENTS[[:space:]]*:=.*$/\1/p' "$CONFIG_STACKS_MK" -} - -# $1 = stack var name -> its fragment NAMES, in merge order, one per line. -config_stack_fragments() { - sed -n "s/^$1_FRAGMENTS[[:space:]]*:=[[:space:]]*//p" "$CONFIG_STACKS_MK" \ - | sed -e 's/[[:space:]]*#.*$//' | tr -s ' \t' '\n' | sed '/^$/d' -} - -# $1 = stack var name -> absolute fragment paths, in merge order, one per line. -config_stack_files() { - local n - while IFS= read -r n; do - [ -n "$n" ] || continue - printf '%s\n' "$CONFIG_FRAGMENT_DIR/$n.fragment" - done < <(config_stack_fragments "$1") -} - -# DE10NANO_KERNEL -> de10nano-kernel: the human-facing stack name. -config_stack_label() { - printf '%s\n' "$1" | tr 'A-Z_' 'a-z-' -} - -# Strip comments/blank lines from a fragment, KEEPING `# BR2_X is not set` -# lines (kconfig reads those as an explicit =n — they are configuration, not -# commentary). Output: only `BR2_...=...` and `# BR2_... is not set` lines, -# trailing same-line comments and whitespace removed. Values are otherwise -# verbatim, so a value containing '=' or '#' inside quotes survives — no -# committed value carries a bare ` #`, which is the one thing this would -# mis-strip. -config_strip_fragment() { - sed -e 's/^[[:space:]]*# \(BR2_[A-Za-z0-9_]*\) is not set.*$/@@NOTSET@@\1/' \ - -e 's/^[[:space:]]*#.*$//' \ - -e 's/[[:space:]]\+#.*$//' \ - -e 's/[[:space:]]*$//' \ - -e 's/^@@NOTSET@@\(.*\)$/# \1 is not set/' "$@" \ - | grep -e '^BR2_' -e '^# BR2_' || true -} - -# The symbol NAME of a stripped line (either form). -config_line_symbol() { - case "$1" in - "# "*" is not set") local s="${1#\# }"; printf '%s\n' "${s% is not set}" ;; - *) printf '%s\n' "${1%%=*}" ;; - esac -} diff --git a/scripts/lint-kernel-patches.sh b/scripts/lint-kernel-patches.sh index d3792e4c..94661420 100755 --- a/scripts/lint-kernel-patches.sh +++ b/scripts/lint-kernel-patches.sh @@ -50,7 +50,7 @@ # # Usage: scripts/lint-kernel-patches.sh [patch-dir...] # With no arguments, lints the series named by BR2_LINUX_KERNEL_PATCH in -# configs/fragments/de10nano.fragment, plus the upstream-only series alongside it +# configs/mister_de10nano_defconfig, plus the upstream-only series alongside it # ("-upstream") when that directory exists. # A directory named on the command line must exist and contain patches. # @@ -64,7 +64,7 @@ set -o pipefail # (shellcheck SC2155), and the rest of scripts/ avoids that pattern. REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" readonly REPO_ROOT -readonly DEFCONFIG="$REPO_ROOT/configs/fragments/de10nano.fragment" +readonly DEFCONFIG="$REPO_ROOT/configs/mister_de10nano_defconfig" # Resolve the default from the defconfig rather than hardcoding the path, which is what # the usage text above has always promised and what scripts/export-kernel-tree.sh already diff --git a/scripts/list-kernel-variants.sh b/scripts/list-kernel-variants.sh deleted file mode 100755 index 082be192..00000000 --- a/scripts/list-kernel-variants.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env bash -# -# list-kernel-variants.sh — the kernel-variant registry, derived from the -# filesystem instead of hand-maintained in N places (item D, follow-up to -# ADR 0021 as amended 2026-07-18). -# -# WHY THIS EXISTS: build.yml and release.yml each carried their own -# `kernel: [rt]` matrix literal, and both files' headers claimed "adding a -# variant = one matrix entry" — a claim that was already false the moment a -# second workflow needed the same list, since it actually meant editing TWO -# matrix literals plus the fragment. The real registry has always been -# .github/actions/buildroot-build/action.yml's fragment-existence check -# (configs/mister_.fragment): a variant is accepted there iff that file -# exists, no other list consulted. This script is the one place that reads -# that same registry and emits it as JSON, so both workflows' matrices are -# `fromJSON()` of ONE computed list instead of two typed-by-hand ones that can -# drift apart (which is exactly the bug this item exists to close). -# -# CONTRACT: stdout is EXACTLY one line — a JSON array of variant names (e.g. -# ["rt"]) — on success, and nothing else. On failure (including the -# "zero fragments" case below) this exits non-zero with a message on stderr -# and prints NOTHING resembling JSON to stdout, so a caller that forgot to -# check the exit code gets a `fromJSON` parse error instead of a silently -# empty matrix. That distinction matters: an empty `strategy.matrix.kernel` -# is not "no legs, that's fine" to GitHub Actions — a job with zero matrix -# combinations runs zero times and the job itself is reported as a no-op, -# which reads as green. Failing loudly here is what stands between a -# filesystem accident (e.g. every fragment deleted) and a release/CI run that -# silently ships zero kernel variants while looking successful. -# -# EXCLUDED ON PURPOSE: the board/common fragment stacks under -# configs/fragments/ (the shared kernel-only BASE every variant builds against -# lives there, configs/fragments/stacks.mk, and so do the two stage-1 -# initramfs stacks) and configs/mister_installer_defconfig (the SD-card -# installer config). The stacks live in a SUBDIRECTORY and the installer -# defconfig carries no `.fragment` suffix, so the glob below already -# excludes both without any special-casing — the explicit denylist further -# down exists only so that fact survives a future rename or move instead of -# relying on an accident of path or extension. -# -# ALSO RESERVED: the variant name "main". Unlike the files above, -# a hypothetical configs/mister_main.fragment WOULD match the *.fragment glob -# below -- but .github/actions/buildroot-build/action.yml's `case` matches -# `main)` as its FULL-IMAGE build, not a kernel-only one, so that name reaching -# a matrix would silently run a ~3h20m `make all` inside a kernel leg instead -# of a kernel-only build, only failing much later when the leg's staging step -# looks for output-main/images/zImage_dtb. Checked explicitly below, by name, -# so this can never reach a matrix. -# -# NAME VALIDATION mirrors buildroot-build/action.yml's own variant-name -# whitelist ([a-z0-9_-]) — a name that whitelist would reject must not reach -# a matrix (and from there a shell/path context) via this script either. -# -# Exit: 0 with one JSON line on stdout = the registry, however many entries; -# 1 = a fragment yielded an invalid name, or zero fragments were found (both -# are repo bugs, not valid empty states); 2 = usage/IO error. - -set -euo pipefail - -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -cd "$ROOT" - -if [ ! -d configs ]; then - echo "list-kernel-variants: FATAL: configs/ not found under $ROOT" >&2 - exit 2 -fi - -variants=() -shopt -s nullglob -for f in configs/mister_*.fragment; do - case "$f" in - configs/fragments/* | configs/mister_installer_defconfig) - # Unreachable given the *.fragment glob above -- the stacks are in a - # subdirectory and the installer defconfig lacks the extension -- but - # kept explicit per the EXCLUDED ON PURPOSE note in the header, so - # this is documented in code, not just prose. - continue - ;; - esac - - name="${f#configs/mister_}" - name="${name%.fragment}" - - case "$name" in - main) - echo "::error::${f} yields the variant name 'main' -- that name is RESERVED by .github/actions/buildroot-build for the full-image build, not a kernel-only variant (see the ALSO RESERVED note in this script's header); rename the fragment" >&2 - exit 1 - ;; - esac - - case "$name" in - *[!a-z0-9_-]* | '') - echo "::error::${f} yields an invalid variant name '${name}' -- kernel-variant names must be non-empty [a-z0-9_-] (see the variant validation in .github/actions/buildroot-build/action.yml)" >&2 - exit 1 - ;; - esac - - variants+=("$name") -done -shopt -u nullglob - -if [ "${#variants[@]}" -eq 0 ]; then - echo "::error::no kernel-variant fragments found under configs/ (expected at least configs/mister_rt.fragment, see docs/rt-beta-kernel.md / ADR 0021) -- refusing to emit an empty matrix, which GitHub Actions would run as zero legs and report as a success" >&2 - exit 1 -fi - -# Sort for a deterministic, reviewable order -- glob order is filesystem- -# dependent, not something a matrix's log output should depend on. mapfile, -# not a bare command-substitution word-split, so a (currently impossible, -# whitelist-enforced) name containing whitespace still round-trips intact -- -# same defensive habit lint.yml's own shellcheck step uses. LC_ALL=C so the -# order can't depend on the runner's locale either (same convention as -# scripts/check-abi.sh, scripts/check-linux-img.sh, scripts/ci-tests.sh). -before="${#variants[@]}" -mapfile -t variants < <(printf '%s\n' "${variants[@]}" | LC_ALL=C sort) - -# `mapfile < <(... | sort)` does NOT observe a `sort` failure: neither -# `set -e` nor `set -o pipefail` sees inside a process substitution, and -# mapfile itself returns 0 having simply read however many lines `sort` -# managed to emit before dying (e.g. a killed/OOM'd `sort` under TMPDIR -# exhaustion -- build.yml carries an explicit disk-reclaim step, so that is -# not a hypothetical here). That would silently shrink (in the worst case, to -# zero) the already-validated `variants` array AFTER the non-empty check -# above has passed, which is exactly the silently-empty-matrix failure mode -# this script's whole header promises to refuse. Re-check the count is -# unchanged post-sort so a partial/failed sort is caught here, loudly, -# instead of downstream as a mysteriously smaller (or empty) matrix. -if [ "${#variants[@]}" -ne "$before" ]; then - echo "::error::internal error: sorting ${before} variant name(s) yielded ${#variants[@]} -- 'sort' likely failed inside the process substitution (its exit status is invisible to mapfile/set -e); refusing to emit a matrix that may have silently lost entries" >&2 - exit 1 -fi - -json="[" -for i in "${!variants[@]}"; do - [ "$i" -gt 0 ] && json+="," - json+="\"${variants[$i]}\"" -done -json+="]" - -printf '%s\n' "$json" diff --git a/scripts/mk-release.sh b/scripts/mk-release.sh new file mode 100755 index 00000000..832684ae --- /dev/null +++ b/scripts/mk-release.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +# mk-release.sh -- turn a finished `make` into a verified release asset set. +# +# usage: scripts/mk-release.sh [] [] (defaults: output, dist) +# +# release.yml's build job is this script plus the sdcard image. It is a plain +# sequence, and every step is one you can run at a terminal: +# +# 1. read /MiSTer.version out of the built linux.img and check the contract +# (6 ASCII digits, no newline, equal to $MISTER_VERSION when that is set); +# RELEASE_DATE = 20, written to /RELEASE_DATE for the caller +# 2. stage the image assets: linux.img, zImage_dtb, zImage_dtb-rt, +# buildroot.config, linux.config, linux-rt.config, legal-info.tar.gz +# 3. fetch, verify and extract the pinned STOCK release archive +# (scripts/verify-stock-payload.sh; the STOCK_* pins come from the +# environment -- release.yml's env block, or your shell) +# 4. assemble files/linux/ = stock's tree with OUR linux.img, zImage_dtb and +# 7za dropped in, and pack release_.7z the way the Downloader expects +# 5. prove the archive round-trips under the pinned ARM 7za (qemu-arm) and +# that its member list matches the assembled tree +# 6. SHA256SUMS over everything above +# +# Needs on the host: 7z (p7zip-full), qemu-arm, debugfs (e2fsprogs), curl. +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +out=${1:-$ROOT/output} +dist=${2:-$ROOT/dist} +work=$ROOT/release-work +# shellcheck source=scripts/ci-lib.sh +source "$ROOT/scripts/ci-lib.sh" +say() { printf '\n==> mk-release: %s\n' "$*"; } +die() { echo "mk-release: FATAL: $*" >&2; exit 1; } + +for t in 7z qemu-arm debugfs curl; do command -v "$t" >/dev/null 2>&1 || die "'$t' not found in PATH"; done +for f in images/linux.img images/zImage_dtb images/zImage_dtb-rt images/linux-rt.config images/7za .config; do + [ -f "$out/$f" ] || die "$out/$f is missing -- run 'make' first (zImage_dtb-rt / linux-rt.config come from package/linux-rt)" +done +[ -d "$out/legal-info" ] || die "$out/legal-info is missing -- run 'make legal-info' first" + +# --- 1. /MiSTer.version -------------------------------------------------------- +say "reading /MiSTer.version from $out/images/linux.img" +rm -rf "$work"; mkdir -p "$work/ver" "$dist" +debugfs -R "rdump /MiSTer.version $work/ver" "$out/images/linux.img" >/dev/null 2>"$work/debugfs.log" || true +verfile="$work/ver/MiSTer.version" +[ -f "$verfile" ] || { sed 's/^/ /' "$work/debugfs.log" >&2; die "debugfs could not extract /MiSTer.version"; } +[ "$(wc -c < "$verfile")" -eq 6 ] || die "/MiSTer.version is $(wc -c < "$verfile") bytes, expected exactly 6 (docs/downloader-contract.md §3)" +[ "$(tail -c1 "$verfile" | od -An -tx1 | tr -d ' ')" != "0a" ] || die "/MiSTer.version ends in a newline -- that breaks the Downloader's version-equality check" +yymmdd=$(cat "$verfile") +case "$yymmdd" in [0-9][0-9][0-9][0-9][0-9][0-9]) ;; *) die "/MiSTer.version '$yymmdd' is not 6 ASCII digits" ;; esac +if [ -n "${MISTER_VERSION:-}" ] && [ "$yymmdd" != "$MISTER_VERSION" ]; then + die "built /MiSTer.version '$yymmdd' != requested MISTER_VERSION '$MISTER_VERSION' -- post-build.sh did not honor the override" +fi +release_date="20$yymmdd" +echo "$release_date" > "$dist/RELEASE_DATE" +echo " /MiSTer.version=$yymmdd -> RELEASE_DATE=$release_date" + +# --- 2. image assets -------------------------------------------------------------- +say "staging image assets into $dist" +cp -f "$out/images/linux.img" "$out/images/zImage_dtb" "$out/images/zImage_dtb-rt" "$out/images/linux-rt.config" "$dist/" +cp -f "$out/.config" "$dist/buildroot.config" +trees=("$out"/build/linux-[0-9]*/) +[ "${#trees[@]}" -eq 1 ] && [ -d "${trees[0]}" ] || die "expected exactly one kernel tree at $out/build/linux-[0-9]*/, found ${#trees[@]} (a stale sibling from a version bump?)" +cp -f "${trees[0]}.config" "$dist/linux.config" +ci_lib_package_legal_info "$out" "$dist/legal-info.tar.gz" patches-only +ci_lib_check_release_asset_size "$dist/legal-info.tar.gz" legal-info.tar.gz \ + ". The package set has outgrown a single source bundle -- split it (e.g. sources/ as its own asset)." + +# --- 3. the stock archive --------------------------------------------------------- +say "fetching + verifying the pinned stock release" +vsp="$ROOT/scripts/verify-stock-payload.sh" +"$vsp" fetch-stock "$work/stock_release.7z" +"$vsp" verify-stock "$work/stock_release.7z" +"$vsp" extract-stock "$work/stock_release.7z" "$work/stock-extract" +"$vsp" verify-uboot "$work/stock-extract" + +# --- 4. assemble + pack ------------------------------------------------------------ +say "assembling files/linux and packing release_$release_date.7z" +mkdir -p "$work/release-stage" +cp -a "$work/stock-extract/files" "$work/release-stage/files" +cp -f "$out/images/linux.img" "$out/images/zImage_dtb" "$out/images/7za" "$work/release-stage/files/linux/" +find "$work/release-stage/files/linux" -maxdepth 1 -printf ' %f\n' | sort +# Plain solid LZMA2, no BCJ2: the on-device 7za (2016) cannot read BCJ2 streams. +( cd "$work/release-stage" && 7z a -mx=9 -m0=lzma2 -mf=off -ms=on "$dist/release_$release_date.7z" files/ >/dev/null ) +echo " wrote $dist/release_$release_date.7z ($(wc -c < "$dist/release_$release_date.7z") bytes)" + +# --- 5. round trip under the pinned ARM 7za ---------------------------------------- +say "round-tripping the archive under the pinned ARM 7za (qemu-arm)" +"$vsp" fetch-7za "$work/7za" +"$vsp" roundtrip "$dist/release_$release_date.7z" "$work/7za" "$work/downloader-extract" "$out/target" +"$vsp" verify-uboot "$work/downloader-extract" --hash-only +"$vsp" verify-layout "$dist/release_$release_date.7z" "$work/release-stage" + +# --- 6. SHA256SUMS ------------------------------------------------------------------- +say "SHA256SUMS" +( cd "$dist" && sha256sum "release_$release_date.7z" linux.img zImage_dtb zImage_dtb-rt buildroot.config linux.config linux-rt.config legal-info.tar.gz > SHA256SUMS && cat SHA256SUMS ) +# The stock archive stays for scripts/mk-sdcard.sh, which reuses it through +# fetch-sdcard-payload.sh's cache instead of downloading it again. +say "done: $dist ready; stock archive kept at $work/stock_release.7z for mk-sdcard.sh" diff --git a/scripts/mk-sdcard.sh b/scripts/mk-sdcard.sh index 8cbb2288..beb57a16 100755 --- a/scripts/mk-sdcard.sh +++ b/scripts/mk-sdcard.sh @@ -4,8 +4,7 @@ # (`sdcard.img` / `sdcard-full.img`; TASKS.md P5.3, PLAN.md §8, ADR 0017, ADR 0020). # # This is the ORCHESTRATOR that ties the individually-authored sdcard-image pieces -# together into one release artifact. It runs AFTER a completed `make rt` THEN -# `make all` — that order, so `all` folds rt's staged module tree into linux.img +# together into one release artifact. It runs AFTER a completed `make all` # (it needs the real kernel + rootfs this repo builds) and produces # `output/images/sdcard.img.xz` (or `output/images/sdcard-full.img.xz` when # SDCARD_CORES=1), plus the raw `.img` beside it so `scripts/check-sdcard.sh` can @@ -21,15 +20,16 @@ # The seven steps (fixed interface — TASKS.md P5.3 "scripts/mk-sdcard.sh") # --------------------------------------------------------------------------- # 1. Build the INSTALLER initramfs cpio from configs/mister_installer_defconfig -# into output-installer/ (mirrors how the Makefile builds output-initramfs/ -# and output-rt/: a separate Buildroot O= with its own static-musl config). +# into output-installer/ (a separate Buildroot O= with its own static-musl +# config). # Product: output-installer/images/rootfs.cpio. # # 2. Relink OUR kernel with that cpio embedded to produce the INSTALLER # zImage_dtb, then RESTORE output/ so output/images/zImage_dtb (the real, # Downloader-shipped kernel) is left exactly as `make all` produced it. This # REUSES the completed main build in output/: a `linux-reconfigure all` that -# re-embeds step 1's cpio (via external.mk's MISTER_INITRAMFS_CPIO override) and +# re-embeds step 1's cpio (via linux/linux-ext-mister-initramfs.mk's +# MISTER_INITRAMFS_CPIO override) and # re-links only the kernel on the ALREADY-BUILT toolchain (~15 min) -- NOT a # fresh from-scratch build in a new O= (that would rebuild the whole internal # glibc toolchain + rootfs, ~3 h, and blow the CI job's wall-clock cap; see @@ -76,9 +76,8 @@ # --------------------------------------------------------------------------- # Usage # --------------------------------------------------------------------------- -# make rt && make all # prerequisites: RT kernel FIRST (so `all` -# # folds its modules into linux.img), then -# # the main kernel + rootfs +# make all # prerequisite: the main kernel + rootfs (linux.img +# # already carries every kernel variant's modules) # scripts/mk-sdcard.sh # -> output/images/sdcard.img(.xz) # SDCARD_CORES=1 scripts/mk-sdcard.sh # -> output/images/sdcard-full.img(.xz) # @@ -155,15 +154,11 @@ readonly OUR_PAYLOAD_7ZA="$OUTPUT_DIR/images/7za" # matching modules. That is exactly what the build-ORDER coherence check in # require_prerequisites still guards. -# The extra-modules overlay (same path as the Makefile's EXTRA_MODULES_OVERLAY): -# where `make rt` (locally) or the CI kernel artifacts (release.yml) stage the -# variant module trees that `make all` folds into linux.img. Read-only here — -# require_prerequisites cross-checks every kver staged in it against the -# linux.img actually being shipped, because this script snapshots that image -# BEFORE its own step-2 relink regenerates it: a `make all` that ran before -# `make rt` yields a snapshot with no RT modules, and nothing downstream would -# ever notice. -readonly EXTRA_MODULES_OVERLAY="$REPO_ROOT/work/extra-modules-overlay" +# Since ADR 0030 Phase C the RT kernel (package/linux-rt) installs its module +# tree into the rootfs as part of the same `make all` that produces linux.img, +# so there is no overlay to cross-check against the snapshotted image: a +# linux.img from `make all` carries every kernel variant's modules by +# construction. # --- Staging + assembly scratch -------------------------------------------- # STAGE_DIR is the SAME default fetch-sdcard-payload.sh uses, so a warm @@ -305,41 +300,6 @@ require_prerequisites() { # first Linux update, which is the exact behaviour ADR 0023 exists to end. [ -f "$OUR_PAYLOAD_7ZA" ] || die "missing $OUR_PAYLOAD_7ZA — run 'make all' before 'make sdcard' (package/7zip installs it; the card ships linux/7za, docs/verification/sdcard-payload.md)" - # Build-ORDER coherence (the check nothing else can do this late): the card's - # linux.img must already contain every module tree the extra-modules overlay - # staged — i.e. `make all` must have run AFTER `make rt` staged it. Built - # the other way round (all → rt), the image predates the overlay and a - # variant kernel finds NO matching modules: docs/rt-beta-kernel.md §5's - # silent broken-peripherals failure, baked into a flashable card. - # - # This check OUTLIVED the thing that motivated it and is kept deliberately. - # The card no longer ships zImage_dtb-rt itself (ADR 0021 as amended - # 2026-07-27), but the RT MODULES still ride inside this linux.img, and the - # documented dev workflow is to download zImage_dtb-rt and drop it on a card - # built from exactly this image. A card whose rootfs lacks the matching - # module tree turns that supported workflow into the same silent failure — - # so the invariant still has a consumer, just a manual one. - # - # So: every kver staged in the overlay must exist inside linux.img (debugfs - # — read-only, no root, same tool check-linux-img.sh leans on). An overlay - # with no module trees is fine and is not an error: that is the plain - # `make all` case with no variant built (and CI's release job, which never - # runs `make rt` locally, populates the overlay from artifacts BEFORE its - # `make all` — so it passes here too). - local kdir kver listing dbg="" - for kdir in "$EXTRA_MODULES_OVERLAY"/usr/lib/modules/*/; do - [ -d "$kdir" ] || continue # unmatched glob stays literal — skip it - kver=$(basename "$kdir") - [ -n "$dbg" ] || dbg=$(resolve_debugfs) - # debugfs -p prints one /ino/mode/uid/gid/name/... record per entry and - # exits 0 even when the lookup fails, so success is judged by the OUTPUT - # (records start '/'), not the exit status — same reasoning as - # check-linux-img.sh's ssh_keys listing. - listing=$("$dbg" -R "ls -p /usr/lib/modules/$kver" "$OUR_LINUX_IMG" 2>/dev/null || true) - printf '%s\n' "$listing" | grep -q '^/[0-9]' \ - || die "linux.img lacks /usr/lib/modules/$kver, which the extra-modules overlay stages — the image predates the overlay (was 'make all' run BEFORE 'make rt'?). Re-run 'make all' to fold the tree into linux.img, or a dev who drops the matching variant kernel onto this card boots it with no modules (docs/rt-beta-kernel.md §5)" - log "linux.img carries /usr/lib/modules/$kver (matches the overlay)" - done # The installer pieces authored by the sibling tasks. [ -f "$INSTALLER_DEFCONFIG_FILE" ] || die "missing installer defconfig: $INSTALLER_DEFCONFIG_FILE" @@ -436,7 +396,7 @@ build_installer_kernel() { # restores the shipped artifact from the pre-relink snapshot on any early exit, # and disarm it once the normal restore has run. (The kernel build tree under # output/build/linux-*/ still references the installer cpio after such a failure, - # but the next `make all` self-corrects via external.mk's default MISTER_INITRAMFS_CPIO; + # but the next `make all` self-corrects via linux-ext-mister-initramfs.mk's default MISTER_INITRAMFS_CPIO; # what must never be left wrong is the shipped output/images/zImage_dtb, and this # guarantees that.) Snapshot exists: snapshot_real_outputs ran before this. _restore_output_zimage() { @@ -448,7 +408,7 @@ build_installer_kernel() { trap '_restore_output_zimage' EXIT # Re-embed the installer cpio and re-link. `linux-reconfigure` re-runs the kernel - # kconfig-fixup (external.mk sets CONFIG_INITRAMFS_SOURCE=$INSTALLER_CPIO) then + # kconfig-fixup (linux-ext-mister-initramfs.mk sets CONFIG_INITRAMFS_SOURCE=$INSTALLER_CPIO) then # rebuilds + reinstalls the kernel; the trailing `all` re-runs post-image.sh # (BR2_ROOTFS_POST_IMAGE_SCRIPT) to reassemble output/images/zImage_dtb -- now the # INSTALLER kernel. Everything else in output/ is already built, so `all` is fast. @@ -461,8 +421,8 @@ build_installer_kernel() { cp -f "$OUR_ZIMAGE_DTB" "$INSTALLER_ZIMAGE_DTB" # Restore output/ to the real kernel: reconfigure back to the DEFAULT (stage-1) - # cpio -- external.mk's MISTER_INITRAMFS_CPIO default is output-initramfs/'s cpio, - # which the main build already produced -- and reassemble. Then, belt-and- + # cpio -- linux-ext-mister-initramfs.mk's MISTER_INITRAMFS_CPIO default is + # output/images/mister-initramfs.cpio, which package/mister-initramfs produced -- and reassemble. Then, belt-and- # suspenders, drop our pre-relink snapshot back over output/images/zImage_dtb. log " restoring output/ to the real kernel ..." br_make "$OUTPUT_DIR" linux-reconfigure all diff --git a/scripts/sbom-to-dependency-snapshot.py b/scripts/sbom-to-dependency-snapshot.py index e71b56f6..62d13de2 100755 --- a/scripts/sbom-to-dependency-snapshot.py +++ b/scripts/sbom-to-dependency-snapshot.py @@ -20,7 +20,7 @@ scripts/sbom-to-dependency-snapshot.py \ --manifest output/legal-info/manifest.csv \ - --manifest output-rt/legal-info/manifest.csv \ + --manifest output-de25/legal-info/manifest.csv \ --sha "$GITHUB_SHA" --ref refs/heads/master \ --job-id "$GITHUB_RUN_ID" --job-correlator Release_dependency-graph \ --job-html-url "$RUN_URL" --detector-url "$REPO_URL" \ diff --git a/scripts/test-initramfs.sh b/scripts/test-initramfs.sh index 7bcdf254..3392bcc7 100755 --- a/scripts/test-initramfs.sh +++ b/scripts/test-initramfs.sh @@ -33,19 +33,19 @@ # entry on it, so this synthetic test is the only place that regression can # ever be caught (see the case function below for the full argument). # -# Usage: scripts/test-initramfs.sh [--board de10nano|de25nano] [case ...] +# Usage: scripts/test-initramfs.sh [--board de10nano|de25nano] [--kernel default|rt] [case ...] # With no case arguments, runs all eight cases. Exit 0 iff every requested # case passed; nonzero otherwise (wired for P4.1's CI job). # # TWO BOARDS, ONE /init (ADR 0029 D11, 2026-09-06). The stage-1 /init is # arch-neutral and is built for both boards from the same fragment stack base -# (configs/fragments/initramfs-common.fragment); `--board` picks which built +# (package/mister-initramfs, built by each board's own configuration); `--board` picks which built # cpio to boot and which machine to boot it on: # -# de10nano (default) output-initramfs/images/rootfs.cpio, armv7, on +# de10nano (default) output/images/mister-initramfs.cpio, armv7, on # `qemu-system-arm -M virt` with a multi_v7_defconfig # kernel at the DE10's pinned version. -# de25nano output-initramfs-de25/images/rootfs.cpio, aarch64, on +# de25nano output-de25/images/mister-initramfs.cpio, aarch64, on # `qemu-system-aarch64 -M virt -cpu cortex-a76` with a # kernel built from the DE25's OWN product config # (board/mister/de25nano/linux.config + the shared @@ -58,18 +58,28 @@ # DE10 leg deliberately does not (its product kernel # cannot run under QEMU at all). # +# ONE BOARD, TWO KERNEL SERIES (2026-09-11). `--kernel rt` (de10nano only) +# runs the same DE10 leg against the RT kernel's pin (BR2_PACKAGE_LINUX_RT_VERSION, +# 7.2.y) with the RT series' own re-anchored board patch 0031 +# (board/mister/de10nano/linux-patches-beta/). 7.x exfat is iomap-based and +# 0031 had to be rewritten for it; the DE25 leg executes that rewrite on +# aarch64, but the DE10-Nano runs it as 32-bit ARM, which nothing else boots +# -- the first field `ln -s` on an RT-booted board Oopsed (page_symlink -> +# NULL write_begin, 2026-09-11, before the rewrite had shipped there). This +# leg is the 32-bit proof; its caches live under work/test-initramfs-rt*. +# # Every case, cmdline and assertion is identical between the two legs. The -# cross compiler for the DE25 leg is the stage-1 build's own musl toolchain -# (output-initramfs-de25/host/bin), so `make de25-initramfs` is the only +# cross compiler for the DE25 leg is the DE25 build's own glibc toolchain +# (output-de25/host/bin), so `make de25` is the only # build prerequisite -- no `make de25` needed. # # Prerequisites (all checked explicitly, with an actionable message, before # anything runs): -# - `make initramfs` (or `make de25-initramfs`) already run, so the cpio +# - `make mister-initramfs` (or `make de25`, with the DE25 stack enabling the extension) already run, so the cpio # exists # - the matching Buildroot cross toolchain on PATH or under the output dir # the board uses (arm-buildroot-linux-gnueabihf-gcc from output/host/bin; -# aarch64-buildroot-linux-musl-gcc from output-initramfs-de25/host/bin) +# aarch64-buildroot-linux-gnu-gcc from output-de25/host/bin) # - qemu-system-arm / qemu-system-aarch64, mkfs.vfat, mkfs.exfat, sfdisk, # mke2fs, cpio, mtools (mcopy, mmd) # - a QEMU-bootable test kernel: reused from a cache @@ -91,11 +101,18 @@ SUPPORT="$HERE/test-initramfs" # environment is the same switch for callers that cannot pass arguments # (ci-tests.sh's per-board legs use the flag). BOARD="${TEST_INITRAMFS_BOARD:-de10nano}" +# `--kernel` picks which of the board's kernel series the QEMU test kernel is +# built at: `default` (BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE, the shipped +# kernel) or `rt` (BR2_PACKAGE_LINUX_RT_VERSION with the RT series' own patch +# 0031). TEST_INITRAMFS_KERNEL is the environment form. +KERNEL="${TEST_INITRAMFS_KERNEL:-default}" _args=() while [ "$#" -gt 0 ]; do case "$1" in --board) shift; BOARD="${1:-}" ;; --board=*) BOARD="${1#--board=}" ;; + --kernel) shift; KERNEL="${1:-}" ;; + --kernel=*) KERNEL="${1#--kernel=}" ;; *) _args+=("$1") ;; esac shift @@ -104,8 +121,8 @@ set -- ${_args[@]+"${_args[@]}"} case "$BOARD" in de10nano) - CPIO="$ROOT/output-initramfs/images/rootfs.cpio" - CPIO_MAKE_TARGET="initramfs" + CPIO="$ROOT/output/images/mister-initramfs.cpio" + CPIO_MAKE_TARGET="mister-initramfs" KARCH=arm CROSS_COMPILE="${CROSS_COMPILE:-arm-buildroot-linux-gnueabihf-}" TOOLCHAIN_BIN="$ROOT/output/host/bin" @@ -116,16 +133,17 @@ de10nano) # The generic ARM kernel: multi_v7_defconfig + this harness's fragment. KERNEL_BASE_DEFCONFIG=multi_v7_defconfig KERNEL_BASE_FILES=() - PIN_FRAGMENT="$ROOT/configs/fragments/de10nano.fragment" + PIN_FRAGMENT="$ROOT/configs/mister_de10nano_defconfig" + PIN_SYMBOL=BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE EXFAT_SYMLINK_PATCH="$ROOT/board/mister/de10nano/linux-patches/0031-exfat-samsung-symlinks.patch" CACHE_TAG="" ;; de25nano) - CPIO="$ROOT/output-initramfs-de25/images/rootfs.cpio" - CPIO_MAKE_TARGET="de25-initramfs" + CPIO="$ROOT/output-de25/images/mister-initramfs.cpio" + CPIO_MAKE_TARGET="de25 # with BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS=y in the DE25 stack (ADR 0029 D11)" KARCH=arm64 - CROSS_COMPILE="${CROSS_COMPILE:-aarch64-buildroot-linux-musl-}" - TOOLCHAIN_BIN="$ROOT/output-initramfs-de25/host/bin" + CROSS_COMPILE="${CROSS_COMPILE:-aarch64-buildroot-linux-gnu-}" + TOOLCHAIN_BIN="$ROOT/output-de25/host/bin" QEMU_SYSTEM=qemu-system-aarch64 # `-M virt` has no default CPU on aarch64; cortex-a76 is the DE25's big # core and what the stage-1 toolchain tunes for (BR2_cortex_a76_a55 -- @@ -137,7 +155,8 @@ de25nano) KERNEL_BASE_DEFCONFIG="" KERNEL_BASE_FILES=("$ROOT/board/mister/de25nano/linux.config" "$ROOT/board/mister/common/linux-mister.fragment") - PIN_FRAGMENT="$ROOT/configs/fragments/de25nano.fragment" + PIN_FRAGMENT="$ROOT/configs/mister_de25nano_defconfig" + PIN_SYMBOL=BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE # Resolved through the DE25's own patch dir, which links to the 7.x # re-anchored copy in linux-patches-beta/ (since 2026-09-06 -- this # very case found the shared 6.18 form Oopsing on 7.x, ADR 0002 §8b). @@ -150,6 +169,23 @@ de25nano) ;; esac +case "$BOARD/$KERNEL" in +*/default) + ;; +de10nano/rt) + # The RT series: its pin, its own 7.x-anchored 0031, its own caches (a + # 7.2.y source tree and O= build must never share work/ with the 6.18 + # ones -- ensure_qemu_kernel() reuses whatever it finds there). + PIN_SYMBOL=BR2_PACKAGE_LINUX_RT_VERSION + EXFAT_SYMLINK_PATCH="$ROOT/board/mister/de10nano/linux-patches-beta/0031-exfat-samsung-symlinks.patch" + CACHE_TAG="-rt" + ;; +*) + printf 'test-initramfs.sh: FATAL: unknown --kernel %s for --board %s (known: default; rt on de10nano)\n' "'$KERNEL'" "$BOARD" >&2 + exit 2 + ;; +esac + INIT_SRC="$ROOT/board/mister/common/initramfs-overlay/init" MARKER_C="$SUPPORT/marker-init.c" TEST_SYMLINK_C="$SUPPORT/test-symlink.c" @@ -171,14 +207,14 @@ KERNEL_SRC="${TEST_INITRAMFS_KERNEL_SRC:-$ROOT/work/test-initramfs$CACHE_TAG-ker # fails the QEMU kernel build with a confusing "too few arguments". Reading the # pin keeps this test kernel on the same version the image ships, which is what # this script's header already claims it does. -KERNEL_VERSION="${TEST_INITRAMFS_KERNEL_VERSION:-$(sed -n 's/^BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="\(.*\)"$/\1/p' "$PIN_FRAGMENT")}" +KERNEL_VERSION="${TEST_INITRAMFS_KERNEL_VERSION:-$(sed -n "s/^$PIN_SYMBOL=\"\(.*\)\"\$/\1/p" "$PIN_FRAGMENT")}" # Inline, not die() -- that is defined further down, and this block runs before # it. Under `set -uo pipefail` (no -e) an undefined-function call would print # "command not found" and CARRY ON, which is exactly the silent failure this # guard exists to prevent. [ -n "$KERNEL_VERSION" ] || { printf 'test-initramfs.sh: FATAL: %s\n' \ - "could not read BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE from ${PIN_FRAGMENT#"$ROOT"/}" >&2 + "could not read $PIN_SYMBOL from ${PIN_FRAGMENT#"$ROOT"/}" >&2 exit 2 } # The pristine source tarball. Buildroot's own kernel build fetches it into @@ -1021,7 +1057,7 @@ main() { ensure_qemu_kernel build_marker_inits - log "board: $BOARD ($KARCH, $QEMU_SYSTEM ${QEMU_MACHINE[*]}, kernel $KERNEL_VERSION, cpio ${CPIO#"$ROOT"/})" + log "board: $BOARD ($KARCH, $QEMU_SYSTEM ${QEMU_MACHINE[*]}, kernel $KERNEL_VERSION [$KERNEL series, $(basename "$(dirname "$EXFAT_SYMLINK_PATCH")")/0031], cpio ${CPIO#"$ROOT"/})" log "running ${#requested[@]} case(s): ${requested[*]}" echo "" local c diff --git a/scripts/test-sdcard-install.sh b/scripts/test-sdcard-install.sh index eb9d3c96..33950811 100755 --- a/scripts/test-sdcard-install.sh +++ b/scripts/test-sdcard-install.sh @@ -64,10 +64,10 @@ CROSS_COMPILE="${CROSS_COMPILE:-$ROOT/output/host/bin/arm-buildroot-linux-gnueab # scripts/test-initramfs.sh (board patch 0031, applied below, tracks the pinned # kernel's APIs; 6.18.40 gave exfat_remove_entries() a 4th arg, so a stale pin # here fails the QEMU kernel build with a confusing "too few arguments"). -KERNEL_VERSION="${TEST_SDCARD_KERNEL_VERSION:-$(sed -n 's/^BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="\(.*\)"$/\1/p' "$ROOT/configs/fragments/de10nano.fragment")}" +KERNEL_VERSION="${TEST_SDCARD_KERNEL_VERSION:-$(sed -n 's/^BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="\(.*\)"$/\1/p' "$ROOT/configs/mister_de10nano_defconfig")}" [ -n "$KERNEL_VERSION" ] || { printf 'test-sdcard-install.sh: FATAL: %s\n' \ - "could not read BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE from configs/fragments/de10nano.fragment" >&2 + "could not read BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE from configs/mister_de10nano_defconfig" >&2 exit 2 } KERNEL_TARBALL="${TEST_SDCARD_KERNEL_TARBALL:-$ROOT/dl/linux-$KERNEL_VERSION.tar.xz}" diff --git a/sdk.log b/sdk.log new file mode 100644 index 00000000..e3e67d54 --- /dev/null +++ b/sdk.log @@ -0,0 +1,208 @@ +==> host 'install' is not GNU; shimming /usr/bin/gnuinstall into PATH for Buildroot +PATH="/mnt/source/Buildroot_MiSTer-vanilla/work/.hostshim:$PATH" make -C /mnt/source/Buildroot_MiSTer-vanilla/work/buildroot O=/mnt/source/Buildroot_MiSTer-vanilla/output BR2_EXTERNAL=/mnt/source/Buildroot_MiSTer-vanilla sdk +make[1]: Entering directory '/mnt/source/Buildroot_MiSTer-vanilla/work/buildroot' +/mnt/source/Buildroot_MiSTer-vanilla/package/linux-rt/linux-rt.mk:119: warning: overriding recipe for target '/mnt/source/Buildroot_MiSTer-vanilla/board/mister/de10nano/linux.config' +linux/linux.mk:700: warning: ignoring old recipe for target '/mnt/source/Buildroot_MiSTer-vanilla/board/mister/de10nano/linux.config' +>>> Finalizing host directory +>>> Finalizing target directory +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/src/hare +mkdir -p /mnt/source/Buildroot_MiSTer-vanilla/output/host/etc/meson +sed -e "s%@TARGET_CFLAGS@%'-D_LARGEFILE_SOURCE', '-D_LARGEFILE64_SOURCE', '-D_FILE_OFFSET_BITS=64', '-O2', '-g0', '-D_FORTIFY_SOURCE=1'@PKG_TARGET_CFLAGS@%g" -e "s%@TARGET_LDFLAGS@%@PKG_TARGET_LDFLAGS@%g" -e "s%@TARGET_CXXFLAGS@%'-D_LARGEFILE_SOURCE', '-D_LARGEFILE64_SOURCE', '-D_FILE_OFFSET_BITS=64', '-O2', '-g0', '-D_FORTIFY_SOURCE=1'@PKG_TARGET_CXXFLAGS@%g" -e "s%@TARGET_FCFLAGS@%'-O2', '-g0'@PKG_TARGET_FCFLAGS@%g" -e "s%@TARGET_CC@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-gcc%g" -e "s%@TARGET_CXX@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-g++%g" -e "s%@TARGET_AR@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-gcc-ar%g" -e "s%@TARGET_FC@%/bin/false%g" -e "s%@TARGET_STRIP@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-strip%g" -e "s%@TARGET_ARCH@%arm%g" -e "s%@TARGET_CPU@%cortex-a9%g" -e "s%@TARGET_ENDIAN@%little%g" -e "s%@TARGET_FCFLAGS@%%g" -e "s%@TARGET_CFLAGS@%%g" -e "s%@TARGET_LDFLAGS@%%g" -e "s%@TARGET_CXXFLAGS@%%g" -e "s%@BR2_CMAKE@%/usr/bin/cmake%g" -e "s%@PKGCONF_HOST_BINARY@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/pkgconf%g" -e "s%@HOST_DIR@%/mnt/source/Buildroot_MiSTer-vanilla/output/host%g" -e "s%@STAGING_DIR@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/arm-buildroot-linux-gnueabihf/sysroot%g" -e "s%@STATIC@%false%g" /mnt/source/Buildroot_MiSTer-vanilla/work/buildroot/support/misc/cross-compilation.conf.in > /mnt/source/Buildroot_MiSTer-vanilla/output/host/etc/meson/cross-compilation.conf.in +sed -e "s%@TARGET_CC@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-gcc%g" -e "s%@TARGET_CXX@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-g++%g" -e "s%@TARGET_AR@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-gcc-ar%g" -e "s%@TARGET_FC@%/bin/false%g" -e "s%@TARGET_STRIP@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-strip%g" -e "s%@TARGET_ARCH@%arm%g" -e "s%@TARGET_CPU@%cortex-a9%g" -e "s%@TARGET_ENDIAN@%little%g" -e "s%@TARGET_FCFLAGS@%'-O2', '-g0'%g" -e "s%@TARGET_CFLAGS@%'-D_LARGEFILE_SOURCE', '-D_LARGEFILE64_SOURCE', '-D_FILE_OFFSET_BITS=64', '-O2', '-g0', '-D_FORTIFY_SOURCE=1'%g" -e "s%@TARGET_LDFLAGS@%%g" -e "s%@TARGET_CXXFLAGS@%'-D_LARGEFILE_SOURCE', '-D_LARGEFILE64_SOURCE', '-D_FILE_OFFSET_BITS=64', '-O2', '-g0', '-D_FORTIFY_SOURCE=1'%g" -e "s%@BR2_CMAKE@%/usr/bin/cmake%g" -e "s%@PKGCONF_HOST_BINARY@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/pkgconf%g" -e "s%@HOST_DIR@%/mnt/source/Buildroot_MiSTer-vanilla/output/host%g" -e "s%@STAGING_DIR@%/mnt/source/Buildroot_MiSTer-vanilla/output/host/arm-buildroot-linux-gnueabihf/sysroot%g" -e "s%@STATIC@%false%g" /mnt/source/Buildroot_MiSTer-vanilla/work/buildroot/support/misc/cross-compilation.conf.in > /mnt/source/Buildroot_MiSTer-vanilla/output/host/etc/meson/cross-compilation.conf +grep -qsE '^/bin/bash$' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shells || echo "/bin/bash" >> /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shells +/usr/bin/sed -i -e '/# GENERIC_SERIAL$/s~^.*#~console::respawn:/sbin/getty -L console 0 vt100 #~' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/inittab +/usr/bin/sed -i -e '/^#.*-o remount,rw \/$/s~^#\+~~' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/inittab +if grep -q CONFIG_ASH=y /mnt/source/Buildroot_MiSTer-vanilla/output/build/busybox-1.38.0/.config; then grep -qsE '^/bin/ash$' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shells || echo "/bin/ash" >> /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shells; fi +if grep -q CONFIG_HUSH=y /mnt/source/Buildroot_MiSTer-vanilla/output/build/busybox-1.38.0/.config; then grep -qsE '^/bin/hush$' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shells || echo "/bin/hush" >> /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shells; fi +# Remove any existing certificates under /etc/ssl/certs +rm -f /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/ssl/certs/* +# Create symlinks to certificates under /etc/ssl/certs +# and generate the bundle +cd /mnt/source/Buildroot_MiSTer-vanilla/output/target ; for i in `find usr/share/ca-certificates -name "*.crt" | LC_COLLATE=C sort` ; do ln -sf ../../../$i etc/ssl/certs/`basename ${i} .crt`.pem ; cat $i ; done >/mnt/source/Buildroot_MiSTer-vanilla/output/build/ca-certificates.crt +# Create symlinks to the certificates by their hash values +/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/c_rehash /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/ssl/certs +Doing /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/ssl/certs +# Install the certificates bundle +/mnt/source/Buildroot_MiSTer-vanilla/work/.hostshim/install -D -m 644 /mnt/source/Buildroot_MiSTer-vanilla/output/build/ca-certificates.crt /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/ssl/certs/ca-certificates.crt +/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/udevadm hwdb --update --usr --root /mnt/source/Buildroot_MiSTer-vanilla/output/target +find /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share \( -iname "*.gir" -o -iname \*.rnc \) -delete +rm -f /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/glib-2.0/schemas/*.xml /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/glib-2.0/schemas/*.dtd +/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/glib-compile-schemas /mnt/source/Buildroot_MiSTer-vanilla/output/host/arm-buildroot-linux-gnueabihf/sysroot/usr/share/glib-2.0/schemas --targetdir=/mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/glib-2.0/schemas +No schema files found: doing nothing. +find /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/python3.14 -name '*.py' -print0 | xargs -0 --no-run-if-empty touch -d @1788535000 +PYTHONPATH="/mnt/source/Buildroot_MiSTer-vanilla/output/host/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/python3.14/" /mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/python3.14 /mnt/source/Buildroot_MiSTer-vanilla/output/build/python3-3.14.7/Lib/compileall.py -q -b -s /mnt/source/Buildroot_MiSTer-vanilla/output/target -p / /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/python3.14 +find /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/python3.14 -name '*.py' -print0 | xargs -0 --no-run-if-empty rm -f +find /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/python3.14 -name '*.opt-1.pyc' -print0 -o -name '*.opt-2.pyc' -print0 | xargs -0 --no-run-if-empty rm -f +mkdir -p /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc +echo "buildroot" > /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/hostname +/usr/bin/sed -i -e '$a \127.0.1.1\tbuildroot' -e '/^127.0.1.1/d' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/hosts +mkdir -p /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc +echo "Welcome to Buildroot" > /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/issue +/usr/bin/sed -i -e s,^root:[^:]*:,root::, /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shadow +grep -qsE '^/bin/sh$' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shells || echo "/bin/sh" >> /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shells +ln -sf bash /mnt/source/Buildroot_MiSTer-vanilla/output/target/bin/sh +/usr/bin/sed -i -e '/^root:/s,[^/]*$,bash,' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/passwd +if [ -x /mnt/source/Buildroot_MiSTer-vanilla/output/target/sbin/swapon -a -x /mnt/source/Buildroot_MiSTer-vanilla/output/target/sbin/swapoff ]; then /usr/bin/sed -i -e '/^#.*\/sbin\/swap/s/^#\+[[:blank:]]*//' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/inittab; else /usr/bin/sed -i -e '/^[^#].*\/sbin\/swap/s/^/#/' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/inittab; fi +grep -qsE '^/usr/bin/tmux$' /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shells || echo "/usr/bin/tmux" >> /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/shells +if test -d /mnt/source/Buildroot_MiSTer-vanilla/output/target/lib/modules/`MAKEFLAGS='' /usr/bin/make -j33 HOSTCC="/usr/bin/gcc -O2 -isystem /mnt/source/Buildroot_MiSTer-vanilla/output/host/include -L/mnt/source/Buildroot_MiSTer-vanilla/output/host/lib -Wl,-rpath,/mnt/source/Buildroot_MiSTer-vanilla/output/host/lib" ARCH=arm KCFLAGS="-Wno-attribute-alias" INSTALL_MOD_PATH=/mnt/source/Buildroot_MiSTer-vanilla/output/target CROSS_COMPILE="/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-" WERROR=0 REGENERATE_PARSERS=1 DEPMOD=true INSTALL_MOD_STRIP=1 -C /mnt/source/Buildroot_MiSTer-vanilla/output/build/linux-6.18.50 --no-print-directory -s kernelrelease 2>/dev/null` && grep -q "CONFIG_MODULES=y" /mnt/source/Buildroot_MiSTer-vanilla/output/build/linux-6.18.50/.config; then /mnt/source/Buildroot_MiSTer-vanilla/output/host/sbin/depmod -a -b /mnt/source/Buildroot_MiSTer-vanilla/output/target `MAKEFLAGS='' /usr/bin/make -j33 HOSTCC="/usr/bin/gcc -O2 -isystem /mnt/source/Buildroot_MiSTer-vanilla/output/host/include -L/mnt/source/Buildroot_MiSTer-vanilla/output/host/lib -Wl,-rpath,/mnt/source/Buildroot_MiSTer-vanilla/output/host/lib" ARCH=arm KCFLAGS="-Wno-attribute-alias" INSTALL_MOD_PATH=/mnt/source/Buildroot_MiSTer-vanilla/output/target CROSS_COMPILE="/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-" WERROR=0 REGENERATE_PARSERS=1 DEPMOD=true INSTALL_MOD_STRIP=1 -C /mnt/source/Buildroot_MiSTer-vanilla/output/build/linux-6.18.50 --no-print-directory -s kernelrelease 2>/dev/null`; fi +>>> linux-rt 7.2.4: module tree depmod'd in /mnt/source/Buildroot_MiSTer-vanilla/output/target/lib/modules/7.2.4 +/usr/bin/make -j33 -f support/misc/gen-glibc-locales.mk ENDIAN="little" LOCALES="en_US.UTF-8" Q=@ +make[2]: Entering directory '/mnt/source/Buildroot_MiSTer-vanilla/work/buildroot' +Generating locale en_US.UTF-8 +Adding /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/locale/en_US.utf8 +make[2]: Leaving directory '/mnt/source/Buildroot_MiSTer-vanilla/work/buildroot' +printf '%s\n' C en_US locale-archive > /mnt/source/Buildroot_MiSTer-vanilla/output/build/locales.nopurge +for dir in /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/locale /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/X11/locale /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/locale; do if [ ! -d $dir ]; then continue; fi; for langdir in $dir/*; do if [ -e "${langdir}" ]; then grep -qx "${langdir##*/}" /mnt/source/Buildroot_MiSTer-vanilla/output/build/locales.nopurge || rm -rf $langdir; fi done; done +if [ -d /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/X11/locale ]; then for lang in C en_US; do if [ -f /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/X11/locale/$lang/XLC_LOCALE ]; then echo "$lang/XLC_LOCALE: $lang"; fi done > /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/X11/locale/locale.dir; fi +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/include /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/aclocal \ + /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/pkgconfig /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/pkgconfig \ + /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/cmake /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/cmake \ + /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/rpm /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/doc +find /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/{lib,share}/ -name '*.cmake' -print0 | xargs -0 rm -f +find /mnt/source/Buildroot_MiSTer-vanilla/output/target/lib/ /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/ /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/libexec/ \ + \( -name '*.a' -o -name '*.la' -o -name '*.prl' \) -print0 | xargs -0 rm -f +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/zsh +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/man /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/man +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/info /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/info +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/doc /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/doc +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share/gtk-doc +rmdir /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/share 2>/dev/null || true +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/target/lib/debug /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/debug +find /mnt/source/Buildroot_MiSTer-vanilla/output/target -type f \( -perm /111 -o -name '*.so*' \) -not \( -name 'libpthread*.so*' -o -name 'ld-*.so*' -o -name '*.ko' \) -print0 | xargs -0 /mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-strip --remove-section=.comment --remove-section=.note 2>/dev/null || true +find /mnt/source/Buildroot_MiSTer-vanilla/output/target \( -name 'ld-*.so*' -o -name 'libpthread*.so*' \) -print0 | xargs -0 -r /mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/arm-buildroot-linux-gnueabihf-strip --remove-section=.comment --remove-section=.note --strip-debug 2>/dev/null || true +test -f /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/ld.so.conf && \ + { echo "ERROR: we shouldn't have a /etc/ld.so.conf file"; exit 1; } || true +test -d /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc/ld.so.conf.d && \ + { echo "ERROR: we shouldn't have a /etc/ld.so.conf.d directory"; exit 1; } || true +mkdir -p /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc +( \ + echo "NAME=Buildroot"; \ + echo "VERSION=v2026.09.11-beta-11-g4118964"; \ + echo "ID=buildroot"; \ + echo "VERSION_ID=2026.08"; \ + echo "PRETTY_NAME=\"Buildroot 2026.08\"" \ +) > /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr/lib/os-release +ln -sf ../usr/lib/os-release /mnt/source/Buildroot_MiSTer-vanilla/output/target/etc +>>> Sanitizing RPATH in target tree +PARALLEL_JOBS=33 \ + PER_PACKAGE_DIR=/mnt/source/Buildroot_MiSTer-vanilla/output/per-package \ + /mnt/source/Buildroot_MiSTer-vanilla/work/buildroot/support/scripts/fix-rpath target +>>> Sanity check in overlays /mnt/source/Buildroot_MiSTer-vanilla/board/mister/de10nano/rootfs-overlay +support/scripts/check-merged \ + -t overlay \ + -u \ + \ + /mnt/source/Buildroot_MiSTer-vanilla/board/mister/de10nano/rootfs-overlay +>>> Copying overlay /mnt/source/Buildroot_MiSTer-vanilla/board/mister/de10nano/rootfs-overlay +>>> Executing post-build script ../../board/mister/de10nano/post-build.sh +post-build.sh: pinned root password (stock-parity '1', fixed salt) +post-build.sh: wrote /MiSTer.version = 260904 (6 bytes, no newline) +touch /mnt/source/Buildroot_MiSTer-vanilla/output/target/usr +>>> Generating root filesystems common tables +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs +mkdir -p /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs +printf ' dbus -1 dbus -1 * /run/dbus - dbus DBus messagebus user\n dhcpcd -1 dhcpcd -1 * - - - dhcpcd user\n ntp -1 ntp -1 * - - - ntpd user\n sshd -1 sshd -1 * /var/empty - - SSH drop priv user\n ftp -1 ftp -1 * /home/ftp - - Anonymous FTP User\n - - sudo -1 - - - -\n - - input -1 * - - - Input device group\n - - kvm -1 * - - - kvm nodes\n - - sgx -1 * - - - SGX device nodes\n\n' >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/full_users_table.txt +printf ' /bin/busybox f 4755 0 0 - - - - -\n /usr/libexec/dbus-daemon-launch-helper f 4750 0 dbus - - - - -\n /usr/bin/fusermount f 4755 0 0 - - - - -\n /var/empty d 755 root root - - - - -\n /usr/bin/sudo f 4755 0 0 - - - - -\n\n' > /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/full_devices_table.txt +cat system/device_table.txt >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/full_devices_table.txt +>>> Generating filesystem image rootfs.ext2 +mkdir -p /mnt/source/Buildroot_MiSTer-vanilla/output/images +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2 +mkdir -p /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2 +rsync -auH --exclude=/THIS_IS_NOT_YOUR_ROOT_FILESYSTEM /mnt/source/Buildroot_MiSTer-vanilla/output/target/ /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target +echo '#!/bin/sh' > /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +echo "set -e" >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +echo "chown -h -R 0:0 /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target" >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +PATH="/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin:/mnt/source/Buildroot_MiSTer-vanilla/output/host/sbin:/mnt/source/Buildroot_MiSTer-vanilla/work/.hostshim:/home/mcf/.local/bin:/home/mcf/.local/bin:/home/mcf/.nvm/versions/node/v24.15.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/snap/bin" /mnt/source/Buildroot_MiSTer-vanilla/work/buildroot/support/scripts/mkusers /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/full_users_table.txt /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +echo "/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/makedevs -d /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/full_devices_table.txt /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target" >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +printf ' rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target/usr/lib/udev/hwdb.d/ /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target/etc/udev/hwdb.d/\n' >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +echo "find /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target/run/ -mindepth 1 -prune -print0 | xargs -0r rm -rf --" >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +echo "find /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target/tmp/ -mindepth 1 -prune -print0 | xargs -0r rm -rf --" >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +printf ' find /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target -print0 | xargs -0 -r touch -hd @1788535000\n' >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +printf ' \n' >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +printf ' rm -f /mnt/source/Buildroot_MiSTer-vanilla/output/images/rootfs.ext2\n /mnt/source/Buildroot_MiSTer-vanilla/output/host/sbin/mkfs.ext4 -d /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target -N 0 -m 5 -L "rootfs" -I 256 -U 71916572-439f-448e-b8d8-12b0a032fa56 -E hash_seed=9afc615c-c310-4e03-ada9-613522e83ae6 -b 4096 -O has_journal,ext_attr,resize_inode,dir_index,filetype,extent,64bit,flex_bg,sparse_super,large_file,huge_file,dir_nlink,extra_isize,metadata_csum,^metadata_csum_seed,^orphan_file /mnt/source/Buildroot_MiSTer-vanilla/output/images/rootfs.ext2 "512M" || { ret=$?; echo "*** Maybe you need to increase the filesystem size (BR2_TARGET_ROOTFS_EXT2_SIZE)" 1>&2; exit $ret; }\n' >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +chmod a+x /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +PATH="/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin:/mnt/source/Buildroot_MiSTer-vanilla/output/host/sbin:/mnt/source/Buildroot_MiSTer-vanilla/work/.hostshim:/home/mcf/.local/bin:/home/mcf/.local/bin:/home/mcf/.nvm/versions/node/v24.15.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/snap/bin" FAKEROOTDONTTRYCHOWN=1 /mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/fakeroot -- /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/fakeroot +rootdir=/mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/ext2/target +table='/mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/full_devices_table.txt' +mke2fs 1.47.4 (6-Mar-2025) +Creating regular file /mnt/source/Buildroot_MiSTer-vanilla/output/images/rootfs.ext2 +Creating filesystem with 131072 4k blocks and 32768 inodes +Filesystem UUID: 71916572-439f-448e-b8d8-12b0a032fa56 +Superblock backups stored on blocks: + 32768, 98304 + +Allocating group tables: 0/4 done +Writing inode tables: 0/4 done +Creating journal (4096 blocks): done +Copying files into the device: done +Writing superblocks and filesystem accounting information: 0/4 done + +ln -sf rootfs.ext2 /mnt/source/Buildroot_MiSTer-vanilla/output/images/rootfs.ext4 +>>> Generating filesystem image rootfs.tar +mkdir -p /mnt/source/Buildroot_MiSTer-vanilla/output/images +rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar +mkdir -p /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar +rsync -auH --exclude=/THIS_IS_NOT_YOUR_ROOT_FILESYSTEM /mnt/source/Buildroot_MiSTer-vanilla/output/target/ /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target +echo '#!/bin/sh' > /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +echo "set -e" >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +echo "chown -h -R 0:0 /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target" >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +PATH="/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin:/mnt/source/Buildroot_MiSTer-vanilla/output/host/sbin:/mnt/source/Buildroot_MiSTer-vanilla/work/.hostshim:/home/mcf/.local/bin:/home/mcf/.local/bin:/home/mcf/.nvm/versions/node/v24.15.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/snap/bin" /mnt/source/Buildroot_MiSTer-vanilla/work/buildroot/support/scripts/mkusers /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/full_users_table.txt /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +echo "/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/makedevs -d /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/full_devices_table.txt /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target" >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +printf ' rm -rf /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target/usr/lib/udev/hwdb.d/ /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target/etc/udev/hwdb.d/\n' >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +echo "find /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target/run/ -mindepth 1 -prune -print0 | xargs -0r rm -rf --" >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +echo "find /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target/tmp/ -mindepth 1 -prune -print0 | xargs -0r rm -rf --" >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +printf ' find /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target -print0 | xargs -0 -r touch -hd @1788535000\n' >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +printf ' \n' >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +printf ' (cd /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target; find -print0 | LC_ALL=C sort -z | tar --pax-option=exthdr.name=%%d/PaxHeaders/%%f,atime:=0,ctime:=0 -cf /mnt/source/Buildroot_MiSTer-vanilla/output/images/rootfs.tar --null --xattrs-include='\''*'\'' --no-recursion -T - --numeric-owner)\n' >> /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +chmod a+x /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +PATH="/mnt/source/Buildroot_MiSTer-vanilla/output/host/bin:/mnt/source/Buildroot_MiSTer-vanilla/output/host/sbin:/mnt/source/Buildroot_MiSTer-vanilla/work/.hostshim:/home/mcf/.local/bin:/home/mcf/.local/bin:/home/mcf/.nvm/versions/node/v24.15.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/snap/bin" FAKEROOTDONTTRYCHOWN=1 /mnt/source/Buildroot_MiSTer-vanilla/output/host/bin/fakeroot -- /mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/fakeroot +rootdir=/mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/tar/target +table='/mnt/source/Buildroot_MiSTer-vanilla/output/build/buildroot-fs/full_devices_table.txt' +>>> Executing post-image script ../../board/mister/de10nano/post-image.sh +post-image.sh: zImage = /mnt/source/Buildroot_MiSTer-vanilla/output/images/zImage (9696920 bytes) +post-image.sh: dtb = /mnt/source/Buildroot_MiSTer-vanilla/output/images/socfpga_cyclone5_de10nano.dtb (20377 bytes) +post-image.sh: wrote /mnt/source/Buildroot_MiSTer-vanilla/output/images/zImage_dtb (9717297 bytes) +check-zimage-dtb.sh: /mnt/source/Buildroot_MiSTer-vanilla/output/images/zImage_dtb (9717297 bytes) +ok zImage magic 0x016f2818 present at +0x24 + zImage declared start (+0x28) = 0 + zImage declared end (+0x2C) = 9696920 <- U-Boot's fdt_addr offset + U-Boot computes fdt_addr = 0x01000000 + 0x0093f698 = 0x0193f698 +ok DTB magic 0xd00dfeed sits exactly at the declared end (9696920) + DTB totalsize = 20377 +ok DTB totalsize reaches exactly EOF (9696920 + 20377 = 9717297) +ok size 9717297 < 16 MiB budget (headroom 7059919 bytes, top addr 0x01944631) +check-zimage-dtb.sh: all assertions passed +post-image.sh: wrote /mnt/source/Buildroot_MiSTer-vanilla/output/images/linux.img (536870912 bytes, hardlink of /mnt/source/Buildroot_MiSTer-vanilla/output/images/rootfs.ext2) +check-linux-img.sh: /mnt/source/Buildroot_MiSTer-vanilla/output/images/linux.img (536870912 bytes) +ok size == 536870912 bytes (512 MiB) +ok volume label = 'rootfs' +ok filesystem UUID = 71916572-439f-448e-b8d8-12b0a032fa56 (pinned) +ok directory hash seed = 9afc615c-c310-4e03-ada9-613522e83ae6 (pinned) + features (as built): has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum +ok feature set matches the pinned 14-feature stock-derived list exactly +ok no ssh_host_* files anywhere in the image (ADR 0015) +ok dhcpcd hook set is exactly the pinned one (01-test 20-resolv.conf 30-hostname 50-ntp.conf 90-timezone 91-ntp-kick) +ok dhcpcd example-hook set is exactly the pinned one (10-wpa_supplicant 15-timezone 29-lookup-hostname 50-yp.conf) +ok /etc/ssh_keys is present and empty in the image (keys are runtime state, not build output) +check-linux-img.sh: all assertions passed +>>> Preparing the SDK +/mnt/source/Buildroot_MiSTer-vanilla/work/.hostshim/install -m 755 /mnt/source/Buildroot_MiSTer-vanilla/work/buildroot/support/misc/relocate-sdk.sh /mnt/source/Buildroot_MiSTer-vanilla/output/host/relocate-sdk.sh +mkdir -p /mnt/source/Buildroot_MiSTer-vanilla/output/host/share/buildroot +(\ + export LC_ALL=C; \ + grep -lr '/mnt/source/Buildroot_MiSTer-vanilla/output/host' '/mnt/source/Buildroot_MiSTer-vanilla/output/host' | while read -r FILE; do \ + if file -b --mime-type "$FILE" | grep -q '^text/' && \ + [ "$FILE" != '/mnt/source/Buildroot_MiSTer-vanilla/output/host/share/buildroot/sdk-location' ] && \ + [ "$FILE" != '/mnt/source/Buildroot_MiSTer-vanilla/output/host/share/buildroot/sdk-relocs' ]; then \ + echo "$FILE"; \ + fi; \ + done \ +) | sed -e 's|^/mnt/source/Buildroot_MiSTer-vanilla/output/host|.|g' > /mnt/source/Buildroot_MiSTer-vanilla/output/host/share/buildroot/sdk-relocs +echo /mnt/source/Buildroot_MiSTer-vanilla/output/host > /mnt/source/Buildroot_MiSTer-vanilla/output/host/share/buildroot/sdk-location +>>> Generating SDK tarball +tar czf "/mnt/source/Buildroot_MiSTer-vanilla/output/images/arm-buildroot-linux-gnueabihf_sdk-buildroot.tar.gz" \ + --owner=0 --group=0 --numeric-owner \ + --transform='s#^mnt/source/Buildroot_MiSTer-vanilla/output/host#arm-buildroot-linux-gnueabihf_sdk-buildroot#' \ + -C / mnt/source/Buildroot_MiSTer-vanilla/output/host +make[1]: Leaving directory '/mnt/source/Buildroot_MiSTer-vanilla/work/buildroot' +exit=0