feat(panic): FUCK [panic] mode=strict|fallback + realtest image variant

- UTSM panic_full returns in fallback mode (logs [PANIC:FALLBACK] + code + hit
  count); panic_halt keeps always-halt sites (CPU exception, VMM-E11 LA57,
  VMM-E15 DSK jump, UTSM-E42 test hook). Call sites given safe continuations.
- Mode passed to DSK/FirstInit/login/desktop via DSK_BOOT_FLAG_PANIC_FALLBACK;
  DKM kernel_api.panic / kern.log.panic return to driver; ext4 fatal aborts the
  op via setjmp/longjmp and DSK falls back to FAT32 ESP.
- build.ps1/Makefile: dev=strict, release=fallback, new realtest (release
  options + strict); default -Variant all; serialized iso packing under -j.
- Fix '*/' inside comments (dkm.h, kernel_api.h, bus.c) that broke the build.
- Includes pending work: dkm_bus service bus, mt7920/wlan drivers, desktop
  files/startmenu/prank, pe-tools, diskinfo, docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Linehu
2026-10-12 23:57:19 +08:00
co-authored by Cursor
parent a7e5b2bc7a
commit 8554a82677
84 changed files with 7325 additions and 484 deletions
+97 -30
View File
@@ -43,9 +43,59 @@ static void pregline(fbc_ctx *p, const char *name, u64 v, i64 x, i64 y, u32 fg)
phex64(p, v, x + 5 * g_ascii_w, y, fg);
}
/* ---- DRR 归档(drr.h 声明,drr_stub.c 提供;未初始化时返回 -1) ---- */
/* 按屏宽折行居中。返回下一行 y。超出 y_limit 的行不画。 */
static i64 pwrap(fbc_ctx *p, const char *s, i64 y, i64 y_limit, u32 fg) {
i64 cols;
if (!s) return y;
cols = (i64)p->w / g_ascii_w - 2;
if (cols < 8) cols = 8;
if (cols > 120) cols = 120;
while (*s && y + g_ascii_h <= y_limit) {
char line[121];
i64 n = 0;
while (s[n] && n < cols) { line[n] = s[n]; n++; }
line[n] = 0;
s += n;
fbc_string_center(p, line, y, fg);
y += g_ascii_h + 4;
}
return y;
}
/* ---- panic 模式(panic.h 头注释) ---- */
static int g_panic_fallback;
static u32 g_panic_fallback_hits;
void panic_set_fallback(int enable) {
g_panic_fallback = enable ? 1 : 0;
log_info(g_panic_fallback ? "[PANIC] mode=fallback (panic points take backup paths)"
: "[PANIC] mode=strict (zero degradation)");
}
int panic_fallback_enabled(void) {
return g_panic_fallback;
}
u32 panic_fallback_hits(void) {
return g_panic_fallback_hits;
}
void panic_full(const char *symbol, const char *msg, const panic_regs *regs) {
if (g_panic_fallback && !regs) {
g_panic_fallback_hits++;
log_warn("[PANIC:FALLBACK] panic point hit, taking backup path");
if (symbol) log_warn(symbol);
if (msg) log_warn(msg);
log_hex64("[PANIC:FALLBACK] hits=", g_panic_fallback_hits);
return;
}
panic_halt(symbol, msg, regs);
}
/* ---- DRR 归档(drr.h 声明,drr_stub.c 提供;未初始化时返回 -1) ---- */
void panic_halt(const char *symbol, const char *msg, const panic_regs *regs) {
log_error("[PANIC] ==========================================");
log_error("[PANIC] panic_full: 莲花崩溃屏");
if (symbol) { log_error("[PANIC] symbol:"); log_error(symbol); }
@@ -75,43 +125,60 @@ void panic_full(const char *symbol, const char *msg, const panic_regs *regs) {
/* 背景色 = Logo 图片背景色(四角平均,gen_panic_logo.py 生成) */
fbc_fill_bg(p, g_panic_logo_bg);
/* DEAICUP 莲花 Logo 居中,文字随 logo 下缘排布 */
i64 ly = ((i64)p->h - (i64)g_panic_logo_h) / 2 - 40;
if (ly < 8) ly = 8;
fbc_draw_rgba(p, g_panic_logo_rgba,
(i64)g_panic_logo_w, (i64)g_panic_logo_h,
((i64)p->w - (i64)g_panic_logo_w) / 2, ly);
/* 底部留给错误码:莲花按整数步进缩小,保证 symbol/msg 落在屏内。
* 长串按屏宽折行,避免居中后错误码被裁出左右边缘。 */
const u32 fg = 0xFFF0E8D8, dim = 0xFFB0A8C0, acc = 0xFFF0D080;
i64 y = ly + (i64)g_panic_logo_h + 8;
fbc_string_center(p, "DESHAB PANIC", y, acc);
y += g_ascii_h + 8;
if (symbol) { fbc_string_center(p, symbol, y, fg); y += g_ascii_h + 8; }
if (msg) {
/* 单行截断 60 字符 */
char line[61];
u32 i = 0;
while (msg[i] && i < 60) { line[i] = msg[i]; i++; }
line[i] = 0;
fbc_string_center(p, line, y, fg);
y += g_ascii_h + 8;
}
if (regs) {
if (y + g_ascii_h * 6 < (i64)p->h) {
pregline(p, "RIP ", regs->rip, (i64)p->w / 2 - 14 * g_ascii_w / 2, y, dim); y += g_ascii_h + 2;
pregline(p, "RSP ", regs->rsp, (i64)p->w / 2 - 14 * g_ascii_w / 2, y, dim); y += g_ascii_h + 2;
pregline(p, "FLG ", regs->rflags, (i64)p->w / 2 - 14 * g_ascii_w / 2, y, dim); y += g_ascii_h + 2;
if (regs->vector == 14) {
pregline(p, "CR2 ", regs->cr2, (i64)p->w / 2 - 14 * g_ascii_w / 2, y, dim);
i64 text_need = (g_ascii_h + 6) * (regs ? 8 : 5);
i64 step = 1;
while (step < 8 &&
(i64)g_panic_logo_h / step + text_need + 24 > (i64)p->h)
step++;
i64 dw = (i64)g_panic_logo_w / step;
i64 dh = (i64)g_panic_logo_h / step;
i64 ly = ((i64)p->h - dh - text_need) / 2;
if (ly < 4) ly = 4;
{
i64 lx = ((i64)p->w - dw) / 2;
for (i64 r = 0; r < dh; r++) {
for (i64 c = 0; c < dw; c++) {
const unsigned char *px4 =
g_panic_logo_rgba + (((u64)r * (u64)step) * (u64)g_panic_logo_w
+ (u64)c * (u64)step) * 4;
u32 a = px4[3];
if (a < 8) continue;
u32 col = 0xFF000000u | ((u32)px4[0] << 16) | ((u32)px4[1] << 8) | px4[2];
if (a < 250) col = fbc_blend(fbc_pixel_read(p, lx + c, ly + r), col, a);
fbc_pixel(p, lx + c, ly + r, col);
}
}
}
fbc_string_center(p, archived == 0 ? "crash archived to DRR" : "DRR archive unavailable",
(i64)p->h - g_ascii_h - 24, dim);
i64 y_limit = (i64)p->h - 4;
i64 y = ly + dh + 8;
if (y + text_need > y_limit) y = y_limit - text_need;
if (y < 4) y = 4;
y = pwrap(p, "DESHAB PANIC", y, y_limit, acc);
y += 4;
y = pwrap(p, symbol, y, y_limit, fg);
y = pwrap(p, msg, y, y_limit, fg);
if (regs && y + g_ascii_h * 3 < y_limit) {
i64 rx = (i64)p->w / 2 - 12 * g_ascii_w;
if (rx < 4) rx = 4;
pregline(p, "RIP ", regs->rip, rx, y, dim); y += g_ascii_h + 2;
if (y + g_ascii_h < y_limit) { pregline(p, "RSP ", regs->rsp, rx, y, dim); y += g_ascii_h + 2; }
if (y + g_ascii_h < y_limit) { pregline(p, "FLG ", regs->rflags, rx, y, dim); y += g_ascii_h + 2; }
if (regs->vector == 14 && y + g_ascii_h < y_limit)
pregline(p, "CR2 ", regs->cr2, rx, y, dim);
}
if ((i64)p->h > g_ascii_h + 8) {
fbc_string_center(p, archived == 0 ? "crash archived to DRR" : "DRR archive unavailable",
(i64)p->h - g_ascii_h - 8, dim);
}
}
log_error("[PANIC] halt");
arch_halt_forever();
for (;;) __asm__ volatile("cli; hlt");
}
void panic(const char *msg) {