diff --git a/general/package/novatek-osdrv-nt9856x/files/script/load_novatek b/general/package/novatek-osdrv-nt9856x/files/script/load_novatek index 1ab7584223..ce2be0bd60 100755 --- a/general/package/novatek-osdrv-nt9856x/files/script/load_novatek +++ b/general/package/novatek-osdrv-nt9856x/files/script/load_novatek @@ -152,6 +152,47 @@ insert_ko() { #insmod hdal/kdrv_videoout/fbdev/nvt_fb.ko } +# The vendor U-Boot lays memory out from osmem: the DT memory node it hands +# over ends there and the HDAL pool starts there. The kernel's RAM comes from +# mem= alone, and the bootcmd these boards were given re-runs the saved +# bootargs, so an osmem changed later never reaches mem=. Booted with mem= +# past the node, the kernel owns the start of the HDAL pool and +# nvtmpp_heap_init in kflow_common panics the camera into a reboot loop. +# The opposite drift leaves the DT above the kernel's RAM and hangs it before +# the console, which nothing here can catch. #2107. +check_mem() { + reg=/proc/device-tree/memory/reg + [ -r $reg ] || return 0 + dt_mem=$(( 0x$(hexdump -ve '1/1 "%02x"' $reg | cut -c9-16) >> 20 )) + booted_mem= + for arg in $(cat /proc/cmdline); do + case "$arg" in + mem=*M) + booted_mem=${arg#mem=} + booted_mem=${booted_mem%M} + break + ;; + esac + done + case "$booted_mem" in + "" | *[!0-9]*) return 0 ;; + esac + [ "$booted_mem" -gt "$dt_mem" ] || return 0 + + logger -s -p daemon.err -t novatek "Kernel booted with mem=${booted_mem}M, past the ${dt_mem}M U-Boot laid out from osmem; HDAL would overwrite kernel memory, not loading it" + bootargs=$(fw_printenv -n bootargs 2>/dev/null) + case " $bootargs" in + *" mem=${booted_mem}M"*) + bootargs=$(echo " $bootargs" | sed "s/ mem=${booted_mem}M/ mem=${dt_mem}M/; s/^ //") + fw_setenv bootargs "$bootargs" && + logger -s -p daemon.err -t novatek "bootargs set to mem=${dt_mem}M; reboot to load HDAL" + ;; + esac + exit 1 +} + +check_mem + cd /lib/modules/4.19.91/novatek insert_ko