Skip to content

kernel: bring up hi3516cv100 (V1) against Linux 7.0#187

Merged
widgetii merged 8 commits into
mainfrom
feat/hi3516cv100-neo-7.0
May 24, 2026
Merged

kernel: bring up hi3516cv100 (V1) against Linux 7.0#187
widgetii merged 8 commits into
mainfrom
feat/hi3516cv100-neo-7.0

Conversation

@widgetii
Copy link
Copy Markdown
Member

Summary

Brings cv100 (V1, ARM926EJ-S, Hi3518 SDK V1.0.B.0, kernel 3.0.8 baseline) up to Linux 7.0 — mirrors the cv200 #162 / av100 #165 pattern with V1-specific shim coverage. End-to-end validated under qemu-system-arm -M hi3516cv100.

Two-layer approach

V1 has no OSAL abstraction (same as V2 cv200): the vendor .o blobs in kernel/obj/hi3516cv100/ embed kernel API call sites verbatim against 3.0.8. Where the kernel API was removed or renamed, runtime load fails with "Unknown symbol" or modpost rejects the module.

kernel/osal_v1_shim/cv100_shim.c (646 lines) — re-exports the legacy kernel symbol set the cv100 blobs reference but modern 7.0 either renamed, inlined, removed-for-security, or moved to noprof helpers:

  • do_gettimeofday, register_sysctl_table, init_timer_key, strlcpy, _cond_resched, __kmalloc, kmem_cache_alloc, __memzero, printk, del_timer, vmalloc, sched_setscheduler — same shape as cv200's v2_shim
  • __arm_ioremap, __iounmap, create_proc_entry, __bug, do_mmap_pgoff, do_munmap, __copy_to_user, __copy_from_user — V1-specific (cv200's blobs were already past these)
  • msecs_to_jiffies, __get_free_pages, module_put, __udelay, __const_udelay, dma_alloc_coherent, dma_free_coherent, no_llseek, rtc_time_to_tm, rtc_tm_to_time, schedule_work, hi_sched_clock — surfaced via modpost iteration

The shim body is gated #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0), so on the cv100_lite production target (3.0.8) it compiles to an empty pr_info shell.

kernel/init/hi3516cv100/*.c — 92 EXPORT_SYMBOL re-declarations via the existing DECLARE_BLOB_FUNC pattern across 9 init wrappers (mmz: 18, vou: 35, hidmac: 14, rc: 10, sio+sensor_i2c: 5 each, hiuser: 3, isp+hifb: 1 each). cv100 blobs carry legacy 8-byte struct kernel_symbol __ksymtab entries that modern modpost doesn't recognize — re-EXPORT in the wrapper TU regenerates the modern ksymtab metadata.

Source-side patches

  • kernel/mmz/hi3516cv100/{media-mem,kcom,mmz-userdev}.c — drop <mach/hardware.h> + <asm/system.h>; CONFIG_OUTER_CACHE guard on <asm/outercache.h>; < 3.10 proc-fs version branch for create_proc_entry → proc_create + COMPAT_USE_PROC_OPS; mmz_write_proc signature switch
  • kernel/rtc/hi3516cv100/hi_rtc.cIO_ADDRESS() static-mapping macros → ioremap_nocache-backed globals (28 use sites cast (void *)); COMPAT_TIMER_SETUP for the temperature timer
  • kernel/ir/hi3516cv100/hiir.c — same IO_ADDRESSioremap_nocache pattern (2 sites)
  • kernel/cipher/hi3516cv100/src/cipher_intf.c — drop <asm/system.h>
  • kernel/obj/hi3516cv100/.*.o.cmd — 31 stub files (savedcmd_*.o := :) satisfying modpost's expectation of companion .cmd files alongside each blob .o. Mirrors PR kernel: ship blob .cmd stubs + gate open_pm + add dev_warn shim (cv200/av100 neo unblock) #171 for cv200/av100. Force-added past .gitignore.

Kernel-side dependency

Requires OpenIPC/linux PR #46 on upstream-patchesalready merged as 8701d2079bf72097dd3592c2aed404060613461f. That PR adds hi3516cv100.dtsi + hi3516cv100-demb.dts + ARCH_HI3516CV100 Kconfig + mach-hi3518ev20x.c compat-array entry. cv100 dtsi #include "hi3516cv200.dtsi" and overrides only the VIC base — the rest of the MMIO map (CRG, sysctl, UARTs, SP804, FEMAC, FMC) is identical between V1 and V2. The CRG driver (COMMON_CLK_HI3516CV200) is reused unchanged.

A sibling firmware PR will follow to add hi3516cv100_neo_defconfig + hi3516cv100.neo.config + neo-post-image.sh + the cv100 v1_shim.ko install rule in hisilicon-opensdk.mk.

Verification

cv100_lite (kernel 3.0.8 production) — no regression

Built BOARD=hi3516cv100_lite br-hisilicon-opensdk with HISILICON_OPENSDK_OVERRIDE_SRCDIR pointed at this branch. 34 .ko module set matches nightly byte-for-byte by name (diff exit 0). Booted under qemu-system-arm -M hi3516cv100 against the nightly cv100 squashfs with this branch's modules swapped in; compared lsmod and dmesg against an unmodified-modules baseline:

  • lsmod: identical 33-module set with identical dep tree. Module sizes match exactly except in modules whose init wrappers got EXPORT_SYMBOL patches — size deltas (mmz +436, hidmac +356, hi3518_rc +176, hi3518_sio +108, hi_i2c +104, hiuser +104, hi3518_isp +24) correlate exactly to ~24 bytes/exported-symbol matching expected __ksymtab entry overhead.
  • dmesg: diff is exactly 2 benign lines — random MAC (kernel generates one since vendor MAC is 00:00:00:00:00:00, varies every boot) and RAMDISK size 4739KiB → 4740KiB (1 KiB squashfs delta from added __ksymtab entries). No symbol-collision warnings, no errors.

cv100_neo (kernel 7.0) — boots + ethernet works

With a local hi3516cv100_neo_defconfig (firmware-side sibling, not in this PR), built full opensdk + linux (7.0 from upstream-patches with PR #46 merged) and wrapped uImage = zImage + DTB. Booted under qemu-system-arm -M hi3516cv100 against a hybrid rootfs (nightly userspace + 7.0 modules from this branch):

hisi-femac 10090000.ethernet eth0: Link is Up - 100Mbps/Full
cv100 V1 OSAL shim: ready (do_gettimeofday, register_sysctl_table, ...)
openipc-hi3516cv100 login:
eth0   inet addr:10.0.2.15
64 bytes from 10.0.2.2: seq=0 ttl=255 time=135.170 ms
64 bytes from 10.0.2.2: seq=1 ttl=255 time=16.912 ms

Both DoDs met: boots to login + ethernet pingable. open_v1_shim.ko inserts cleanly at boot. No Oops/panic/BUG.

Out of scope (separate concerns)

  • struct module drift — pre-compiled cv100 blobs embed a struct module sized for kernel 3.0.8; modern 7.0 expects a different layout. mmz.ko / hi3518_base.ko fail insmod on 7.0 with .gnu.linkonce.this_module section size must match... — same drift cv200/av100 hit too; fix lives outside this PR (vermagic shim or blob recompile). Doesn't affect cv100_lite (the production target) and doesn't block the cv100_neo boot/ethernet DoDs.
  • Firmware sibling PR with hi3516cv100_neo_defconfig etc. — coming next.

Test plan

  • Linux 7.0 compile against openipc/linux:upstream-patches (post-PR hi3516cv200: OSAL shim layer for kernel version independence #46)
  • hi3516cv100_lite (kernel 3.0.8) byte-equivalence vs nightly — no regression in lsmod or dmesg
  • QEMU hi3516cv100 boot + lsmod parity (cv100_lite no-regression test)
  • QEMU hi3516cv100 boot under 7.0 kernel — login prompt reached, eth0 UP, ping gateway succeeds
  • Real-hardware test on a cv100 board — deferred until firmware sibling lands

🤖 Generated with Claude Code

Vixand added 8 commits May 24, 2026 09:12
Brings the cv100 (V1, ARM926EJ-S) module set up against the openipc/linux
7.0 base used by cv200_neo / av100_neo. cv100 has no OSAL abstraction —
the vendor .o blobs in kernel/obj/hi3516cv100/ embed kernel API calls
verbatim against the 3.0.8 SDK base. Two-layer fix mirrors the cv200
#162 pattern:

* `kernel/osal_v1_shim/cv100_shim.c` — re-exports legacy kernel symbols
  the cv100 blobs reference (do_gettimeofday, register_sysctl_table,
  init_timer_key, strlcpy, _cond_resched, __kmalloc, kmem_cache_alloc,
  __memzero, printk, del_timer, vmalloc, sched_setscheduler). Gated to
  >=5.0 so on the cv100_lite production target (3.0.8) the module is a
  benign no-op shell. Strict subset of v2_shim coverage; symbols cv200
  needs but cv100 doesn't (PDE_DATA, dev_err/warn, jiffies_to_msecs,
  register_sysctl_paths) are omitted.

* `kernel/mmz/hi3516cv100/{media-mem,kcom,mmz-userdev}.c` — strip
  mach/hardware.h and asm/system.h (removed in modern ARM); guard
  asm/outercache.h with CONFIG_OUTER_CACHE; add the 3.10 proc-fs
  version branch (proc_create + COMPAT_USE_PROC_OPS) for media-mem's
  /proc entry; switch mmz_write_proc signature for the new
  fops/proc_ops .write slot.

* `kernel/cipher/hi3516cv100/src/cipher_intf.c` — drop asm/system.h.

* `kernel/hi3516cv100.kbuild` — wire v1_shim ahead of mmz with the same
  CFLAGS_*=-D_cond_resched=...unused_inline trick cv200 uses to suppress
  the static-inline definition from <linux/sched.h>.
Both files keyed their MMIO macros off `IO_ADDRESS(phys_addr)`, the
mach/hardware.h static virtual-mapping table that's gone on modern ARM
(removed alongside mach support cleanup). cv200's equivalent files had
already been refactored to ioremap-backed globals pre-#162 — cv100's
source predates that work.

* `rtc/hi_rtc.c`: hold ioremap_nocache results for the CRG (0x20030000)
  and SPI (0x20060000) windows in `rtc_{crg,spi}_base_addr` globals,
  redefine CRG_BASE_ADDR / RTC_SPI_BASE_ADDR to point to them. All
  writel/readl call sites get a `(void *)` cast (modern __iomem-typed
  prototype). The temperature_detection timer callback gets the
  COMPAT_TIMER_SETUP signature swap from kernel_compat.h — same dual-
  signature pattern as cv200 hi_rtc.c. iounmap both windows in
  rtc_exit().

* `ir/hiir.c`: ioremap_nocache the 0x40-byte IR register window
  (0x20070000) and the single-word IOCONFIG cell (0x200f01F8) at
  init, redefine IR_REG_BASE / IOCONFIG as casts of the resulting
  void __iomem* pointers so WRITE_REG/READ_REG keep their offset
  arithmetic. iounmap on exit.

Both modules' writel/readl indirection through ((volatile u32 *)addr)
in WRITE_REG/READ_REG works equally well with the new pointer-typed
base addresses cast through unsigned long.
Mirrors PR #171 for cv200/av100 — modern kbuild's modpost requires a
companion .<file>.o.cmd file alongside each .o. The .o blobs in
kernel/obj/hi3516cv100/ were extracted from vendor SDK V1.0.B.0 with
no .cmd metadata, so a stub `savedcmd_kernel/obj/.../foo.o := :`
satisfies modpost on >= 5.x kernels without changing the build flow
on 3.0.8 (modpost on older kernels doesn't consult the .cmd files).

Force-added past .gitignore (which blanket-excludes .*.cmd because
buildroot's normal flow regenerates them from .o builds).
cv100 blobs (V1, Hi3518 SDK V1.0.B.0, kernel 3.0.8 base) reference a
broader set of removed-since-3.0 kernel symbols than cv200 does —
surface via modpost when linking against ARMv5 Linux 7.0.

Add re-exports for:

* __arm_ioremap / __iounmap — pre-3.10 ARM ioremap/iounmap helpers;
  wrap modern ioremap/iounmap.
* create_proc_entry — removed 3.10; wrap proc_create_data(..., NULL).
  Blob post-call writes to ->proc_fops / ->write_proc become no-ops
  (struct fields gone) but procfs entry exists; acceptable since
  cv100 procfs nodes are diagnostic.
* __bug — BUG() arch backend; panic() with file:line for clean fail.
* do_mmap_pgoff / do_munmap — kernel-internal mmap helpers, unexported
  in 4.x for security. Wrap vm_mmap / vm_munmap which carry security
  hooks; SELinux is off in OpenIPC's kernel config so semantics match
  for the cv100 mmz blob's MMZ-region user-mapping path.
* __copy_to_user / __copy_from_user — renamed to
  arm_copy_{to,from}_user on modern ARM. Signature-compatible alias.
Modern <linux/uaccess.h> defines __copy_to_user / __copy_from_user as
static-inline wrappers around raw_copy_*_user — but the cv100 .o blobs
expect them as exported symbols. Use the same Kbuild macro-rename
trick the shim already uses for _cond_resched: pass
-D__copy_to_user=...unused_inline so the header inline is emitted
under a throwaway name, then #undef inside the shim TU and provide
our own function under the legacy symbol name.
… __udelay

Round 2 of cv100_neo modpost unresolved symbols (after the first batch
covering __copy_*_user, __arm_ioremap, __iounmap, create_proc_entry,
__bug, do_mmap_pgoff, do_munmap):

* msecs_to_jiffies — static inline; alias to __msecs_to_jiffies.
* __get_free_pages — was a function pre-6.x; alias to get_free_pages_noprof.
* module_put — static inline with no exported helper for the put path;
  no-op stub since cv100 blob modules don't unload at runtime under QEMU.
* __udelay — now a macro dispatching arm_delay_ops.udelay; wrap the
  function-pointer call with the same 0x10C7 pre-scale the macro applies.

Two more Kbuild -D macro renames (msecs_to_jiffies, module_put) to
suppress the static-inline definitions in their respective headers.
…_BLOB_FUNC

The cv100 .o blobs (V1, Hi3518 SDK V1.0.B.0) carry __ksymtab_* entries in
the legacy 8-byte struct kernel_symbol layout — modern modpost on Linux
7.0 doesn't recognize that section format, so cross-module symbol
references fail at link time with "undefined!" even though the symbol
is defined and "exported" inside the blob.

Mirror the existing cv200/av100 vou_init.c pattern: re-declare each
blob-exported symbol via DECLARE_BLOB_FUNC + EXPORT_SYMBOL in the
corresponding init wrapper. modpost regenerates the modern ksymtab
metadata from the wrapper's EXPORT_SYMBOL directives, and the legacy
__ksymtab section in the blob is ignored.

92 symbols across 9 init wrappers — mmz (18), vou (35), hidmac (14),
rc (10), sio + sensor_i2c (5 each), hiuser (3), isp + hifb (1 each).
Plus hi_sched_clock added to osal_v1_shim (no blob defines it, it's
a vendor wrapper for the kernel's sched_clock()).
…*_to_*_tm / schedule_work

Final batch of cv100_neo modpost unresolved kernel symbols:

* __const_udelay — companion to __udelay, dispatches via
  arm_delay_ops.const_udelay.
* dma_alloc_coherent / dma_free_coherent — became macros over
  dma_alloc_attrs / dma_free_attrs with attrs=0.
* no_llseek — removed in 6.12. Provide as a function returning -ESPIPE
  (what the legacy kernel-internal helper did).
* rtc_time_to_tm / rtc_tm_to_time — renamed *_time64_* in 5.6;
  wrap with the cast from unsigned long → time64_t.
* schedule_work — static inline wrapper over queue_work_on; provide
  as a real exported function symbol.

Adds two more Kbuild -D renames (schedule_work, no_llseek) to suppress
the static-inline definitions in their headers.
@widgetii widgetii merged commit 488a76f into main May 24, 2026
31 checks passed
@widgetii widgetii deleted the feat/hi3516cv100-neo-7.0 branch May 24, 2026 06:32
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