blob: ca312e5b8f82d9cd38cdbe8e825a2d886f0ac078 [file] [view]
# AGENTS.md
Guidance for AI coding agents (Claude Code, Codex, etc.) working in this
repository. Humans should start with [README.md](README.md); this file
restates the contribution rules in the operational order an agent needs them.
License-acceptability questions whether a particular license text is
acceptable for inclusion are governed by
[LICENSE-CRITERIA.md](LICENSE-CRITERIA.md).
## What this repository is
This is **linux-firmware**, the upstream collection of binary firmware images
loaded by the Linux kernel at runtime. It is *not* a normal software project:
- The payload is **normally binary blobs** rather than source you build here
though contributors *may* provide source, and it's welcome where the firmware
owner permits it (see `keyspan_pda/` for a built-from-source example). The
large majority are redistributed binaries.
- The most important file is **`WHENCE`** — a hand-maintained manifest that
records the origin, license, and redistribution terms of *every* file.
- The repository's core value is **licensing provenance**, not code. Most of
the rules below exist to keep that provenance accurate and auditable.
Upstream lives at <https://gitlab.com/kernel-firmware/linux-firmware.git>.
## Golden rules (read before any change)
1. **Every file in git must be accounted for** *almost always* by a `WHENCE`
entry. Adding a firmware blob without one breaks the build; removing or
renaming one without updating `WHENCE` does too. There are two kinds of
exception:
- **Repository tooling/metadata** (this file, `README.md`,
`check_whence.py`, etc.) is registered in the `known_files` allowlist
*inside* `check_whence.py`.
- **License texts** live in the `LICENSES/` directory and are accounted for
by being referenced from a `Licence:` line in `WHENCE` (e.g.
`See LICENCE.foo for details.`) not by a `File:` entry.
If `make check` reports a file is unaccounted for, place it in the right
bucket above. **Don't add tooling or license files to `WHENCE` as `File:`
entries** to silence a check (see "Things to leave alone").
2. **Never invent license information.** The license and the redistributability
of a blob are facts that come from the firmware's owner usually conveyed in
the submitter's commit and `Signed-off-by`. If you don't have it, don't guess.
Surface the gap to the user instead. When evaluating whether a license *text*
is acceptable, apply the criteria in
[LICENSE-CRITERIA.md](LICENSE-CRITERIA.md) sections 3.1–3.3 — do not guess
at acceptability, and do not fabricate the underlying license facts.
3. **Always run `make check` before considering a change complete** (see below).
4. **Preserve the `Signed-off-by` line.** It is a legal attestation of the right
to redistribute. Never add, fabricate, or alter one on someone's behalf.
5. **Don't edit binary firmware files.** Agents add, move, link, or remove
blobs and document them; they do not modify blob contents.
## The most common task: adding or updating a firmware file
1. Place the blob(s) in the appropriate vendor/driver subdirectory (e.g.
`qcom/`, `cirrus/`, `intel/`). Match the directory convention of similar
existing files.
2. Add a stanza to `WHENCE` (see "WHENCE format" below) declaring the file and
its license. Group it with related entries; keep the file roughly ordered as
the surrounding content is.
3. If the firmware needs a new license, the license text **must** go in the
`LICENSES/` directory. Prefer `LICENSES/LICENSE.<vendor>` for new files
(`LICENSES/LICENCE.<vendor>` also exists in the tree and is still accepted,
but new files should use the `LICENSE.<vendor>` spelling). Reference it from
`WHENCE` with `See LICENSE.<vendor> for details.` using the bare filename;
`check_whence.py` resolves it under `LICENSES/`. The license text must meet
the criteria in [LICENSE-CRITERIA.md](LICENSE-CRITERIA.md) section 3; new
license texts require maintainer review (see section 5).
4. Run `make check`.
5. Commit with a `Signed-off-by` from someone authoritative on the license,
and — if an agent helped produce the change — a trailer noting AI
involvement (e.g. `Assisted-by:`). See "Commit conventions".
## WHENCE format
`WHENCE` is parsed by `check_whence.py`, so the syntax is load-bearing. The
keywords that matter:
- `Driver: <name> - <description>` — human-readable section header.
- `File: <path>` — a binary firmware file tracked in git. This is the usual one.
- `RawFile: <path>` — a file shipped verbatim (not converted to ihex form).
- `Link: <linkname> -> <target>` — a symlink. The target is relative to the
link's directory. `check_whence.py` verifies the target exists and that links
don't point at other links.
- `Source: <path>` — source for firmware that is compiled here (rare).
- `Version:` / `Info:` — optional metadata lines.
- `Licence:` / `License:` — the license terms. Either name an inline word
(e.g. `Redistributable`, `GPLv2`) or refer out with
`See <LICENSE-file> for details.` Referenced license files live in the
`LICENSES/` directory and are cited by bare filename (the checker resolves
the path); the file must exist there.
Spaces in paths are backslash-escaped (e.g. `foo\ bar.bin`).
**Block structure.** `WHENCE` is a series of blocks separated by a delimiter
line of dashes. A block opens with one or more `Driver:` lines, then one or
more *sections* separated by blank lines. A section is a group of
`File:`/`RawFile:` entries, optionally annotated, closed by a `Licence:` line.
By convention:
- If a `Driver:` block for your device already exists, **add your files to it**
instead of starting a duplicate block.
- A `Version:`/`Info:` line annotates the `File:` directly above it.
- A `Licence:` line applies to the files in its section. This grouping is a
convention for human readers — `check_whence.py` does not enforce which files
a `Licence:` covers — so keep each section's license unambiguous. A
license/section may precede its firmware files if that reads more naturally.
Study a few existing stanzas in `WHENCE` before writing a new one matching an
existing pattern is the safest approach.
## Validation: `make check`
Run **`make check`** before considering any change complete. It runs
`pre-commit run --all-files` the same gate CI enforces covering the
`WHENCE`tree check plus shell, Python, and Markdown linting. **Treat
`make check` as the single source of truth; don't invoke the individual
checkers directly**, so the rule set can grow without this doc going stale.
If `pre-commit` isn't installed: `pip install pre-commit`.
Note: the `WHENCE` check reads `git ls-files`, so **stage new files
(`git add`) before running `make check`** otherwise they're invisible to the
check and it reports a phantom mismatch.
## Commit conventions
- Subject line style: `<vendor/area>: <imperative summary>`, e.g.
`qcom: Update DSP firmware for qcs8300 platform` or
`cirrus: cs35l56: Add firmware for Cirrus Amps for a Dell laptop`.
- A **`Signed-off-by:`** line is **mandatory** and must come from someone with
authority over the firmware's licensing (typically from within the owning
company). CI (`ci-fairy check-commits --signed-off-by`) rejects commits
without it. Do not add one yourself ask the user.
- **Include a firmware changelog in the commit message where possible** what
changed in this firmware revision (fixes, new device support, version bumps).
For binary blobs the commit message is often the only human-readable record
of the change, so capture whatever the vendor provides.
- If an AI agent assisted in producing the commit, record it with a trailer
such as `Assisted-by: <tool/model>` (an equivalent `Co-developed-by:` /
`Co-Authored-By:` is fine). The exact tag isn't critical; surfacing that AI
was involved is.
- Never include a `CONFIDENTIALITY STATEMENT` anywhere in the commit or MR;
per README that causes the firmware to be rejected outright.
- New work goes on a branch and is submitted as a GitLab MR, an emailed git
binary diff, or a pull request to `linux-firmware@kernel.org`.
## Repository tooling (don't reinvent these)
- `copy-firmware.sh` installs firmware to a destdir per `WHENCE` (used by
`make install` / `install-xz` / `install-zst`). Supports optional compression.
- `dedup-firmware.sh` replaces duplicate installed files with symlinks
(`make dedup`).
- `build_packages.py` builds `.deb`/`.rpm` (`make deb` / `make rpm`); templates
in `contrib/templates/`.
- `make dist` builds a release tarball.
- `contrib/process_linux_firmware.py` maintainer-side processing helper.
## Things to leave alone unless explicitly asked
- The `known_files` / `executable_files` allowlists inside `check_whence.py`:
only touch them when you are genuinely adding a new top-level tooling file,
and understand you're changing the validator itself.
- License text files (`LICENSE.*` / `LICENCE.*`): treat as authoritative legal
text. Add new ones when a new license is needed; don't reword existing ones.