Skip to content

soc: per-vendor file for kernel map - #1442

Open
johnchia wants to merge 2 commits into
themactep:masterfrom
johnchia:soc-kernel-per-family
Open

soc: per-vendor file for kernel map#1442
johnchia wants to merge 2 commits into
themactep:masterfrom
johnchia:soc-kernel-per-family

Conversation

@johnchia

@johnchia johnchia commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Follows #1426. That PR gave every SoC family its own makefile fragment; this one
moves the last thing still keyed on SOC_FAMILY in thingino.mk into those
files — the kernel — and retires a guard that turned out to be dead.

thingino.mk picked the kernel branch with a 45-line ifeq chain, one arm per
family, several nesting a second test on KERNEL_VERSION. Every fact in it
belongs to a family that now has a file of its own.

What a family says now

# soc/ingenic/t30.mk
KERNEL_VERSION := 3.10.14
KERNEL_BRANCH  := ingenic-t31

Seven of the twelve families are exactly that — two plain assignments. The five
whose branch really does depend on the kernel version add a key:

# soc/ingenic/t41.mk
KERNEL_VERSION        := 4.4.94
KERNEL_BRANCH         := ingenic-t41-4.4.94
KERNEL_BRANCH_3.10.14 := ingenic-t41-3.10.14

and t23 pins a hash the same way, KERNEL_HASH_4.4.94. The keyed form cannot be
avoided for those five: the branches are not derivable by any naming rule, since
t23 changes base between versions, t41's 3.10 branch carries its own suffix, and
t40 and a1 use a single branch for both.

