Files
MeowOS-For-R3P2/patch_v2/bootmenu/S11jpeg_display_shell
T
AskaEth f9c2ea42a4 fix(boot): M21 r1 评审 P1 — bl_cap 把 cur=0 当「无有效值」照写 20(+P2 两处)
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,与本单无关,已在报告中提示。)
2026-11-05 22:04:16 +08:00

103 lines
5.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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