P1 根因(评审给的真机驱动证据链,已按其最小修法改):
/module_driver/pwm_backlight.sh 是 `insmod pwm_backlight.ko ... default_brightness=0
max_brightness=101`,模块 init 把 props.brightness 置 0 再 update_status(PWM 0 分支)→ 上电即灭屏;
该模块由 S11module_driver_default 加载,rcS 自然序排在 S11jpeg_display_shell 之后。于是:
- 函数入口那次 bl_cap:背光节点还不存在,写必然失败(no-op);
- fb0 出现后画图前那次 bl_cap:读到 cur=0,旧条件 `cur <= cap` 命中「只降不升」跳过分支,
20 从未写入 → 画图时刻亮度 0。
物理后果两头都是缺陷:面板仍亮则 logo 依旧亮(原问题没修);面板灭则 S11~S21 无可见 logo,
settings.conf 缺失时直到 launcherd 才亮屏(相对 stock「0.1s 后写 60」是回归)。
修改:
- bl_cap 判定改为「仅 1 <= cur <= cap 才视为已有有效值跳过;0 / 空 / 非数字一律照写」。
S22 抢写 1 的竞态保护不变(1 落在 1..20 → 仍跳过,不会被顶回 20)。
- 删掉函数入口那次 bl_cap(节点未建,必然 no-op,且是重定向报错的来源);只保留 fb0 就绪后、
画 logo 前那一次 —— 同一驱动脚本里 pwm_backlight.ko 先于 soc_fb.ko 加载,fb0 出现即节点就绪。
- 写入成功时打一行 `backlight: -> 20 (was N)` 便于刷机后复核;`2>/dev/null` 移到 `>` 之前,
节点未就绪时连重定向报错一起吞掉(P2-1)。
- S22:失败路径日志由「保持 S11 低亮度」改为「不改背光(当前 brightness=N)」(P2-2);写入失败
日志同样附当前读数;写入处的 2>/dev/null 次序一并改正。
- 头部注释按时序真相重写(驱动默认 0 = 灭屏,不是「上电很亮」)。
实测(沙箱重写 sysfs 路径 + stub cmd_jpeg_display/nanddump/sleep,dash 与 busybox 各一遍):
cur=0 → 画图时刻 20、结束 20(修复前 0/0);cur=1 → 1/1;cur=60、cur=101 → 20/20;
竞态(fb0 就绪前外部写 1)→ 画图时刻 1、结束 1(未被顶回);节点不可写时 stderr 0 行、仍画图、rc=0。
S22 19 用例全 rc=0(仅 usage rc=1,rcS 不可达)、sleep 调用 0、行为与改文案前一致。
S11 与 S22 内容均变 → fw_content.conf 两条 md5 同步更新为
3ad33301fb9f0884102a47e17a1985ed / 1a0aa33d6f806f3f1648168cc1d8b953
(未改动 meow_watchdog 那条:main tip dfde95b 仍是 553840cd,与本单无关,已在报告中提示。)
103 lines
5.0 KiB
Bash
Executable File
103 lines
5.0 KiB
Bash
Executable File
#!/bin/sh
|
||
#
|
||
# S11jpeg_display_shell — 开机 logo 显示(stock 基线 + MeowOS M21 改动)
|
||
#
|
||
# stock 基线(md5 249220f2489f63a4c946c55d8d981ca9)的问题:
|
||
# `cmd_jpeg_display` 画完 logo **之后**才写死 60。画图那一刻用的是驱动默认亮度,而真机
|
||
# /module_driver/pwm_backlight.sh 是 `insmod pwm_backlight.ko ... default_brightness=0
|
||
# max_brightness=101`,pwm_backlight.ko 的 init 会把 props.brightness 置 0 再 update_status
|
||
# (走 PWM 0 分支)—— 即上电是**全黑**:logo 先画在灭屏上,0.1s 后才被写死的 60 照亮,
|
||
# 一出现就是 60(≈60% 亮度,用户报「冷启动开机 logo 挺亮」)。
|
||
# 本脚本又跑在 S21mount_ubifs 之前:那时 /usr/data 还没挂载,读不到
|
||
# /usr/data/meow/settings.conf,所以这里**只能**写一个和用户设置无关的安全低值。
|
||
#
|
||
# M21 改动:
|
||
# 1) 在画 logo **之前**写 BOOT_BL_MAX=20(≈max_brightness 101 的 1/5):logo 以「暗但可见」出现;
|
||
# 2) 删除画完后写死 60 的那行 —— 用户亮度改由 S22brightness(/usr/data 挂载后)就位;
|
||
# 3) 写入「只降不升」:当前值落在 **1..20**(有效且已更暗,例如 S22 已按用户设置写成 1)才不动;
|
||
# **0 / 空 / 非数字一律照写 20** —— 驱动默认就是 0(等于灭屏),把 0 当「已有值」跳过会让本
|
||
# 脚本一个值都写不进去(评审 P1:画图时刻亮度 0,且删掉 60 后整段 init 没有可见 logo)。
|
||
# 4) /dev/fb0 等待、mtd5 主题判定、后台 `jpeg_display &` 语义与 stock 一致。
|
||
#
|
||
# 时序(三层写入者 + 运行期):
|
||
# 驱动默认 0(灭)→ S11 写 20(画 logo 前,logo 暗而可见)→ S21mount_ubifs
|
||
# → S22brightness(用户值,如 1)→ S70/S90 launcher/watchdog 继续按 display.brightness 维持。
|
||
#
|
||
# 注:rcS 用 `$i start` fork 执行本脚本,`jpeg_display &` 后父进程立即返回。所以写入必须在
|
||
# jpeg_display() **函数体内**(子进程自己的时序),不能挪到 case 分支顶层 —— 那是父进程,
|
||
# 会和子进程抢时序。
|
||
# ⚠️ 也不能放在函数入口:背光模块由排在后面的 S11module_driver_default(rcS 自然序
|
||
# S11jpeg_display_shell < S11module_driver_default)才 insmod,入口那一刻
|
||
# /sys/class/backlight/backlight_pwm0/ 还不存在,写入必然 no-op(重定向失败还会漏一行错)。
|
||
# 能写的时机是 /dev/fb0 出现之后 —— 同一份驱动脚本里 pwm_backlight.ko 先于 soc_fb.ko 加载,
|
||
# fb0 一出现背光节点必定已就绪。
|
||
|
||
BL_BRIGHTNESS="/sys/class/backlight/backlight_pwm0/brightness"
|
||
# 画 logo 前的亮度上限(绝对档位 0..max_brightness,不是百分比)。
|
||
# 这是「暗但可见」的安全低值,不是用户值;用户值(display.brightness,可能更暗如 1)由 S22brightness 写入。
|
||
BOOT_BL_MAX=20
|
||
|
||
# 只降不升地把背光压到 <= $1:
|
||
# 当前读数在 1..$1 = 已有有效且更暗的值(如 S22 已写用户值 1)→ 不动;
|
||
# 0 / 空 / 非数字(驱动默认 0 = 灭屏、节点未就绪)→ 视为「没有有效值」,照写。
|
||
bl_cap()
|
||
{
|
||
cap="$1"
|
||
cur=$(cat "$BL_BRIGHTNESS" 2>/dev/null)
|
||
case "$cur" in
|
||
''|*[!0-9]*) ;; # 读不到 / 非数字 → 照写
|
||
*) [ "$cur" -ge 1 ] && [ "$cur" -le "$cap" ] && return 0 ;; # 已有 1..cap 的有效值 → 不动
|
||
esac
|
||
# 2>/dev/null 放在 > 之前:节点尚未就绪时连「重定向失败」的报错一起吞掉(否则每个冷启动漏一行)。
|
||
if echo "$cap" 2>/dev/null > "$BL_BRIGHTNESS"; then
|
||
echo "backlight: -> $cap (was ${cur:-unreadable})"
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
jpeg_display()
|
||
{
|
||
echo "Starting display... "
|
||
|
||
while true
|
||
do
|
||
if [ -e "/dev/fb0" ]; then
|
||
break
|
||
fi
|
||
sleep 0.02
|
||
done
|
||
|
||
echo "Wait display... "
|
||
|
||
# M21:画 logo 前写一次安全低亮度。此时背光节点必定已就绪(同一驱动脚本里
|
||
# pwm_backlight.ko 先于 soc_fb.ko 加载,fb0 出现即背光已注册)。只降不升:
|
||
# cur 落在 1..20 的有效值就不动;cur=0(驱动默认 = 灭屏)照写 20;
|
||
# S22brightness 若已写更暗的用户值也不会被顶回 20。
|
||
bl_cap "$BOOT_BL_MAX"
|
||
|
||
theme=$(nanddump -q -s 0x20000 -l 7 /dev/mtd5 -a)
|
||
# stock 写的是 `==`(BusyBox test 接受,dash/POSIX test 不接受);语义不变,改为 `=` 以便移植与宿主验证。
|
||
if [ "$theme" = "theme:1" ]; then
|
||
cmd_jpeg_display /etc/logo1.jpeg
|
||
elif [ "$theme" = "theme:2" ]; then
|
||
cmd_jpeg_display /etc/logo2.jpeg
|
||
else
|
||
cmd_jpeg_display /etc/logo.jpeg
|
||
fi
|
||
# stock: "R1 lg 35583 need 100ms delay" —— 原先是给「画完后写 60」留的面板 settle 时间。
|
||
# 亮度写入已移到画图之前,但该硬件 settle 保留(在后台子进程里,不阻塞 init 链)。
|
||
sleep 0.1
|
||
echo "Finish display... "
|
||
}
|
||
|
||
case "$1" in
|
||
start)
|
||
jpeg_display &
|
||
|
||
;;
|
||
*)
|
||
exit 1
|
||
esac
|
||
|
||
exit 0
|