From 7018a36a18877471d19104582e2f85a1abece93e Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Sun, 4 Oct 2026 10:11:22 +0300 Subject: [PATCH 1/2] gk7205v500: let the kernel unload modules With CONFIG_MODULE_UNLOAD off, a module that is in cannot come out again, so nothing on this family can be swapped or reloaded without a reboot. That includes the media stack itself while a fault in it is being chased. The setting was left off with the vendor's tiny defconfig, but it is not part of the ABI the closed V500 objects depend on. They carry no struct module of their own: modpost generates __this_module with this kernel's layout, and they already export cleanup_module. The vendor's own xm72050500_full_defconfig ships with MODULE_UNLOAD=y. The layout hazard is CONFIG_PM, which moves struct device's fields, and it stays off. gk7201v200 has its own kernel config and is not touched. --- br-ext-chip-goke/board/gk7205v500/gk7205v500.generic.config | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/br-ext-chip-goke/board/gk7205v500/gk7205v500.generic.config b/br-ext-chip-goke/board/gk7205v500/gk7205v500.generic.config index aef2bc3c5..6ba00a3ea 100644 --- a/br-ext-chip-goke/board/gk7205v500/gk7205v500.generic.config +++ b/br-ext-chip-goke/board/gk7205v500/gk7205v500.generic.config @@ -229,7 +229,9 @@ CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set -# CONFIG_MODULE_UNLOAD is not set +# The closed V500 objects carry no struct module of their own (modpost builds it +# with this kernel's layout), so unloading is safe for them; CONFIG_PM is not. +CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set From 535d5e485a40cebe5578ace49c4e00660b9c76ce Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Sun, 4 Oct 2026 10:32:08 +0300 Subject: [PATCH 2/2] load_goke (gk7205v500): remove modules by the name they register under Once the kernel can unload, -r, -a and the sensor-detection pass reach remove_ko() and remove_detect() for the first time, and neither removed anything. The from-source build installs xm_.ko, but each module registers as open_, so every `rmmod xm_` failed with "No such file or directory". `modprobe -r xm_` is no better: it exits 0 and leaves the module loaded. The sysconfig line also named a module that does not exist, xm_sys_config. So detection left sysconfig loaded with sensors=unknown, and the modprobe that should have reloaded it with the detected sensor found it already in and did nothing. unload() tries open_ first, then the name as given. Both lists now run in dependency order: venc before rc, and sysconfig before osal. --- .../files/script/load_goke | 83 +++++++++++-------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/general/package/goke-osdrv-gk7205v500/files/script/load_goke b/general/package/goke-osdrv-gk7205v500/files/script/load_goke index f659eabd8..63f0bd65d 100755 --- a/general/package/goke-osdrv-gk7205v500/files/script/load_goke +++ b/general/package/goke-osdrv-gk7205v500/files/script/load_goke @@ -114,13 +114,22 @@ insert_detect() { modprobe xm_isp_sensor_spi } +# The from-source build (hisilicon-opensdk) installs xm_.ko, but the module +# inside registers as open_, and rmmod and modprobe -r both want the +# registered name: `rmmod xm_vi` fails with "No such file or directory" and +# `modprobe -r xm_vi` exits 0 with the module still in. Try the registered +# name first, then the name as given for a build that ships the vendor's own. +unload() { + rmmod -w "open_${1#xm_}" 2>/dev/null || rmmod -w "$1" +} + remove_detect() { - rmmod -w xm_isp_sensor_spi - rmmod -w xm_isp_sensor_i2c - rmmod -w xm_isp - rmmod -w xm_base - rmmod -w xm_osal >/dev/null 2>&1 - rmmod -w xm_sys_config + unload xm_isp_sensor_spi + unload xm_isp_sensor_i2c + unload xm_isp + unload xm_base + unload xm_sysconfig + unload xm_osal } insert_audio() { @@ -134,12 +143,12 @@ insert_audio() { } remove_audio() { - rmmod -w xm_acodec - rmmod -w xm_adec - rmmod -w xm_aenc - rmmod -w xm_ao - rmmod -w xm_ai - rmmod -w xm_aio + unload xm_acodec + unload xm_adec + unload xm_aenc + unload xm_ao + unload xm_ai + unload xm_aio echo "remove audio" } @@ -191,33 +200,35 @@ insert_ko() { remove_ko() { # rmmod -w xm_wdt # rmmod -w xm_pm + # Dependents before what they depend on: venc holds rc, and sysconfig is + # held by sys and mipi_rx and itself holds osal. remove_audio - rmmod -w xm_mipi_rx + unload xm_mipi_rx # rmmod -w xm_isp_piris # rmmod -w sil9024 &> /dev/null - rmmod -w xm_ive - rmmod -w xm_rc - rmmod -w xm_jpege - rmmod -w xm_h264e - rmmod -w xm_h265e - rmmod -w xm_venc - rmmod -w xm_vedu - rmmod -w xm_chnl + unload xm_isp_sensor_spi + unload xm_isp_sensor_i2c + unload xm_isp_pwm 2>/dev/null + unload xm_ive + unload xm_jpege + unload xm_h265e + unload xm_h264e + unload xm_venc + unload xm_rc + unload xm_vedu + unload xm_chnl # rmmod -w gfbg # rmmod -w xm_vo - rmmod -w xm_vpss - rmmod -w xm_isp - rmmod -w xm_vi - rmmod -w xm_vgs - rmmod -w xm_rgn + unload xm_vpss + unload xm_isp + unload xm_vi + unload xm_vgs + unload xm_rgn # rmmod -w xm_tde - rmmod -w xm_isp_sensor_i2c &>/dev/null - rmmod -w xm_isp_sensor_spi &>/dev/null - rmmod -w xm_isp_pwm - rmmod -w xm_sys - rmmod -w xm_base - rmmod -w xm_osal - rmmod -w xm_sys_config + unload xm_sys + unload xm_base + unload xm_sysconfig + unload xm_osal } load_usage() { @@ -307,9 +318,9 @@ fi #######################Action############################### # -r and -a remove the stack first, which needs a kernel that can unload -# modules. This family's kernels are built without CONFIG_MODULE_UNLOAD, to -# match the ABI the vendor modules were compiled against, so rmmod would fail -# on every module and -a would then insmod over the ones still loaded. +# modules. Kernels for this family were built without CONFIG_MODULE_UNLOAD +# before #2528, and on one of those rmmod fails on every module and -a would +# then insmod over the ones still loaded. # /sys/module//refcnt only exists when unloading is supported. if [ $b_arg_remove -eq 1 ] && ! ls /sys/module/*/refcnt >/dev/null 2>&1; then echo "[err] this kernel cannot unload modules: -r/-a are unavailable, reboot to reload" >&2