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:
+133
-71
@@ -189,31 +189,6 @@ static i64 fb_text_width(const char *s) {
|
||||
return n * ASCII_STEP;
|
||||
}
|
||||
|
||||
/* Alpha-blended ASCII text — same as fb_text but multiplied by a global alpha,
|
||||
* used to fade English subtitles in/out alongside the Chinese bitmaps. */
|
||||
static void fb_text_alpha(u32 *fb, const char *s, i64 x, i64 y, u32 fg, u32 bg, u32 global_alpha) {
|
||||
for (i64 i=0; s[i]; i++) {
|
||||
u32 ch = (u32)(u8)s[i];
|
||||
if (ch < ' ' || ch > '~') ch = ' ';
|
||||
u32 idx = ch - ' ';
|
||||
const u8 *g = g_ascii[idx];
|
||||
for (i64 r=0; r<ASCII_H; r++) {
|
||||
i64 yy = y + r;
|
||||
if (yy < 0 || (u64)yy >= fb_h) continue;
|
||||
u32 *line = (u32 *)((u8 *)fb + (u64)yy * fb_p);
|
||||
for (i64 c=0; c<ASCII_W; c++) {
|
||||
u32 a = g[r * ASCII_W + c];
|
||||
if (a == 0) continue;
|
||||
u32 eff_a = ((u32)a * global_alpha) >> 8;
|
||||
if (eff_a == 0) continue;
|
||||
i64 xx = x + i*ASCII_STEP + c;
|
||||
if (xx < 0 || (u64)xx >= fb_w) continue;
|
||||
line[(u64)xx] = (eff_a == 255) ? fg : blend(bg, fg, eff_a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* draw pre-rendered grayscale bitmap – writes only, no framebuffer read */
|
||||
static void fb_bitmap_alpha(u32 *fb, const u8 *data, i64 w, i64 h, i64 x, i64 y, u32 fg, u32 bg, u32 global_alpha) {
|
||||
for (i64 r=0; r<h; r++) {
|
||||
@@ -236,21 +211,33 @@ static void fb_bitmap_alpha(u32 *fb, const u8 *data, i64 w, i64 h, i64 x, i64 y,
|
||||
* 整屏显示错误码后停机。 */
|
||||
#include "../login/ohmylogo_data.c"
|
||||
|
||||
static u64 fi_fat_strlen(const char *s) { u64 n = 0; while (s[n]) n++; return n; }
|
||||
|
||||
static void fill_rect(u32 *fb, i64 x, i64 y, i64 w, i64 h, u32 color);
|
||||
/* DSK_BOOT_FLAG_PANIC_FALLBACK:firstinit_fatal 只留串口坐标后返回,调用点走备用路径 */
|
||||
static int g_panic_fallback;
|
||||
static void firstinit_fatal(const char *sym) {
|
||||
logl(sym);
|
||||
if (g_panic_fallback) {
|
||||
logl("[FirstInit:FALLBACK] fatal point hit, taking backup path");
|
||||
return;
|
||||
}
|
||||
if (fb_a) {
|
||||
u32 *fb = (u32 *)(u64)fb_a;
|
||||
fill_rect(fb, 0, 0, (i64)fb_w, (i64)fb_h, 0xFF020F22u);
|
||||
i64 lx = ((i64)fb_w - g_panic_logo_w) / 2;
|
||||
i64 ly = ((i64)fb_h - g_panic_logo_h) / 2 - 60;
|
||||
if (ly < 0) ly = 0;
|
||||
for (i64 r = 0; r < g_panic_logo_h; r++) {
|
||||
for (i64 c = 0; c < g_panic_logo_w; c++) {
|
||||
i64 text_need = (ASCII_H + 6) * 4;
|
||||
i64 step = 1;
|
||||
while (step < 8 &&
|
||||
(i64)g_panic_logo_h / step + text_need + 24 > (i64)fb_h)
|
||||
step++;
|
||||
i64 dw = (i64)g_panic_logo_w / step;
|
||||
i64 dh = (i64)g_panic_logo_h / step;
|
||||
i64 lx = ((i64)fb_w - dw) / 2;
|
||||
i64 ly = ((i64)fb_h - dh - text_need) / 2;
|
||||
if (ly < 4) ly = 4;
|
||||
for (i64 r = 0; r < dh; r++) {
|
||||
for (i64 c = 0; c < dw; c++) {
|
||||
const unsigned char *px4 =
|
||||
g_panic_logo_rgba + ((u64)r * g_panic_logo_w + (u64)c) * 4;
|
||||
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];
|
||||
@@ -267,11 +254,28 @@ static void firstinit_fatal(const char *sym) {
|
||||
*(u32 *)((u8 *)fb + (u64)yy * fb_p + (u64)xx * 4) = col;
|
||||
}
|
||||
}
|
||||
i64 ty = ly + g_panic_logo_h + 24;
|
||||
fb_text(fb, sym, ((i64)fb_w - (i64)fi_fat_strlen(sym) * ASCII_STEP) / 2,
|
||||
ty, 0xFFF2D8D8u, 0);
|
||||
fb_text(fb, "DESHAB NET FATAL - SYSTEM HALTED",
|
||||
((i64)fb_w - 32 * ASCII_STEP) / 2, ty + ASCII_H + 16, 0xFFB08890u, 0);
|
||||
i64 ty = ly + dh + 12;
|
||||
i64 y_limit = (i64)fb_h - 4;
|
||||
if (ty + text_need > y_limit) ty = y_limit - text_need;
|
||||
if (ty < 4) ty = 4;
|
||||
i64 cols = (i64)fb_w / ASCII_STEP - 2;
|
||||
if (cols < 8) cols = 8;
|
||||
if (cols > 120) cols = 120;
|
||||
{
|
||||
const char *s = sym ? sym : "";
|
||||
while (*s && ty + 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;
|
||||
fb_text(fb, line, ((i64)fb_w - n * ASCII_STEP) / 2, ty, 0xFFF2D8D8u, 0);
|
||||
ty += ASCII_H + 6;
|
||||
}
|
||||
}
|
||||
if (ty + ASCII_H <= y_limit)
|
||||
fb_text(fb, "DESHAB NET FATAL - SYSTEM HALTED",
|
||||
((i64)fb_w - 32 * ASCII_STEP) / 2, ty, 0xFFB08890u, 0);
|
||||
}
|
||||
for (;;) __asm__("cli; hlt");
|
||||
}
|
||||
@@ -296,23 +300,21 @@ static u32 bg_at_y(i64 y) {
|
||||
return blend(BG_TOP, BG_BOTTOM, (u32)(((u64)y * 255ULL) / (fb_h - 1)));
|
||||
}
|
||||
|
||||
static void fill_gradient_rect(u32 *fb, i64 x, i64 y, i64 w, i64 h) {
|
||||
for (i64 r=0; r<h; r++) {
|
||||
i64 yy = y + r;
|
||||
if (yy < 0 || (u64)yy >= fb_h) continue;
|
||||
u32 color = bg_at_y(yy);
|
||||
u32 *line = (u32 *)((u8 *)fb + (u64)yy * fb_p);
|
||||
for (i64 c=0; c<w; c++) {
|
||||
i64 xx = x + c;
|
||||
if (xx < 0 || (u64)xx >= fb_w) continue;
|
||||
line[(u64)xx] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 模糊化的桌面壁纸(与 login 共用,构建期盒模糊 back.rgba) */
|
||||
#include "../login/back_blur_data.c"
|
||||
|
||||
static u32 wallpaper_at(i64 x, i64 y) {
|
||||
if (fb_w == 0 || fb_h == 0) return BG_MID;
|
||||
if (x < 0) x = 0;
|
||||
if (y < 0) y = 0;
|
||||
if ((u64)x >= fb_w) x = (i64)fb_w - 1;
|
||||
if ((u64)y >= fb_h) y = (i64)fb_h - 1;
|
||||
u64 sy = (u64)y * WALLPAPER_BLUR_H / fb_h;
|
||||
u64 sx = (u64)x * WALLPAPER_BLUR_W / fb_w;
|
||||
const unsigned char *px = g_wall_blur_rgba + (sy * WALLPAPER_BLUR_W + sx) * 4;
|
||||
return 0xFF000000u | ((u32)px[0] << 16) | ((u32)px[1] << 8) | px[2];
|
||||
}
|
||||
|
||||
static void draw_blur_wallpaper(u32 *fb) {
|
||||
for (i64 y = 0; y < (i64)fb_h; y++) {
|
||||
u32 *line = (u32 *)((u8 *)fb + (u64)y * fb_p);
|
||||
@@ -326,6 +328,20 @@ static void draw_blur_wallpaper(u32 *fb) {
|
||||
}
|
||||
}
|
||||
|
||||
/* 卡片重绘不能再用深色渐变铺底,否则圆角外会留下一圈黑框。 */
|
||||
static void restore_wallpaper_rect(u32 *fb, i64 x, i64 y, i64 w, i64 h) {
|
||||
for (i64 r = 0; r < h; r++) {
|
||||
i64 yy = y + r;
|
||||
if (yy < 0 || (u64)yy >= fb_h) continue;
|
||||
u32 *line = (u32 *)((u8 *)fb + (u64)yy * fb_p);
|
||||
for (i64 c = 0; c < w; c++) {
|
||||
i64 xx = x + c;
|
||||
if (xx < 0 || (u64)xx >= fb_w) continue;
|
||||
line[(u64)xx] = wallpaper_at(xx, yy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int rounded_rect_contains(i64 px, i64 py, i64 x, i64 y, i64 w, i64 h, i64 radius) {
|
||||
if (px < x || py < y || px >= x + w || py >= y + h) return 0;
|
||||
if (radius <= 0) return 1;
|
||||
@@ -383,11 +399,54 @@ static void delay_frame(void) {
|
||||
|
||||
#include "text_bitmaps.c"
|
||||
|
||||
/* 开场文字画在壁纸上。透明字素跳过,抗锯齿边缘按该点壁纸颜色混合,
|
||||
* 不再铺一块灰渐变当底。 */
|
||||
static void fb_bitmap_on_wall(u32 *fb, const u8 *data, i64 w, i64 h, i64 x, i64 y, u32 fg, u32 global_alpha) {
|
||||
for (i64 r = 0; r < h; r++) {
|
||||
i64 yy = y + r;
|
||||
if (yy < 0 || (u64)yy >= fb_h) continue;
|
||||
u32 *line = (u32 *)((u8 *)fb + (u64)yy * fb_p);
|
||||
for (i64 c = 0; c < w; c++) {
|
||||
i64 xx = x + c;
|
||||
if (xx < 0 || (u64)xx >= fb_w) continue;
|
||||
u8 val = data[r * (u64)w + (u64)c];
|
||||
if (val == 0) continue;
|
||||
u32 a = ((u32)val * global_alpha) >> 8;
|
||||
if (a == 0) continue;
|
||||
u32 bg = wallpaper_at(xx, yy);
|
||||
line[(u64)xx] = (a >= 255) ? fg : blend(bg, fg, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fb_text_on_wall(u32 *fb, const char *s, i64 x, i64 y, u32 fg, u32 global_alpha) {
|
||||
for (i64 i = 0; s[i]; i++) {
|
||||
u32 ch = (u32)(u8)s[i];
|
||||
if (ch < ' ' || ch > '~') ch = ' ';
|
||||
const u8 *g = g_ascii[ch - ' '];
|
||||
for (i64 r = 0; r < ASCII_H; r++) {
|
||||
i64 yy = y + r;
|
||||
if (yy < 0 || (u64)yy >= fb_h) continue;
|
||||
u32 *line = (u32 *)((u8 *)fb + (u64)yy * fb_p);
|
||||
for (i64 c = 0; c < ASCII_W; c++) {
|
||||
u32 a = g[r * ASCII_W + c];
|
||||
if (a == 0) continue;
|
||||
u32 eff = (a * global_alpha) >> 8;
|
||||
if (eff == 0) continue;
|
||||
i64 xx = x + i * ASCII_STEP + c;
|
||||
if (xx < 0 || (u64)xx >= fb_w) continue;
|
||||
u32 bg = wallpaper_at(xx, yy);
|
||||
line[(u64)xx] = (eff >= 255) ? fg : blend(bg, fg, eff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fade_ring(u32 *fb, i64 cx, i64 cy, u32 bg) {
|
||||
/* Erase the spinner sprite area with gradient background in one frame. */
|
||||
/* 擦掉 DSK 加载环,露出壁纸,不再盖一块灰渐变。 */
|
||||
(void)bg;
|
||||
i64 r = 72;
|
||||
fill_gradient_rect(fb, cx-r, cy-r, r*2+1, r*2+1);
|
||||
restore_wallpaper_rect(fb, cx - r, cy - r, r * 2 + 1, r * 2 + 1);
|
||||
}
|
||||
|
||||
static void draw_card(u32 *fb, i64 x, i64 y, i64 w, i64 h, u32 card, u32 bg_color) {
|
||||
@@ -535,7 +594,7 @@ static void redraw_setup_card(u32 *fb, i64 card_x, i64 card_y, char *pc, char *u
|
||||
u32 card = CARD_BG;
|
||||
u32 sub_fg = 0xFF9098A0; /* dimmer English subtitle color on card */
|
||||
cursor_erase(fb);
|
||||
fill_gradient_rect(fb, card_x - 24, card_y - 24, 948, 648);
|
||||
restore_wallpaper_rect(fb, card_x - 24, card_y - 24, 948, 648);
|
||||
draw_card(fb, card_x, card_y, 900, 600, card, bg);
|
||||
fb_bitmap_alpha(fb, g_txt_title, g_txt_title_w, g_txt_title_h, card_x+40, card_y+40, fg, card, 255);
|
||||
fb_text(fb, "Account Setup", card_x+40, card_y+40+g_txt_title_h+2, sub_fg, card);
|
||||
@@ -763,7 +822,7 @@ static void draw_option_row(u32 *fb, i64 x, i64 y, i64 w, i64 h,
|
||||
static void redraw_prefs_card(u32 *fb, i64 card_x, i64 card_y, setup_prefs *prefs, int active, i64 mx, i64 my, u32 bg, u32 fg) {
|
||||
u32 card = CARD_BG;
|
||||
cursor_erase(fb);
|
||||
fill_gradient_rect(fb, card_x - 24, card_y - 24, 948, 648);
|
||||
restore_wallpaper_rect(fb, card_x - 24, card_y - 24, 948, 648);
|
||||
draw_card(fb, card_x, card_y, 900, 600, card, bg);
|
||||
fb_bitmap_alpha(fb, g_txt_prefs_title, g_txt_prefs_title_w, g_txt_prefs_title_h, card_x+40, card_y+40, fg, card, 255);
|
||||
fb_text(fb, "Preferences", card_x+40, card_y+40+g_txt_prefs_title_h+2, 0xFF9098A0, card);
|
||||
@@ -1154,7 +1213,7 @@ static void draw_wifi_row(u32 *fb, i64 card_x, i64 card_y, setup_net *net, int r
|
||||
static void redraw_network_card(u32 *fb, i64 card_x, i64 card_y, setup_net *net, int active, i64 mx, i64 my, u32 bg, u32 fg) {
|
||||
u32 card = CARD_BG;
|
||||
cursor_erase(fb);
|
||||
fill_gradient_rect(fb, card_x - 24, card_y - 24, 948, 648);
|
||||
restore_wallpaper_rect(fb, card_x - 24, card_y - 24, 948, 648);
|
||||
draw_card(fb, card_x, card_y, 900, 600, card, bg);
|
||||
fb_bitmap_alpha(fb, g_txt_network_title, g_txt_network_title_w, g_txt_network_title_h, card_x+40, card_y+40, fg, card, 255);
|
||||
fb_text(fb, "Network", card_x+40, card_y+40+g_txt_network_title_h+2, 0xFF9098A0, card);
|
||||
@@ -1273,8 +1332,9 @@ static void read_network_page(u32 *fb, i64 card_x, i64 card_y, setup_net *net, i
|
||||
if (*mx >= card_x + 680 && *mx < card_x + 860 && *my >= card_y + 310 && *my < card_y + 354) {
|
||||
/* 严格错误策略:无 wlan 驱动栈 —— 零降级 panic */
|
||||
firstinit_fatal("NET-E01 WLAN CONNECT NOT IMPLEMENTED");
|
||||
/* fallback:不连接,按"保存配置"处理(connected=配置已存,非已联网) */
|
||||
net->connected = 1;
|
||||
logl("[FirstInit] network connect requested");
|
||||
logl("[FirstInit] network connect unavailable, profile saved");
|
||||
redraw_network_card(fb, card_x, card_y, net, NET_ACT_CONNECT, *mx, *my, bg, fg);
|
||||
for (int i=0;i<30;i++) delay_frame();
|
||||
return;
|
||||
@@ -1328,8 +1388,9 @@ static void read_network_page(u32 *fb, i64 card_x, i64 card_y, setup_net *net, i
|
||||
} else if (active == NET_ACT_CONNECT) {
|
||||
/* 严格错误策略:无 wlan 驱动栈,"连接"是未实现路径 —— 零降级 panic */
|
||||
firstinit_fatal("NET-E01 WLAN CONNECT NOT IMPLEMENTED");
|
||||
/* fallback:不连接,按"保存配置"处理(connected=配置已存,非已联网) */
|
||||
net->connected = 1;
|
||||
logl("[FirstInit] network connect requested");
|
||||
logl("[FirstInit] network connect unavailable, profile saved");
|
||||
redraw_network_card(fb, card_x, card_y, net, active, *mx, *my, bg, fg);
|
||||
for (int i=0;i<30;i++) delay_frame();
|
||||
return;
|
||||
@@ -1443,6 +1504,7 @@ void dsk_entry(const dsk_boot_context *ctx) {
|
||||
logl("[FirstInit] bad context");
|
||||
for(;;) __asm__("hlt");
|
||||
}
|
||||
g_panic_fallback = (ctx->flags & DSK_BOOT_FLAG_PANIC_FALLBACK) ? 1 : 0;
|
||||
|
||||
fb_a = ctx->framebuffer_address;
|
||||
fb_w = ctx->framebuffer_width;
|
||||
@@ -1479,9 +1541,9 @@ void dsk_entry(const dsk_boot_context *ctx) {
|
||||
|
||||
logl("[FirstInit] fading in welcome");
|
||||
for (u32 a=0; a<=255; a+=17) {
|
||||
fill_gradient_rect(fb, tx-4, ty-4, tw+8, g_txt_welcome_h + 6 + ASCII_H + 4);
|
||||
fb_bitmap_alpha(fb, g_txt_welcome, tw, g_txt_welcome_h, tx, ty, WELCOME_FG, bg_at_y(ty + g_txt_welcome_h / 2), a);
|
||||
fb_text_alpha(fb, welcome_en, en_x, en_y, sub_fg, bg_at_y(en_y + ASCII_H/2), a);
|
||||
restore_wallpaper_rect(fb, tx-4, ty-4, tw+8, g_txt_welcome_h + 6 + ASCII_H + 4);
|
||||
fb_bitmap_on_wall(fb, g_txt_welcome, tw, g_txt_welcome_h, tx, ty, WELCOME_FG, a);
|
||||
fb_text_on_wall(fb, welcome_en, en_x, en_y, sub_fg, a);
|
||||
delay_frame();
|
||||
}
|
||||
logl("[FirstInit] welcome drawn");
|
||||
@@ -1505,11 +1567,11 @@ void dsk_entry(const dsk_boot_context *ctx) {
|
||||
for (u32 step=0; step<=15; step++) {
|
||||
u32 a2 = step * 17;
|
||||
u32 a1 = 255 - a2;
|
||||
fill_gradient_rect(fb, area_x-4, ty-4, area_w+8, area_h);
|
||||
fb_bitmap_alpha(fb, g_txt_welcome, tw, g_txt_welcome_h, tx, ty, WELCOME_FG, bg_at_y(ty + g_txt_welcome_h / 2), a1);
|
||||
fb_text_alpha(fb, welcome_en, en_x, en_y, sub_fg, bg_at_y(en_y + ASCII_H/2), a1);
|
||||
fb_bitmap_alpha(fb, g_txt_setup, tw2, g_txt_setup_h, tx2, ty, WELCOME_FG, bg_at_y(ty + g_txt_setup_h / 2), a2);
|
||||
fb_text_alpha(fb, setup_en, en2_x, en_y, sub_fg, bg_at_y(en_y + ASCII_H/2), a2);
|
||||
restore_wallpaper_rect(fb, area_x-4, ty-4, area_w+8, area_h);
|
||||
fb_bitmap_on_wall(fb, g_txt_welcome, tw, g_txt_welcome_h, tx, ty, WELCOME_FG, a1);
|
||||
fb_text_on_wall(fb, welcome_en, en_x, en_y, sub_fg, a1);
|
||||
fb_bitmap_on_wall(fb, g_txt_setup, tw2, g_txt_setup_h, tx2, ty, WELCOME_FG, a2);
|
||||
fb_text_on_wall(fb, setup_en, en2_x, en_y, sub_fg, a2);
|
||||
delay_frame();
|
||||
}
|
||||
logl("[FirstInit] setup message drawn");
|
||||
@@ -1673,17 +1735,17 @@ void dsk_entry(const dsk_boot_context *ctx) {
|
||||
logl("[FirstInit] config ready for DSK to write");
|
||||
|
||||
cursor_erase(fb);
|
||||
fill_gradient_rect(fb, card_x - 24, card_y - 24, 948, 648);
|
||||
fb_bitmap_alpha(fb, g_txt_done, g_txt_done_w, g_txt_done_h, cx - g_txt_done_w/2, cy - 30, fg, bg_at_y(cy), 255);
|
||||
restore_wallpaper_rect(fb, card_x - 24, card_y - 24, 948, 648);
|
||||
fb_bitmap_on_wall(fb, g_txt_done, g_txt_done_w, g_txt_done_h, cx - g_txt_done_w/2, cy - 30, fg, 255);
|
||||
/* English subtitle below the Chinese done bitmap */
|
||||
{ const char *done_en = "Setup Complete";
|
||||
i64 dw = fb_text_width(done_en);
|
||||
fb_text(fb, done_en, cx - dw/2, cy + 2, 0xFFA8B8C8, bg_at_y(cy + 10));
|
||||
fb_text_on_wall(fb, done_en, cx - dw/2, cy + 2, 0xFFA8B8C8, 255);
|
||||
}
|
||||
/* status line below the subtitle */
|
||||
{ const char *status = "System starting...";
|
||||
i64 sw = fb_text_width(status);
|
||||
fb_text(fb, status, cx - sw/2, cy + 28, 0xFF808088, bg_at_y(cy + 36));
|
||||
fb_text_on_wall(fb, status, cx - sw/2, cy + 28, 0xFF808088, 255);
|
||||
}
|
||||
logl("[FirstInit] user setup finished");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user