A family file cannot test KERNEL_VERSION itself — soc/<vendor>/*.mk is
included before the version is settled — so thingino.mk resolves the version
first and then dereferences, once per variable:

KERNEL_BRANCH := $(or $(KERNEL_BRANCH_$(KERNEL_VERSION)),$(KERNEL_BRANCH))
KERNEL_HASH   := $(or $(KERNEL_HASH_$(KERNEL_VERSION)),$(KERNEL_HASH))

All three variables read the same way: the family states the value, a
version-keyed name overrides it.

The U-Boot variant fragment goes too

The other thing thingino.mk still dispatched on SOC_* was thirteen arms
mapping a model to configs/uboot/variants/<model>.config. It sat a few lines
below UBOOT_DEFCONFIG, which already reads SOC_UBOOT_NOR/_NAND from the
family file — the same data split across two places. Families now set
SOC_UBOOT_VARIANT alongside the other three SOC_UBOOT_* values:

ifeq ($(SOC_MODEL),t31l)
SOC_RAM_MB        := 64
SOC_UBOOT_NOR     := isvp_t31l_sfcnor
SOC_UBOOT_NAND    := isvp_t31_sfcnand_lite
SOC_UBOOT_VARIANT := t31l
endif

The family names the fragment rather than thingino.mk deriving it from
SOC_MODEL, because the name is not always the model — t31zx uses t31x's. Only
13 of 54 models have one; the absent case behaves like SOC_UBOOT_NOR already
does.

The empty-KERNEL_VERSION guard was stale

ifeq ($(KERNEL_VERSION),) wrapped the whole version chain. Nothing in the tree
assigns KERNEL_VERSION — no defconfig, no workflow, no script; the Makefile
only reads it — so the only ways it could be non-empty were a hand-typed
make KERNEL_VERSION=x or an environment variable. For the command line the
guard is redundant
, because a command-line value already overrides any
makefile assignment whether the guard is there or not. So its entire remaining
job was honouring an environment variable nothing sets.

Dropping it is what lets a family state KERNEL_VERSION outright instead of
feeding a default into a chain that then decides.

soc/ingenic/vendor.mk

KERNEL_SITE and the 7.1 branch are true of every Ingenic family rather than of
any one of them, so repeating them twelve times would be the wrong home. They go
in soc/ingenic/vendor.mk, which has no $(filter) — the directory is already
the vendor. AGENTS.md covers both this and the version keys.

Two things fall out

The git ls-remote is guarded on KERNEL_SITE being set rather than on a
vendor name. A vendor naming its kernel through BR2_LINUX_KERNEL_CUSTOM_GIT
sets no KERNEL_SITE, resolves nothing, and makes no network call on every
make. A property test, not a list of vendor names to keep updated.

The catch-all is written down. else KERNEL_BRANCH := ingenic-t31 quietly
gave t10, t20, t21, t30 and t33 the t31 kernel, and nothing said so.

The one behaviour change

KERNEL_VERSION set in the environment is no longer honoured. Command-line
make KERNEL_VERSION=… still wins, as it always did and independently of this
change. Nothing in the repository sets it in the environment.

Deliberately not changed

c100 still resolves 3.10.14 unless a defconfig sets KERNEL_VERSION_4=y, exactly
as today. It is 4.4-only in practice and this makes fixing that a one-line edit
to soc/ingenic/c100.mk, but that is a behaviour change and does not belong in
a refactor.

Verification

Every family × input combination, against master. 12 families against unset,
KERNEL_VERSION_4=y, KERNEL_VERSION_7=y, three explicit command-line versions
and one environment variable — 84 combinations, 75 identical. The 9 that
differ are all the environment case above, on the 9 families whose own version
is not already 4.4.94. Both harnesses run in this tree, the old one against
master's family files so its guard is not tripped by the new ones.

The matrix earned its keep twice: it caught a missing kernel default on a1 that
no camera defconfig would have exposed, and it caught the harness itself
measuring the wrong thing.

Every model, for the U-Boot fragment. .config never carries
UBOOT_VARIANT_FRAGMENT, so the board sweep cannot see it. All 54 models the
family filters claim resolve the same fragment as the old chain
, and every
fragment named exists on disk.

.config for all 171 camera defconfigs: 171 identical, 0 differing, 0
failures
, against the same master baseline. Both passes on this branch so
OUTPUT_DIR — which contains the branch name — does not move; the
BR2_EXTERNAL_THINGINO_VERSION stamp is excluded since any commit changes it.

@johnchia
johnchia marked this pull request as ready for review August 9, 2026 06:32
@johnchia

johnchia commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

@themactep This could use your input

Kernels should come out of the family files

Taking the point that a SoC does not have a kernel. This PR as it stands has
each family file name one, which is the wrong shape, and I think the tree
already shows it in two places.

It could not hold 7.1. 7.1-rc1 is one branch shared by every family, and
there was nowhere per-family to put it, so it ended up in vendor.mk as a
version-keyed name. That was the structure not fitting, treated as a special
case.

It silently mispairs. Every family reaches two or three kernels — 33
distinct (family, kernel) pairs across 12 families — while the family file names
one. Ask for 4.4 on a t20 today and you get:

KERNEL_VERSION = 4.4.94
KERNEL_BRANCH  = ingenic-t31

a 3.10 branch labelled 4.4. Same for t10, t21, t30, t33. The family file
has no way to say "no 4.4 here", so the default branch rides along unnoticed.
Nothing currently trips this — only three defconfigs ask for a non-default
kernel (c100, t31l, t31n, all on 4.4, all supported) — but it is reachable
by adding one line to a defconfig.

Proposal

Family files describe hardware. Which kernels a family runs becomes a
(family × kernel) table in one per-vendor file, replacing vendor.mk:

# soc/ingenic/kernels.mk
# Which kernels each family runs. A family that does not list a version does
# not run it: asking for one is an error, not a fallback.
KERNEL_SITE := https://github.com/gtxaspec/thingino-linux

KERNEL_DEFAULT_t23        := 3.10.14
KERNEL_BRANCH_t23_3.10.14 := ingenic-t31
KERNEL_BRANCH_t23_4.4.94  := ingenic-t23-4.4.94
KERNEL_HASH_t23_4.4.94    := b8a1f1ed22272b844fd423871f4aca16e8b779ff
KERNEL_BRANCH_t23_7.1-rc1 := ingenic-7.1-rc1

KERNEL_DEFAULT_t20        := 3.10.14
KERNEL_BRANCH_t20_3.10.14 := ingenic-t31
KERNEL_BRANCH_t20_7.1-rc1 := ingenic-7.1-rc1

12 defaults, 33 branch rows, 1 hash — derived mechanically from what the family
files already declare, not retyped.

All of the resolution, in thingino.mk:

KERNEL_VERSION := $(or $(KERNEL_VERSION),$(KERNEL_DEFAULT_$(SOC_FAMILY)))
KERNEL_BRANCH  := $(KERNEL_BRANCH_$(SOC_FAMILY)_$(KERNEL_VERSION))
KERNEL_HASH    := $(KERNEL_HASH_$(SOC_FAMILY)_$(KERNEL_VERSION))
ifeq ($(KERNEL_BRANCH),)
$(error SoC family '$(SOC_FAMILY)' does not run kernel $(KERNEL_VERSION))
endif

This also removes the awkward part of the current PR rather than tidying it.
The KERNEL_BRANCH_$(KERNEL_VERSION) indirection exists only because the family
file has to speak before the kernel version is known. A table does not have to
speak — both axes are known where it is read, so there is no ordering problem to
work around and no version-keyed names anywhere.

Three things I would rather you decide

  1. Does absent mean unsupported? The $(error) assumes it does. If t10,
    t20, t21, t30, t33 actually do run 4.4 and were simply never
    declared, then those rows should exist and the current fallback has been
    hiding it. That is SoC knowledge I do not have.
  2. Is 7.1-rc1 genuinely every family? I encoded vendor.mk's claim as 12
    identical rows, which is where drift will show up first. A version-wide row
    would be terser but weakens the unsupported check.
  3. Where should the file live? soc/ingenic/kernels.mk is picked up by the
    existing wildcard, but if kernels are not SoC properties then somewhere
    outside soc/ like kernels/ingenic.mk may be the honest place.

Happy to push this as an incremental commit on top of this branch rather than a
rewrite. I have a 162-cell matrix (54 models x 3 kernel requests) that diffs the
current behaviour against the new one; the expected difference is exactly the
five mispaired cells becoming errors and nothing else moving.

@johnchia
johnchia marked this pull request as draft August 9, 2026 09:08
@themactep

Copy link
Copy Markdown
Owner

The catch-all is written down. else KERNEL_BRANCH := ingenic-t31 quietly gave t10, t20, t21, t30 and t33 the t31 kernel, and nothing said so.

ingenic-t31 branch is universal, it covers all xburst1 architecture soc families.

@johnchia

johnchia commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the correction, I've taken the kernel mapping out of the soc family.mk and put it into a vendor.mk -- open to suggestions where it goes:

  • kernels/ingenic.mk
  • soc/ingenic/kernels.mk
  • other

@johnchia johnchia changed the title soc: let each family state its own kernel, not thingino.mk soc: per-vender file for kernel map Aug 9, 2026
@johnchia
johnchia marked this pull request as ready for review August 9, 2026 22:10
@johnchia johnchia changed the title soc: per-vender file for kernel map soc: per-vendor file for kernel map Aug 16, 2026
@johnchia

Copy link
Copy Markdown
Contributor Author

Rebased onto master (merge commit) and reworked the kernel table.

The three-tier lookup is gone. kernels/ingenic.mk is now one chain per kernel
version — the families that differ, then the branch the rest of the architecture
shares — the same shape soc/ingenic/*.mk uses after #1451. Nothing overrides
anything, and thingino.mk no longer knows the naming scheme: it resolves the
version, includes the vendor file, and reads the result. Each chain closes on
SOC_ARCH rather than a bare else, so a family with no branch for a version is
rejected instead of quietly taking xburst1's.

No behaviour change — every family crossed with every version, and with none
asked, resolves to the same version, branch and hash as before (48 combinations,
compared mechanically).

Also dropped the re-alignment churn: adding SOC_UBOOT_VARIANT had shifted every
neighbouring line to a new column, so soc/ingenic/ is 48/36 lines lighter and
now reads as 13 additions.

Still open from above: where this file belongs — kernels/ingenic.mk,
soc/ingenic/kernels.mk, or elsewhere.

themactep added a commit to johnchia/thingino-firmware that referenced this pull request Aug 18, 2026
Rebase of themactep#1442 onto current master. The seven soc/ingenic/*.mk files
conflicted with c45befa (per-model if/else ladders, single SOC_UBOOT
resolved for the flash type); resolved by keeping master's structure and
adding the SOC_UBOOT_VARIANT assignments the PR introduced.

Kernel selection leaves thingino.mk's SOC_FAMILY chain: a vendor's kernels
now live in kernels/<vendor>.mk, one chain per version, closing on SOC_ARCH.
thingino.mk resolves the version from the defconfig symbols, includes that
file, and turns a family/version with no branch into an error instead of a
fallback. The ls-remote for KERNEL_HASH is now guarded on KERNEL_SITE being
set. The U-Boot variant fragment chain moves into the family files as
SOC_UBOOT_VARIANT.

The two cameras-exp defconfigs set BR2_INGENIC_SOC_MODEL where they set the
long-dead BR2_SOC_INGENIC_T23N/T31N symbols, which no Kconfig defines: as-is
they resolve no SOC_MODEL and fail with "Unknown SoC model".

Verified against master with a makefile harness:
- kernel resolution, 12 families x (none, KERNEL_VERSION_4, KERNEL_VERSION_7,
  explicit 3.10.14/4.4.94/7.1-rc1): identical except where the new table
  rejects or fixes a silent mispair -- t10/t20/t21/t30/t33 with 4.4.94 now
  resolve ingenic-t31-4.4.94 instead of the 3.10 catch-all ingenic-t31, and
  a1/t40 with an explicit 3.10.14 error instead of taking their 4.4 branch.
  No defconfig in the tree reaches either case. t23's pinned hash unchanged.
- U-Boot variant fragment: all 54 claimed models resolve the same fragment
  as the old chain, and every fragment named exists on disk.

Signed-off-by: Paul Philippov <paul@themactep.com>
@themactep
themactep force-pushed the soc-kernel-per-family branch from 303ea43 to 986285f Compare August 18, 2026 09:29
Kernel selection leaves thingino.mk's SOC_FAMILY chain: a vendor's kernels
now live in kernels/<vendor>.mk, one chain per version, closing on SOC_ARCH.
thingino.mk resolves the version from the defconfig symbols, includes that
file, and turns a family/version with no branch into an error instead of a
fallback. The ls-remote for KERNEL_HASH is guarded on KERNEL_SITE being set,
so a vendor that names its kernel through Buildroot symbols makes no network
call. The U-Boot variant fragment chain moves out of thingino.mk into the
family files as SOC_UBOOT_VARIANT, named by the family because the fragment
is not always named after the model (t31zx uses t31x's).

Rebased onto current master; the seven soc/ingenic/*.mk files conflicted
with the per-model if/else ladder and single-SOC_UBOOT restructure
(c45befa), resolved by keeping master's structure and adding the
SOC_UBOOT_VARIANT assignments.

Verified against master with a makefile harness:
- kernel resolution, 12 families x (none, KERNEL_VERSION_4, KERNEL_VERSION_7,
  explicit 3.10.14/4.4.94/7.1-rc1): identical except where the table rejects
  or fixes a silent mispair -- t10/t20/t21/t30/t33 with 4.4.94 now resolve
  ingenic-t31-4.4.94 instead of the 3.10 catch-all ingenic-t31, and a1/t40
  with an explicit 3.10.14 error instead of taking their 4.4 branch. No
  defconfig in the tree reaches either case. t23's pinned hash unchanged.
- U-Boot variant fragment: all 54 claimed models resolve the same fragment
  as the old chain, and every fragment named exists on disk.

Signed-off-by: Paul Philippov <paul@themactep.com>
@themactep
themactep force-pushed the soc-kernel-per-family branch from 986285f to 53fcdb9 Compare August 18, 2026 09:52
@themactep

Copy link
Copy Markdown
Owner

Nice refactor — the kernel map move is clearly the right direction. One thing I'd push back on: the SOC_UBOOT_VARIANT mechanism is more machinery than the data justifies.

Of the 13 models that have a variant fragment, 12 have SOC_UBOOT_VARIANT literally equal to SOC_MODEL (t10l, t20l, t20x, t23dl, t30x, t31a, t31al, t31l, t31lc, t31x, c100, t32nq). The only real exception is t31zx → t31x.

And that exception is already a rule in the tree: SOC_MODEL_LESS_Z := $(subst z,,$(SOC_MODEL)) (thingino.mk:60), and $(subst z,,t31zx) = t31x. None of the 12 variant files contain a 'z' (checked), so the z-strip reproduces the entire mapping:

UBOOT_VARIANT_FRAGMENT := $(BR2_EXTERNAL)/configs/uboot/variants/$(SOC_MODEL_LESS_Z).config

with the existing $(wildcard ...) guard at the consumer (thingino.mk:480) skipping the ~41 models that have no fragment — the same pattern UBOOT_BOARD_FRAGMENT already uses. Zero new data.

If the goal is to address t31zx as its own thing, the right fix is in U-Boot: give T31ZX a real variant symbol (e.g. CONFIG_T31_VARIANT_T31ZX) and a t31zx.config fragment, since today t31zx is silently folded into t31x. Otherwise a single line handles the exception — a per-model variable spread over 7 files, built around one mismatch, is the kind of tower this refactor is supposed to be taking down.

Two things worth a separate look (both pre-existing, not introduced here):

  • I grepped both U-Boot forks in this tree: the 2026.07 fork defines T33_VARIANT_* Kconfig symbols but none for T10/T20/T23/T30/T31/T32, and the 2013.07 fork has no *_VARIANT_* symbols at all. The fragments set CONFIG_T31_VARIANT_T31X=y etc. — if those symbols don't exist in either fork's Kconfig, olddefconfig silently drops them and the variant fragments are inert today. Worth confirming against the actual fork checkout; if true, the "correct" route above (real U-Boot variants) is also what makes the mechanism do anything at all.
  • If you go the z-strip route, note t31zlt31l.config, which currently applies no fragment at all (t31.mk's t31zl arm sets none) — a one-model behavior difference to decide on deliberately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants