fix(boot): M69 普通重启/OTA 重启不再改写持久启动默认,切 Hiby 走一次性指示
用户定案(2026-11-12):/data/meow_boot_default 是「设置里的默认系统」, 只有显式设默认才许写;普通重启与 OTA 重启都不碰它,重启后选单按配置默认 (含 5s 倒计时)。「切换到 HibyOS」是这一次去 Hiby,用一次性指示 /data/meow_boot_once(bootmenu 开机读一次即删),不改持久默认。 meow_svc_power.c - 新增 boot_default_intent()/apply_boot_default_intent():唯一写入点, CLI 与 IPC 共用一张意图表(SET_DEFAULT_* -> 持久;BACK_HIBY -> 一次性; REBOOT/UPGRADE/SHUTDOWN -> 两个都不写)。 - POWER_REBOOT 与 CLI `reboot` 删掉 write_boot_default(0)(病根)。 - POWER_BACK_HIBY 与 CLI `reboot --hiby` 改走同一条一次性指示路径。 - 写失败照常重启,只把消息说清楚(不静默假装成功)。 meow_bootmenu.c - 新增 consume_boot_once():严格解析 0/1、读到即 unlink;删不掉时退一步 清空内容并记日志,本次照用,绝不让开机失败。 - load_config() 优先级写明并落地:一次性指示 > 持久默认 > meow.conf > 编译默认。 - DEF_BOOT_DEFAULT 1 -> 0(MeowOS):与设置页 boot.default 默认值一致, 避免「没设过默认/刷完固件首次开机」被丢进 Hiby。 测试(宿主,路径重定向到临时目录,不碰 /data) - svc_power_bootdefault_test.c:意图表 + 落盘副作用 + 反向控制(改前会写)。 - test_bm_bootdefault.c:一次性指示优先/读一次即删/删后回落/非法内容/删不掉仍可开机。 未提交二进制、未改 scripts/build/fw_content.conf(钉值仍对应现有二进制, 下一轮重编再把 md5 回写)。
This commit is contained in:
1 parent
a5fce76747
commit
84c7446aa6
4 files changed
+581
-41
No files matched your search
@@ -120,6 +120,8 @@
|
||||
#define FB_DEV "/dev/fb0"
|
||||
#define MEOWAPPS "/usr/data/mnt/sd_0/MeowAPPs"
|
||||
#define CONF_FILE MEOWAPPS "/meow.conf" /* TF 卡配置:boot_timeout_ms/boot_menu/bg_color;boot_default 权威在板载 /data/meow_boot_default */
|
||||
#define BOOT_DEFAULT_FILE "/data/meow_boot_default" /* 持久默认=设置里的「默认系统」:0=MeowOS,1=HibyOS */
|
||||
#define BOOT_ONCE_FILE "/data/meow_boot_once" /* 一次性指示:1=这次开机进 HibyOS(本程序读一次即删) */
|
||||
#define MODE_FILE "/tmp/meow_boot_mode" /* 开机模式标记(tmpfs,开机清空) */
|
||||
#define PLAYER_BIN "/usr/bin/hiby_player"
|
||||
#define PLAYER_LOG "/usr/data/meow_player.log"
|
||||
@@ -173,8 +175,11 @@
|
||||
#endif
|
||||
#define KEYBUF_WORDS 32 /* 1024 bits, 覆盖 KEY_MAX 767 */
|
||||
|
||||
/* ---- 编译默认值(可被 /usr/data/mnt/sd_0/MeowAPPs/meow.conf 覆写)---- */
|
||||
#define DEF_BOOT_DEFAULT 1 /* 1=HibyOS 0=MeowOS */
|
||||
/* ---- 编译默认值(可被 /usr/data/mnt/sd_0/MeowAPPs/meow.conf 覆写)----
|
||||
* M69(2026-11-12 定案):默认改 0(MeowOS)。理由:设置页「默认系统」的默认值就是 meow
|
||||
* (meow_settings.c `boot.default` 默认 "meow"),且这是 MeowOS 自己的固件——用户从未设过默认
|
||||
* 时不该被丢进 Hiby(旧值 1 与设置页默认矛盾,也是「每次升级后要手动切」的主因)。 */
|
||||
#define DEF_BOOT_DEFAULT 0 /* 1=HibyOS 0=MeowOS */
|
||||
#define DEF_BOOT_TIMEOUT_MS 5000
|
||||
#define DEF_BOOT_MENU 1
|
||||
#define DEF_BG 0x000000
|
||||
@@ -514,18 +519,30 @@ static void draw_clock(uint32_t bg)
|
||||
|
||||
/* ================================================================== */
|
||||
/* 配置:boot_default / boot_timeout_ms / boot_menu / bg_color */
|
||||
/* boot_default:权威 = 板载 /data/meow_boot_default(O_TRUNC 单值、不写 TF 卡);
|
||||
* meow.conf 的 boot_default= 仅作无板载标记时的兜底(不新增写入,见 set_boot_default_meow)。 */
|
||||
/* boot_default 优先级(高 → 低;M69 定案 2026-11-12):
|
||||
* ① /data/meow_boot_once 一次性指示(「这一次去 HibyOS」,读一次即删)
|
||||
* ② /data/meow_boot_default 持久默认 = 设置里的「默认系统」(权威)
|
||||
* ③ TF 卡 meow.conf 的 boot_default=(无板载标记时的兜底)
|
||||
* ④ 编译默认 DEF_BOOT_DEFAULT(=MeowOS)
|
||||
* 一次性指示必须压过持久默认,否则用户把默认设成 MeowOS 后「切换到 HibyOS」永远失效。 */
|
||||
/* ================================================================== */
|
||||
static int cfg_boot_default = DEF_BOOT_DEFAULT;
|
||||
static long cfg_boot_timeout_ms = DEF_BOOT_TIMEOUT_MS;
|
||||
static int cfg_boot_menu = DEF_BOOT_MENU;
|
||||
static uint32_t cfg_bg = DEF_BG;
|
||||
|
||||
/* 读板载 /data/meow_boot_default(开机默认权威标记)。返回 0/1;-1=不存在/非法。 */
|
||||
/* 配置/标记文件的生产路径;宿主自测可直接重定向这三个指针(只换路径,不换语义)。 */
|
||||
static const char *g_conf_path = CONF_FILE;
|
||||
static const char *g_boot_default_path = BOOT_DEFAULT_FILE;
|
||||
static const char *g_boot_once_path = BOOT_ONCE_FILE;
|
||||
|
||||
/* bm_log 定义在后方(卡日志);load_config 记录一次性指示消费结果要用。 */
|
||||
static void bm_log(const char *fmt, ...);
|
||||
|
||||
/* 读板载 /data/meow_boot_default(=设置里的「默认系统」)。返回 0/1;-1=不存在/非法。 */
|
||||
static int read_boot_default_onboard(void)
|
||||
{
|
||||
int fd = open("/data/meow_boot_default", O_RDONLY);
|
||||
int fd = open(g_boot_default_path, O_RDONLY);
|
||||
if (fd < 0) return -1;
|
||||
char buf[8];
|
||||
int n = read(fd, buf, sizeof buf - 1);
|
||||
@@ -536,6 +553,50 @@ static int read_boot_default_onboard(void)
|
||||
return (v == 0 || v == 1) ? v : -1;
|
||||
}
|
||||
|
||||
/* 消费一次性指示 /data/meow_boot_once(meow_svc_power 写,本程序开机读一次即删)。
|
||||
* 返回 0/1;-1=不存在/内容非法。
|
||||
* 删除失败**不许影响开机**:本次照用该值;再尽量把内容清空,保证下一次开机读不到有效值
|
||||
* (两条都失败只记日志继续走,宁可日志脏也不让机器开不了机)。 */
|
||||
static int consume_boot_once(void)
|
||||
{
|
||||
int fd = open(g_boot_once_path, O_RDONLY);
|
||||
if (fd < 0) return -1;
|
||||
char buf[8];
|
||||
int n = read(fd, buf, sizeof buf - 1);
|
||||
close(fd);
|
||||
int v = -1;
|
||||
if (n > 0) {
|
||||
/* 严格取值:只接受 "0" / "1"(允许前后空白)。不能直接用 atoi —— "garbage" 会被
|
||||
* atoi 读成 0,等于把垃圾内容当成「进 MeowOS」的指示。 */
|
||||
buf[n] = 0;
|
||||
char *p = buf;
|
||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') p++;
|
||||
if (*p == '0' || *p == '1') {
|
||||
char c = *p++;
|
||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') p++;
|
||||
if (*p == 0) v = c - '0';
|
||||
}
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (unlink(g_boot_once_path) == 0) {
|
||||
bm_log("once: %s -> %s (used, removed)", g_boot_once_path, v < 0 ? "invalid" : (v ? "hiby" : "meow"));
|
||||
return v;
|
||||
}
|
||||
int uerr = errno;
|
||||
/* 删不掉:退而求其次清空内容(下次 open 读到 0 字节 → 非法 → 回落持久默认)。 */
|
||||
int wf = open(g_boot_once_path, O_WRONLY | O_TRUNC);
|
||||
if (wf >= 0) {
|
||||
close(wf);
|
||||
bm_log("once: %s -> %s (used; unlink failed: %s; truncated so next boot ignores it)",
|
||||
g_boot_once_path, v < 0 ? "invalid" : (v ? "hiby" : "meow"), strerror(uerr));
|
||||
} else {
|
||||
bm_log("once: %s -> %s (used; unlink+truncate failed: %s/%s; file may apply again next boot)",
|
||||
g_boot_once_path, v < 0 ? "invalid" : (v ? "hiby" : "meow"), strerror(uerr), strerror(errno));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static void load_config(void)
|
||||
{
|
||||
cfg_boot_default = DEF_BOOT_DEFAULT;
|
||||
@@ -543,13 +604,13 @@ static void load_config(void)
|
||||
cfg_boot_menu = DEF_BOOT_MENU;
|
||||
cfg_bg = DEF_BG;
|
||||
int has_conf = 1;
|
||||
FILE *f = fopen(CONF_FILE, "r");
|
||||
if (!f) { fprintf(stderr, "bootmenu: no %s, using defaults\n", CONF_FILE); has_conf = 0; }
|
||||
FILE *f = fopen(g_conf_path, "r");
|
||||
if (!f) { fprintf(stderr, "bootmenu: no %s, using defaults\n", g_conf_path); has_conf = 0; }
|
||||
if (has_conf) {
|
||||
char buf[128];
|
||||
while (fgets(buf, sizeof buf, f)) {
|
||||
if (!strncmp(buf, "boot_default=", 13)) {
|
||||
/* 板载 /data/meow_boot_default 为权威;此处仅作无板载标记时的兜底(不再新增写入)。 */
|
||||
/* 板载标记为权威;此处仅作无板载标记时的兜底(不再新增写入)。 */
|
||||
cfg_boot_default = atoi(buf + 13);
|
||||
if (cfg_boot_default != 0 && cfg_boot_default != 1) cfg_boot_default = DEF_BOOT_DEFAULT;
|
||||
} else if (!strncmp(buf, "boot_timeout_ms=", 16)) {
|
||||
@@ -565,12 +626,20 @@ static void load_config(void)
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
/* 板载标记优先(权威):覆盖 meow.conf 兜底/编译默认。 */
|
||||
int ob = read_boot_default_onboard();
|
||||
if (ob == 0 || ob == 1) {
|
||||
if (ob != cfg_boot_default)
|
||||
fprintf(stderr, "bootmenu: boot_default onboard=%d (override %d)\n", ob, cfg_boot_default);
|
||||
cfg_boot_default = ob;
|
||||
/* 一次性指示(这次开机专用)压过一切持久来源;读到即删。 */
|
||||
int oc = consume_boot_once();
|
||||
if (oc == 0 || oc == 1) {
|
||||
if (oc != cfg_boot_default)
|
||||
fprintf(stderr, "bootmenu: boot_default once=%d (override %d)\n", oc, cfg_boot_default);
|
||||
cfg_boot_default = oc;
|
||||
} else {
|
||||
/* 持久默认(设置里的「默认系统」)优先:覆盖 meow.conf 兜底/编译默认。 */
|
||||
int ob = read_boot_default_onboard();
|
||||
if (ob == 0 || ob == 1) {
|
||||
if (ob != cfg_boot_default)
|
||||
fprintf(stderr, "bootmenu: boot_default onboard=%d (override %d)\n", ob, cfg_boot_default);
|
||||
cfg_boot_default = ob;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "bootmenu: cfg boot_default=%d timeout_ms=%ld boot_menu=%d bg=%06x\n",
|
||||
cfg_boot_default, cfg_boot_timeout_ms, cfg_boot_menu, cfg_bg);
|
||||
@@ -1644,14 +1713,18 @@ static void write_mode(int choice)
|
||||
choice == 1 ? "hiby" : "meow");
|
||||
}
|
||||
|
||||
/* Bug 1:选 MeowOS → 把它持久为开机默认(写 spec 标记 + meow.conf boot_default=0),与 launcher
|
||||
* «回到HibyOS»(set_boot_default_hiby 写 boot_default=1)对称。效果:本次选中即进 MeowOS 主屏,且
|
||||
* 下一次开机选单默认 MeowOS(不再「选 MeowOS 仍落回 HibyOS」)。
|
||||
* 权威标记 = 板载 /data/meow_boot_default(O_TRUNC 单值);meow.conf 不再写/承载 boot_default。 */
|
||||
/* Bug 1:选 MeowOS → 把它持久为开机默认(写 spec 标记),与设置页「默认系统」/ `set-default-*` 对称。
|
||||
* 效果:本次选中即进 MeowOS 主屏,且下一次开机选单默认 MeowOS(不再「选 MeowOS 仍落回 HibyOS」)。
|
||||
* 权威标记 = 板载 /data/meow_boot_default(O_TRUNC 单值);meow.conf 不再写/承载 boot_default。
|
||||
* 注意:这是**用户在选单里显式选了 MeowOS**(等同设默认),与电源菜单「重启」路径无关。 */
|
||||
static void set_boot_default_meow(void)
|
||||
{
|
||||
int fd = open("/data/meow_boot_default", O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd >= 0) { write(fd, "0\n", 2); close(fd); fprintf(stderr, "bootmenu: /data/meow_boot_default=0\n"); }
|
||||
int fd = open(g_boot_default_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd >= 0) {
|
||||
write(fd, "0\n", 2);
|
||||
close(fd);
|
||||
fprintf(stderr, "bootmenu: %s=0\n", g_boot_default_path);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
Reference in new issue
Block a user