B860AV2.1 刷入 Armbian 后,板载 WiFi 与红外遥控均不可用。两项适配由两个仓库提供:
- b860av21-wifi:RTL8189FTV 驱动源码、可移植构建入口、板级供电设备树叠加
- b860av21-ir:NEC 遥控 keymap 与安装脚本
刷机步骤见 B860AV2.1刷Armbian。
环境
| 项目 | 内容 |
|---|---|
| 机顶盒 | B860AV2.1 |
| SoC | S905L-B(Amlogic GXL / S905L 类平台) |
| 系统 | Armbian noble,aarch64,内核 6.12.37-ophub |
| WiFi | RTL8189FTV,SDIO 024c:f179,2.4 GHz 802.11b/g/n |
| 遥控器 | NEC 地址 0x22,factory_code 0xDD220001 |
| 编译器 | GCC 14(该内核需要 -fmin-function-alignment=4) |
适配结构
两项适配各分两层,故障定位按层次区分。
WiFi:
- 设备树使能脚
GPIODV_27(控制器内偏移 76)输出高电平,芯片上电后被 SDIO 总线枚举。 - 8189fs 驱动提供扫描、STA 关联与数据收发。
红外:
- 内核 meson-ir + rc-core 完成 NEC 解码与输入事件上报。
- keymap 提供扫描码到
KEY_*的映射。
表现为“无无线接口”时查驱动,表现为“/sys/bus/sdio/devices 为空”时查设备树。红外不涉及驱动改动。
WiFi
1. 确认枚举
for d in /sys/bus/sdio/devices/*; do
[ -f "$d/vendor" ] || continue
printf '%s: ' "$d"
cat "$d/vendor" "$d/device"
done
判定:输出含 0x024c 与 0xf179 表示供电与枚举正常,进入第 2 步;输出为空时执行第 3 步。
gpio-599 一类的编号是当次启动的 Linux 全局 GPIO 号,随内核变化,不作为固定值。
2. 编译
git clone https://github.com/YsLtr/b860av21-wifi.git
cd b860av21-wifi
需要与目标内核完全匹配的 headers、make、bc 与编译器。ophub 的 headers 不在 Ubuntu 的 apt 仓库中,使用对应内核发行方提供的包。
CC=gcc-14 bash scripts/build.sh
modinfo ./8189fs.ko
交叉编译使用同一入口:
KERNEL_SRC=/path/to/matching/kernel/build ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- CC=aarch64-linux-gnu-gcc \
JOBS=4 bash scripts/build.sh
脚本直接调用外部模块的 Kbuild,只执行构建。支持的变量:KERNEL_SRC、CC、ARCH、CROSS_COMPILE、JOBS。
3. 设备树叠加(枚举为空时)
叠加只增加一个 output-high 的 GPIO hog,SDIO 时钟、引脚复用与其他外设保持不变。
sudo apt install device-tree-compiler
bash scripts/build-dtb.sh \
/boot/dtb/amlogic/meson-gxl-s905x-p212.dtb \
./meson-gxl-s905x-p212-b860av21-wifi.dtb
脚本以 dtc / fdtget / fdtoverlay 离线合并,不依赖引导程序支持动态 overlay;校验基础树为参考 P212 模型、pinctrl 控制器匹配;输出文件已存在时保留原文件。
安装前准备可启动的救援 SD 卡或串口,然后手工安装、备份、切换:
sudo install -m 0644 ./meson-gxl-s905x-p212-b860av21-wifi.dtb /boot/dtb/amlogic/
sudo cp -an /boot/extlinux/extlinux.conf /boot/extlinux/extlinux.conf.before-b860av21
sudoedit /boot/extlinux/extlinux.conf
修改当前使用条目的 fdt 行:
fdt /dtb/amlogic/meson-gxl-s905x-p212-b860av21-wifi.dtb
其他条目与启动参数保持原样,并保留一个原 DTB 的救援条目。从 uEnv.txt 读取启动配置的系统按实际路径修改。
该 hog 为常高供电,不含电源时序管理与省电关断;需要 runtime PM / suspend 时改用板级 regulator / mmc-pwrseq 并重新验证时序。
4. 安装模块
modinfo -F vermagic ./8189fs.ko
uname -r
modinfo -n 8189fs
find /lib/modules/"$(uname -r)" -type f -name '*8189fs.ko*'
首次安装(系统中无 8189fs 模块):
sudo install -D -m 0644 ./8189fs.ko \
/lib/modules/"$(uname -r)"/kernel/drivers/net/wireless/realtek/8189fs/8189fs.ko
sudo depmod -a
sudo modprobe 8189fs
驱动按 SDIO alias 自动加载。开机自动加载在 /etc/modules-load.d/8189fs.conf 写入一行 8189fs。
已有 8189fs 模块在运行时,modprobe 沿用内存中的旧模块。经有线或串口进入维护窗口,modprobe -r 8189fs 后重新加载,或安排重启。旧模块先备份到 /lib/modules 之外并记录原路径,保证同名模块只存一份。
5. 验证
lsmod | grep 8189fs
modinfo -F version 8189fs
ip -br link
iw dev
nmcli device wifi list
nmcli --ask device wifi connect 'YOUR_2G_SSID' ifname wlan0
iw dev wlan0 link
ip -4 addr show wlan0
ping -I wlan0 -c 5 YOUR_GATEWAY_IP
journalctl -k -b | grep -Ei '8189|mmc|sdio|warning|error'
接口名以 iw dev 输出为准。参考机同时出现 wlan0 与 wlan1,二者为同一张网卡,以可关联 STA 的接口为准。
ping 必须指定 -I wlan0:有线与无线同网段时不带 -I 可能经有线路径,无法证明无线通路。
重启后复查 SDIO ID、驱动版本、自动连接与内核日志。
6. 回滚
- 设备树:恢复备份的 extlinux 配置或选择原 DTB 启动条目;无法启动时用救援 SD 卡挂载启动分区恢复,确认生效后清理新增 DTB。
- 模块升级:卸载新模块,按原路径放回备份,
depmod -a后重新加载。 - 首次安装撤销:卸载 8189fs,删除本次新增的模块与自动加载配置,执行
depmod -a。
设备树与模块为两次独立变更,排障时分别回滚。
红外
1. 确认设备
ir-keytable
for dev in /sys/class/rc/rc*; do
[ -f "$dev/uevent" ] || continue
printf '\n%s\n' "$dev"
cat "$dev/uevent"
done
目标设备带 DRV_NAME=meson-ir;CEC 设备属于另一类。rc 编号由枚举顺序决定,重启后可能变化,按当次 uevent 取值。
2. 安装 keymap
git clone https://github.com/YsLtr/b860av21-ir.git
cd b860av21-ir
sudo sh ./install.sh --install
执行前通读 install.sh 与 zte_b860av21.toml。
脚本行为:
- 从 sysfs 识别唯一的
meson-ir设备;设备缺失或存在多个时退出并提示人工检查。 - 校验目标路径:符号链接、属主不符、组或其他用户可写时退出。
- 检查
/etc/rc_maps.cfg:无关行原样保留,本项目的行去重;存在其他meson-ir行或匹配本设备默认表名的通配行时退出,交由人工处理冲突。 - 修改前建立私有备份目录
/etc/b860av21-ir.backup.XXXXXXXX/,保存原配置与原 keymap;原文件缺失时写入对应.absent标记。 - 安装
/etc/rc_keymaps/zte_b860av21.toml,更新/etc/rc_maps.cfg。 - 输出实际设备名与下一步命令。
脚本只写文件,运行中的键表、协议、服务与启动配置保持原状。新增规则一行:
meson-ir * zte_b860av21.toml
重复运行幂等,内容一致时报 Already installed 并沿用现有备份。
3. 加载与验证
使配置对运行中的输入系统生效,rcN 替换为脚本输出的设备名:
RC=rcN
sudo ir-keytable -s "$RC" -r
sudo ir-keytable -s "$RC" -a /etc/rc_maps.cfg
sudo ir-keytable -s "$RC" -r
sudo ir-keytable -s "$RC" -t
加载前保留 -r 输出作为本机对照。加载后确认读回扫描码与表一致、NEC 协议已启用、输出无错误。
-t 中先测方向、OK、返回等无破坏性按键,再测数字、音量、彩色键并观察应用层响应;确认按下、释放与长按重复;最后测电源键。Ctrl-C 退出。
keymap 含 31 个键:电源、静音、方向、OK、返回、HOME、设置、菜单、音量、频道、四个彩色键、0-9、DEL、#/info。扫描码为 0x22xx 形式(电源 0x22dc、上 0x22ca、OK 0x22ce),取值为 Linux KEY_*:HOME 为 KEY_HOMEPAGE,设置为 KEY_SETUP,OK 为 KEY_ENTER。
4. 开机自动加载
取决于发行版既有的 udev / ir-keytable 规则是否读取 /etc/rc_maps.cfg。安装脚本沿用该机制,不创建服务。计划内重启后重新识别设备并用 -r 确认;需要时执行上文的 -a 命令显式加载。
5. 回滚
选择需要恢复到的那一次安装前的备份,重复安装会产生多个备份:
sudo -s
B=/etc/b860av21-ir.backup.XXXXXXXX
ls -ld "$B" /etc/rc_maps.cfg /etc/rc_keymaps
ls -la "$B"
for name in rc_maps.cfg zte_b860av21.toml; do
target=/etc/rc_maps.cfg
[ "$name" != zte_b860av21.toml ] || target=/etc/rc_keymaps/zte_b860av21.toml
if [ -f "$B/$name" ] && [ ! -L "$B/$name" ]; then
cp -p -- "$B/$name" "$target" || break
elif [ -f "$B/$name.absent" ]; then
rm -f -- "$target" || break
else
printf 'Missing backup: %s; STOP\n' "$name" >&2
break
fi
done
exit
备份之后若存在其他人或软件包做出的配置改动,人工合并后再落地。回滚只恢复文件;内存中的键表需重新执行 -a,或确认持久化配置已恢复后重启,由原有加载机制重新初始化,再用 -r 验证。
仓库自带检查
不需要硬件与 root:
# WiFi
cd b860av21-wifi
python3 tests/driver-check.py
bash tests/dtb-check.sh /path/to/stock/meson-gxl-s905x-p212.dtb
# 红外
cd b860av21-ir
sh -n install.sh
sh tests/test.sh
driver-check.py 校验版本边界、strlcpy 返回值语义、构建参数转发与源码 guard。dtb-check.sh 校验叠加只增加目标 hog、保留已有输出文件、删除新节点后与基础树一致。红外测试在 mktemp 私有目录中模拟 sysfs 与 /etc,覆盖首次安装、备份、幂等、重复规则、冲突、设备缺失/多设备、符号链接、权限与锁。
上述为软件测试,与硬件测试不等价:读回 keymap 显示 31 个键,与 31 个键逐一实按验证是两件事。
限制
WiFi:
- 芯片为 2.4 GHz 802.11b/g/n,5 GHz 属于硬件之外的能力,更换驱动无法获得。
- 不盲扫 GPIO 寻找使能脚,其他引脚控制存储、电源或复位。
- 不假定设备名为
mmc0:0001:1,按当次/sys/bus/sdio/devices/*取值。 - 芯片已枚举时不修改设备树。
- 不用 x86 headers 构建 ARM64 模块,不跨内核复制
.ko,不使用--force-vermagic;内核驱动 API 不稳定,升级后按新内核重新编译。 - 不将本叠加用于其他盒子的整机 DTB;原设备树已占用偏移 76 的 regulator/hog 时冲突。
- 不复制其他机器的 root UUID、IP、MAC。
- 不通过正在使用的 WiFi 连接卸载驱动。
- 不用缩短 systemd 超时或强制重启掩盖驱动/服务故障。
- 实机已验证:SDIO 枚举、模块加载、2.4 GHz 扫描与 STA 连接、传输、断开/重载驱动与重启后自动恢复。AP、P2P、休眠唤醒、长期压力测试属未验证范围。
红外:
- 不使用
curl | sudo sh;脚本与源文件放在自己控制、其他用户不会同时修改的目录。 - 不假定设备为
rc0或rc1。 - 恢复只用本机、root 所有、内容已核对的备份。
- 不盲目选最后一个备份;备份之后存在新改动时整文件恢复会覆盖这些改动。
- 不以“文件已安装”作为“开机持久化已验证”,不以退出码 0 或
Wrote …作为写入成功的唯一依据。 -r输出为诊断文本,不能直接交给-w作为 TOML 备份。- 回滚文件不恢复内存中的键表;旧配置没有匹配本设备的行时,
-a可能保留当前表。 KEY_POWER是运行中的输入事件,关机后能否唤醒由电源管理策略、待机供电、bootloader/固件唤醒码与硬件接线共同决定。- 测试电源键前保存未保存的数据。
--stage仅用于隔离测试,不指向真实根目录或 bind mount。
来源与许可
WiFi 源码由 OpenIPC realtek-wlan(分支 rtl8189fs,基线 f0a677f)分出,保留上游历史与版权;相对基线的改动集中在 Makefile、os_intfs.c、ioctl_cfg80211.c,以版本条件整合。红外部分为扫描码整理与安装脚本,解码由内核 meson-ir 完成,扫描码取自 system/etc/remote_dd22.conf。
两者均为 GPLv2 系许可,详见各自仓库的 COPYING / NOTICE。