Repository navigation
load_novatek: give Linux 48M of a 128 MB board, not 32M - #2660
Conversation
128 MB NT9856x boards have been set up with osmem=32M, which leaves Linux
25 MB. That is one live viewer before majestic's low-memory floor sheds it,
and on a clean boot about 3.4 MB free while it streams, while HDAL keeps a
96 MB pool it does not fill (41 MB free). At osmem=48M the same NT98566 +
SC501AI runs with 23 MB available, majestic admits seven viewers, and HDAL
still keeps 25 MB free.
The vendor U-Boot reads osmem from its environment, so the firmware moves
it there: load_novatek, on a board whose device tree says 128 MB of DRAM,
with osmem unset or still at the old 32M, writes osmem=48M and the matching
mem= in bootargs in one fw_setenv --script write, effective at the next
boot -- the two can never be written apart, which would hang the kernel or
crash HDAL. A bootargs that carries the ${osmem} placeholder keeps it and
only osmem moves; a bootargs whose mem= already disagrees is not touched.
osmem_default marks the move done, so a split an owner picks afterwards is
left alone. Nothing changes on any other board or setting.
.github/scripts/test_load_novatek.sh runs the real script under busybox
with a faked device tree, command line and environment, and checks every
case that must write and every case that must not, check_mem's guard
included.
PR Summary by QodoGive Linux 48M on eligible 128 MB Novatek boards
AI Description
Diagram
High-Level Assessment
Files changed (5)
|
Code Review by Qodo
1. 128 MB Novatek cameras inherit a forced memory split
|
… that the script ran
A saved bootargs with a second mem= beside mem=32M was half-moved and marked done. The move now needs exactly one mem=, of the old split or the ${osmem} placeholder. The test records each run's exit status, so a case that must not write cannot pass because the script died first, and gains the two-mem= case.
Problem
128 MB NT98562/NT98566 boards are set up with
osmem=32M, which leaves Linux 25 MB. On a clean boot that is about 3.4 MB free while majestic streams, just above majestic's 3.2 MB low-memory floor, so majestic admits one live viewer. Meanwhile HDAL keeps a 96 MB pool and leaves 41 MB of it unused. A 32M camera works, but only just, and any second viewer or web UI activity gets shed.These boards keep the vendor U-Boot, which lays memory out from the
osmemvariable in its own environment, so there is no firmware-side default to change.load_novateknow moves it:nvt_memory_cfg/dram), withosmemunset or still the old 32M, and not migrated before.osmem=48Mand the matchingmem=inbootargsin onefw_setenv --scriptwrite, effective at the next boot. The two values can't end up apart: one too high hangs the kernel, the other crashes HDAL (# NT98566 + SC501AI: Cannot start SDK - syscall_403 ENOSYS / hdal module symbol mismatch #2107, load_novatek: refuse to load HDAL over the kernel's own memory #2657).bootargscarries the${osmem}placeholder, onlyosmemmoves. If itsmem=already disagrees, nothing is touched.osmem_default=48Mmarks the move done, so a split an owner chooses later is left alone.Hardware tested on
NT98566 + SC501AI (XM board, 128 MB, vendor U-Boot 2019.04), OpenIPC
nt98566_litenightly 2026-10-21, with thisload_novatekplaced in the overlay for the test. The original environment and script were restored afterwards.Evidence
Before (saved environment):
After the first boot with this script (it still booted
mem=32Mand loaded HDAL normally):The next boot (no further writes):
For comparison, at 32M on a clean boot
MemAvailablewas 6.9 MB at idle, about 3.4 MB while streaming, and majestic admitted ~1 session. Earlier at 48M, a 60 s/video.mp4together with a 20 s/mjpegviewer ran with no shedding..github/scripts/test_load_novatek.sh(new; runs the real script under busybox): 19 checks pass. With theset_default_osmemcall disabled, the migration checks fail.Local
make BOARD=nt98566_lite:STRICT=1 test_shell_parse.sh,STRICT=1 test_strip_shell_comments.sh,ci-matrix.py --self-testandlint-workflow-shell.pypass. Adding the new test means editingci-matrix.py, so this PR builds every board.Scope
general/package/all-patches/linux/(those go to OpenIPC/linux)general/overlay/or in a sharedload_<vendor>script hardcodes a value specific to my boardLD_PRELOAD, and no binaries that cannot be rebuilt from source