feat: DEAICUP lotus panic screen + F2 fbcon abstraction
- panic screen now draws embedded ohMyLogo.png (384px RGBA, gen_panic_logo.py); background color sampled from image corners so screen bg matches logo bg - F2: include/utsm/fbcon.h unified framebuffer console (pixel/blend/fill/rgba-image/text with FBCON_HAVE_FONT opt-in); panic.c migrated onto it - build.ps1 regenerates panic_logo_data.inc when ohMyLogo.png changes
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
#ifndef UTSM_FBCON_H
|
||||
#define UTSM_FBCON_H
|
||||
|
||||
#include <utsm/types.h>
|
||||
#include "../arch/x86_64/limine.h"
|
||||
|
||||
/* boot_modules.c 提供(Limine framebuffer 请求) */
|
||||
extern volatile struct limine_framebuffer_request g_fb_request;
|
||||
|
||||
/* ===================================================================
|
||||
* F2: 统一帧缓冲控制台抽象(fbcon)
|
||||
*
|
||||
* 让"疯要有画面"不绑定任何一个驱动:
|
||||
* - 崩溃路径(panic.c):驱动可能已挂,直接用 Limine fb
|
||||
* - 早期控制台 / 任何需要直绘的 UTSM 内部路径
|
||||
*
|
||||
* 32bpp XRGB,全部带边界检查,无堆依赖。
|
||||
* 文本渲染需要先 include 字库(g_ascii/g_ascii_w/g_ascii_h,
|
||||
* 见 kernel/panic_font.inc)。
|
||||
* =================================================================== */
|
||||
|
||||
typedef struct {
|
||||
u32 *fb;
|
||||
u64 w, h, pitch;
|
||||
} fbc_ctx;
|
||||
|
||||
/* 从 Limine framebuffer 初始化;失败 -1(无 fb / 非 32bpp) */
|
||||
static inline int fbc_init(fbc_ctx *c) {
|
||||
if (!g_fb_request.response || g_fb_request.response->framebuffer_count == 0)
|
||||
return -1;
|
||||
struct limine_framebuffer *fb = g_fb_request.response->framebuffers[0];
|
||||
if (fb->bpp < 32 || !fb->address) return -1;
|
||||
c->fb = (u32 *)fb->address;
|
||||
c->w = fb->width;
|
||||
c->h = fb->height;
|
||||
c->pitch = fb->pitch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fbc_pixel(fbc_ctx *c, i64 x, i64 y, u32 col) {
|
||||
if (x < 0 || (u64)x >= c->w || y < 0 || (u64)y >= c->h) return;
|
||||
*(u32 *)((u8 *)c->fb + (u64)y * c->pitch + (u64)x * 4) = col;
|
||||
}
|
||||
|
||||
static inline u32 fbc_pixel_read(fbc_ctx *c, i64 x, i64 y) {
|
||||
if (x < 0 || (u64)x >= c->w || y < 0 || (u64)y >= c->h) return 0;
|
||||
return *(u32 *)((u8 *)c->fb + (u64)y * c->pitch + (u64)x * 4);
|
||||
}
|
||||
|
||||
/* alpha 混合(0–255) */
|
||||
static inline u32 fbc_blend(u32 bg, u32 fg, u32 alpha) {
|
||||
u32 na = 256 - alpha;
|
||||
u32 r = (((bg >> 16) & 0xFF) * na + ((fg >> 16) & 0xFF) * alpha) >> 8;
|
||||
u32 g = (((bg >> 8) & 0xFF) * na + ((fg >> 8) & 0xFF) * alpha) >> 8;
|
||||
u32 b = ((bg & 0xFF) * na + (fg & 0xFF) * alpha) >> 8;
|
||||
return 0xFF000000u | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
static inline void fbc_fill_rect(fbc_ctx *c, i64 x, i64 y, i64 w, i64 h, u32 col) {
|
||||
for (i64 r = 0; r < h; r++)
|
||||
for (i64 cx = 0; cx < w; cx++)
|
||||
fbc_pixel(c, x + cx, y + r, col);
|
||||
}
|
||||
|
||||
/* 全屏纯色(背景色填充) */
|
||||
static inline void fbc_fill_bg(fbc_ctx *c, u32 col) {
|
||||
for (u64 y = 0; y < c->h; y++) {
|
||||
u32 *line = (u32 *)((u8 *)c->fb + y * c->pitch);
|
||||
for (u64 x = 0; x < c->w; x++) line[x] = col;
|
||||
}
|
||||
}
|
||||
|
||||
/* RGBA8888 图像绘制(半透明像素与已绘背景混合) */
|
||||
static inline void fbc_draw_rgba(fbc_ctx *c, const unsigned char *d,
|
||||
i64 w, i64 h, i64 x, i64 y) {
|
||||
for (i64 r = 0; r < h; r++) {
|
||||
for (i64 cx = 0; cx < w; cx++) {
|
||||
const unsigned char *px4 = d + ((u64)r * w + (u64)cx) * 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(c, x + cx, y + r), col, a);
|
||||
fbc_pixel(c, x + cx, y + r, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- 文本 ----
|
||||
* 字库(g_ascii / g_ascii_w / g_ascii_h)由使用方先 include(如
|
||||
* kernel/panic_font.inc),并定义 FBCON_HAVE_FONT 后再包含本头文件。 */
|
||||
#ifdef FBCON_HAVE_FONT
|
||||
|
||||
static inline void fbc_char(fbc_ctx *c, char ch, i64 x, i64 y, u32 fg) {
|
||||
u32 idx = (u32)ch - 32;
|
||||
if (idx > 94) idx = 0;
|
||||
const u8 *g = g_ascii[idx];
|
||||
for (i64 r = 0; r < g_ascii_h; r++)
|
||||
for (i64 cc = 0; cc < g_ascii_w; cc++) {
|
||||
u8 a = g[r * g_ascii_w + cc];
|
||||
if (a < 24) continue;
|
||||
fbc_pixel(c, x + cc, y + r, fg);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void fbc_string(fbc_ctx *c, const char *s, i64 x, i64 y, u32 fg) {
|
||||
i64 cx = x;
|
||||
while (*s) {
|
||||
fbc_char(c, *s, cx, y, fg);
|
||||
cx += g_ascii_w;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void fbc_string_center(fbc_ctx *c, const char *s, i64 y, u32 fg) {
|
||||
i64 w = 0;
|
||||
for (const char *q = s; *q; q++) w += g_ascii_w;
|
||||
fbc_string(c, s, ((i64)c->w - w) / 2, y, fg);
|
||||
}
|
||||
|
||||
#endif /* FBCON_HAVE_FONT */
|
||||
|
||||
#endif /* UTSM_FBCON_H */
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate panic_logo_data.inc from ohMyLogo.png (root).
|
||||
|
||||
- Downscale logo to 384px wide (keep aspect), RGBA8888
|
||||
- Sample the 4 corners (averaged) as the panic-screen background color
|
||||
Usage: python gen_panic_logo.py <ohMyLogo.png> <panic_logo_data.inc>
|
||||
"""
|
||||
import sys
|
||||
from PIL import Image
|
||||
|
||||
SRC = r"d:/Code/DEAICUP/Deshab/ohMyLogo.png"
|
||||
DST = r"d:/Code/DEAICUP/Deshab/CODE/UTSM/kernel/panic_logo_data.inc"
|
||||
TARGET_W = 384
|
||||
|
||||
|
||||
def main() -> None:
|
||||
src = sys.argv[1] if len(sys.argv) > 1 else SRC
|
||||
dst = sys.argv[2] if len(sys.argv) > 2 else DST
|
||||
im = Image.open(src).convert("RGBA")
|
||||
w0, h0 = im.size
|
||||
scale = TARGET_W / w0
|
||||
w, h = TARGET_W, max(1, round(h0 * scale))
|
||||
im = im.resize((w, h), Image.LANCZOS)
|
||||
px = im.load()
|
||||
|
||||
# background color: average of 4 corner pixels (5x5 patches)
|
||||
rs = gs = bs = n = 0
|
||||
for cx, cy in ((2, 2), (w - 3, 2), (2, h - 3), (w - 3, h - 3)):
|
||||
for dy in range(-2, 3):
|
||||
for dx in range(-2, 3):
|
||||
r, g, b, _ = px[cx + dx, cy + dy]
|
||||
rs += r; gs += g; bs += b; n += 1
|
||||
r, g, b = rs // n, gs // n, bs // n
|
||||
bg = 0xFF000000 | (r << 16) | (g << 8) | b
|
||||
|
||||
lines = []
|
||||
lines.append("/* Auto-generated from ohMyLogo.png — panic screen logo (RGBA8888) */")
|
||||
lines.append("/* DO NOT EDIT. Regenerate via: python gen_panic_logo.py */")
|
||||
lines.append("")
|
||||
lines.append(f"static const int g_panic_logo_w = {w};")
|
||||
lines.append(f"static const int g_panic_logo_h = {h};")
|
||||
lines.append(f"/* panic 界面背景色 = 图片四角平均色 RGB({r},{g},{b}) */")
|
||||
lines.append(f"static const unsigned int g_panic_logo_bg = 0x{bg:08X}u;")
|
||||
lines.append("static const unsigned char g_panic_logo_rgba[] = {")
|
||||
for y in range(h):
|
||||
row = []
|
||||
base = y * w
|
||||
for x in range(w):
|
||||
r, g, b, a = px[x, y]
|
||||
row.append(f"0x{r:02X},0x{g:02X},0x{b:02X},0x{a:02X}")
|
||||
lines.append(" " + ",".join(row) + ",")
|
||||
lines.append("};")
|
||||
with open(dst, "w", encoding="utf-8") as f:
|
||||
f.write("\n".join(lines) + "\n")
|
||||
print(f"[gen_panic_logo] {w}x{h} bg=0x{bg:08X} -> {dst}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
+31
-162
@@ -2,164 +2,32 @@
|
||||
#include <utsm/types.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/drr.h>
|
||||
#include "../arch/x86_64/limine.h"
|
||||
|
||||
/* ===================================================================
|
||||
* F1: 莲花崩溃屏(panic_full)
|
||||
*
|
||||
* "崩了也得崩出莲花。"
|
||||
* 帧缓冲直绘:淡金莲花 + panic_symbol + 消息 + 寄存器简表,
|
||||
* 帧缓冲直绘(fbcon 抽象,F2):DEAICUP 莲花 Logo(ohMyLogo.png
|
||||
* 内嵌)+ panic_symbol + 消息 + 寄存器简表,背景色与图片背景一致,
|
||||
* DRR crash_buf 归档后 halt。不依赖驱动/堆/中断。
|
||||
* =================================================================== */
|
||||
|
||||
void arch_halt_forever(void);
|
||||
|
||||
extern volatile struct limine_framebuffer_request g_fb_request;
|
||||
|
||||
/* 11x18 Consolas 灰度字库(同 firstInit/ascii_bitmaps.c,自动生成) */
|
||||
/* 11x18 Consolas 灰度字库(同 firstInit/ascii_bitmaps.c,自动生成)。
|
||||
* 先包含字库再定义 FBCON_HAVE_FONT 引出 fbcon 文本接口。 */
|
||||
#include "panic_font.inc"
|
||||
#define FBCON_HAVE_FONT 1
|
||||
|
||||
/* ---- 最小绘制原语(32bpp XRGB,带边界检查) ---- */
|
||||
#include <utsm/fbcon.h>
|
||||
|
||||
typedef struct {
|
||||
u32 *fb;
|
||||
u64 w, h, pitch;
|
||||
} pfb;
|
||||
|
||||
static int pfb_init(pfb *p) {
|
||||
if (!g_fb_request.response || g_fb_request.response->framebuffer_count == 0)
|
||||
return -1;
|
||||
struct limine_framebuffer *fb = g_fb_request.response->framebuffers[0];
|
||||
if (fb->bpp < 32 || !fb->address) return -1;
|
||||
p->fb = (u32 *)fb->address;
|
||||
p->w = fb->width;
|
||||
p->h = fb->height;
|
||||
p->pitch = fb->pitch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ppx(pfb *p, i64 x, i64 y, u32 c) {
|
||||
if (x < 0 || (u64)x >= p->w || y < 0 || (u64)y >= p->h) return;
|
||||
*(u32 *)((u8 *)p->fb + (u64)y * p->pitch + (u64)x * 4) = c;
|
||||
}
|
||||
|
||||
static void prect(pfb *p, i64 x, i64 y, i64 w, i64 h, u32 c) {
|
||||
for (i64 r = 0; r < h; r++)
|
||||
for (i64 c2 = 0; c2 < w; c2++)
|
||||
ppx(p, x + c2, y + r, c);
|
||||
}
|
||||
|
||||
static u32 pgrad(u32 top, u32 bot, i64 y, i64 h) {
|
||||
if (h <= 1) return top;
|
||||
if (y < 0) y = 0;
|
||||
if (y >= h) y = h - 1;
|
||||
u32 a = (u32)(((u64)y * 255ULL) / (u64)(h - 1));
|
||||
u32 na = 256 - a;
|
||||
u32 r = (((top >> 16) & 0xFF) * na + ((bot >> 16) & 0xFF) * a) >> 8;
|
||||
u32 g = (((top >> 8) & 0xFF) * na + ((bot >> 8) & 0xFF) * a) >> 8;
|
||||
u32 b = ((top & 0xFF) * na + (bot & 0xFF) * a) >> 8;
|
||||
return 0xFF000000u | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
/* 11x18 灰度字符(g_ascii: ASCII 32..126) */
|
||||
static void pchar(pfb *p, char ch, i64 x, i64 y, u32 fg) {
|
||||
u32 idx = (u32)ch - 32;
|
||||
if (idx > 94) idx = 0;
|
||||
const u8 *g = g_ascii[idx];
|
||||
for (i64 r = 0; r < g_ascii_h; r++) {
|
||||
for (i64 c = 0; c < g_ascii_w; c++) {
|
||||
u8 a = g[r * g_ascii_w + c];
|
||||
if (a < 24) continue;
|
||||
ppx(p, x + c, y + r, fg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pstr(pfb *p, const char *s, i64 x, i64 y, u32 fg) {
|
||||
i64 cx = x;
|
||||
while (*s) {
|
||||
pchar(p, *s, cx, y, fg);
|
||||
cx += g_ascii_w;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
static void pstr_center(pfb *p, const char *s, i64 y, u32 fg) {
|
||||
i64 w = 0;
|
||||
for (const char *q = s; *q; q++) w += g_ascii_w;
|
||||
pstr(p, s, ((i64)p->w - w) / 2, y, fg);
|
||||
}
|
||||
|
||||
/* ---- 莲花:8 瓣椭圆花瓣 + 金芯(淡金 on 暗底) ---- */
|
||||
|
||||
/* sin 表:33 项覆盖 [0, π/2],步长 (π/2)/32,值×1000。
|
||||
* cos(i) = SIN33[32-i]。视觉用途精度足够。 */
|
||||
static const i16 SIN33[33] = {
|
||||
0, 49, 98, 146, 195, 242, 290, 336,
|
||||
383, 428, 471, 513, 556, 597, 635, 671,
|
||||
707, 740, 773, 803, 831, 857, 882, 905,
|
||||
924, 941, 958, 972, 984, 993, 999, 1000, 1000
|
||||
};
|
||||
|
||||
/* a: q12 角度(0..3071,3072=整圈),输出 sin/cos ×1000 */
|
||||
static void sincos_q12(i64 a, i64 *so, i64 *co) {
|
||||
a %= 3072;
|
||||
if (a < 0) a += 3072;
|
||||
i32 qs = (i32)(a / 768);
|
||||
i32 idx = (i32)((a % 768) / 24);
|
||||
i64 s = 0, c = 0;
|
||||
switch (qs) {
|
||||
case 0: s = SIN33[idx]; c = SIN33[32 - idx]; break;
|
||||
case 1: s = SIN33[32 - idx]; c = -SIN33[idx]; break;
|
||||
case 2: s = -SIN33[idx]; c = -SIN33[32 - idx]; break;
|
||||
default: s = -SIN33[32 - idx]; c = SIN33[idx]; break;
|
||||
}
|
||||
*so = s;
|
||||
*co = c;
|
||||
}
|
||||
|
||||
static void petal(pfb *p, i64 cx, i64 cy, i64 angle_q12, i64 len, i64 wid, u32 color) {
|
||||
/* 花瓣局部坐标系:u 沿长轴(尖端收窄),v 沿短轴;旋转到屏幕坐标 */
|
||||
i64 s, c;
|
||||
sincos_q12(angle_q12, &s, &c);
|
||||
i64 len1000 = len ? len * 1000 : 1;
|
||||
i64 wid1000 = wid ? wid * 1000 : 1;
|
||||
for (i64 u = -len; u <= len; u++) {
|
||||
for (i64 v = -wid; v <= wid; v++) {
|
||||
i64 eu = (u * 1000 * 1000) / len1000; /* -1000..1000 */
|
||||
i64 ev = (v * 1000 * 1000) / wid1000;
|
||||
if (eu > 200) ev = (ev * (1000 - (eu - 200) * 2)) / 1000; /* 收尖 */
|
||||
if (eu * eu + ev * ev > 1000 * 1000) continue;
|
||||
i64 dx = (u * c - v * s) / 1000;
|
||||
i64 dy = (u * s + v * c) / 1000;
|
||||
ppx(p, cx + dx, cy + dy, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void lotus(pfb *p, i64 cx, i64 cy) {
|
||||
const u32 petal_c = 0xFFD8B4E8; /* 淡粉金 */
|
||||
const u32 petal_c2 = 0xFFC498D8; /* 深一档 */
|
||||
const u32 core_c = 0xFFF0D080; /* 金芯 */
|
||||
for (i64 k = 0; k < 8; k++) {
|
||||
i64 ang = k * 384; /* 3072/8 */
|
||||
petal(p, cx, cy, ang, 46, 15, (k & 1) ? petal_c : petal_c2);
|
||||
}
|
||||
/* 金芯圆 */
|
||||
for (i64 dy = -12; dy <= 12; dy++)
|
||||
for (i64 dx = -12; dx <= 12; dx++)
|
||||
if (dx * dx + dy * dy <= 144)
|
||||
ppx(p, cx + dx, cy + dy, core_c);
|
||||
/* 芯内小点 */
|
||||
for (i64 dy = -4; dy <= 4; dy++)
|
||||
for (i64 dx = -4; dx <= 4; dx++)
|
||||
if (dx * dx + dy * dy <= 16)
|
||||
ppx(p, cx + dx, cy + dy, 0xFF7050A0);
|
||||
}
|
||||
/* DEAICUP 莲花 Logo(ohMyLogo.png 缩放 384px,RGBA8888)+
|
||||
* 背景色(图片四角平均色)。生成:kernel/gen_panic_logo.py */
|
||||
#include "panic_logo_data.inc"
|
||||
|
||||
/* ---- hex 输出 ---- */
|
||||
|
||||
static void phex64(pfb *p, u64 v, i64 x, i64 y, u32 fg) {
|
||||
static void phex64(fbc_ctx *p, u64 v, i64 x, i64 y, u32 fg) {
|
||||
char buf[19];
|
||||
buf[0] = '0'; buf[1] = 'x';
|
||||
for (i32 i = 0; i < 16; i++) {
|
||||
@@ -167,11 +35,11 @@ static void phex64(pfb *p, u64 v, i64 x, i64 y, u32 fg) {
|
||||
buf[2 + i] = (char)(nib < 10 ? '0' + nib : 'A' + nib - 10);
|
||||
}
|
||||
buf[18] = 0;
|
||||
pstr(p, buf, x, y, fg);
|
||||
fbc_string(p, buf, x, y, fg);
|
||||
}
|
||||
|
||||
static void pregline(pfb *p, const char *name, u64 v, i64 x, i64 y, u32 fg) {
|
||||
pstr(p, name, x, y, fg);
|
||||
static void pregline(fbc_ctx *p, const char *name, u64 v, i64 x, i64 y, u32 fg) {
|
||||
fbc_string(p, name, x, y, fg);
|
||||
phex64(p, v, x + 5 * g_ascii_w, y, fg);
|
||||
}
|
||||
|
||||
@@ -202,30 +70,31 @@ void panic_full(const char *symbol, const char *msg, const panic_regs *regs) {
|
||||
}
|
||||
|
||||
/* 屏幕绘制放在归档之后:绘制循环中再出异常也不丢归档 */
|
||||
pfb P, *p = &P;
|
||||
if (pfb_init(p) == 0) {
|
||||
/* 暗夜渐变:深蓝 → 暗紫 */
|
||||
const u32 top = 0xFF101830, bot = 0xFF241430;
|
||||
for (u64 y = 0; y < p->h; y++) {
|
||||
u32 c = pgrad(top, bot, (i64)y, (i64)p->h);
|
||||
u32 *line = (u32 *)((u8 *)p->fb + y * p->pitch);
|
||||
for (u64 x = 0; x < p->w; x++) line[x] = c;
|
||||
}
|
||||
fbc_ctx P, *p = &P;
|
||||
if (fbc_init(p) == 0) {
|
||||
/* 背景色 = Logo 图片背景色(四角平均,gen_panic_logo.py 生成) */
|
||||
fbc_fill_bg(p, g_panic_logo_bg);
|
||||
|
||||
lotus(p, (i64)p->w / 2, (i64)p->h / 2 - 120);
|
||||
/* 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);
|
||||
|
||||
const u32 fg = 0xFFF0E8D8, dim = 0xFFB0A8C0, acc = 0xFFF0D080;
|
||||
pstr_center(p, "DESHAB PANIC", (i64)p->h / 2 + 10, acc);
|
||||
|
||||
i64 y = (i64)p->h / 2 + 60;
|
||||
if (symbol) pstr_center(p, symbol, y, fg), y += g_ascii_h + 8;
|
||||
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;
|
||||
pstr_center(p, line, y, fg), y += g_ascii_h + 8;
|
||||
fbc_string_center(p, line, y, fg);
|
||||
y += g_ascii_h + 8;
|
||||
}
|
||||
if (regs) {
|
||||
if (y + g_ascii_h * 6 < (i64)p->h) {
|
||||
@@ -233,11 +102,11 @@ void panic_full(const char *symbol, const char *msg, const panic_regs *regs) {
|
||||
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); y += g_ascii_h + 2;
|
||||
pregline(p, "CR2 ", regs->cr2, (i64)p->w / 2 - 14 * g_ascii_w / 2, y, dim);
|
||||
}
|
||||
}
|
||||
}
|
||||
pstr_center(p, archived == 0 ? "crash archived to DRR" : "DRR archive unavailable",
|
||||
fbc_string_center(p, archived == 0 ? "crash archived to DRR" : "DRR archive unavailable",
|
||||
(i64)p->h - g_ascii_h - 24, dim);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
kernel/panic.o: kernel\panic.c include\utsm\log.h include\utsm\types.h \
|
||||
include\utsm\panic.h include\utsm\drr.h include\utsm\config.h \
|
||||
kernel\..\arch\x86_64\limine.h kernel\panic_font.inc
|
||||
kernel\panic_font.inc include\utsm\fbcon.h \
|
||||
include\..\arch\x86_64\limine.h kernel\panic_logo_data.inc
|
||||
include\utsm\log.h:
|
||||
include\utsm\types.h:
|
||||
include\utsm\panic.h:
|
||||
include\utsm\drr.h:
|
||||
include\utsm\config.h:
|
||||
kernel\..\arch\x86_64\limine.h:
|
||||
kernel\panic_font.inc:
|
||||
include\utsm\fbcon.h:
|
||||
include\..\arch\x86_64\limine.h:
|
||||
kernel\panic_logo_data.inc:
|
||||
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
# Deshab Kernel Configuration — dev 变体(build/configs/dev/FUCK)
|
||||
# Deshab Kernel Configuration — dev 变体(build/configs/dev/FUCK)
|
||||
# build.ps1 -Variant dev 打包前注入 SYSTEM/system/deshab64/FUCK
|
||||
# 开发者模式:selftest 开、dev_mode 自动跑 shell.elf 测试、日志持久化、跳过向导直达桌面
|
||||
|
||||
@@ -89,3 +89,5 @@ lib_path=lib
|
||||
linux_lib_guest_path=/usr/lib/deshab
|
||||
linux_lib_sync=1
|
||||
pe_dll_search=1
|
||||
|
||||
|
||||
|
||||
@@ -735,6 +735,30 @@ if (Test-Path $LogoPng) {
|
||||
} else {
|
||||
Write-Host '[build] WARNING: Logo.png not found'
|
||||
}
|
||||
|
||||
# Generate panic_logo_data.inc from ohMyLogo.png (panic screen logo + bg color)
|
||||
$PanicLogoPng = Join-Path $Root 'ohMyLogo.png'
|
||||
$PanicLogoInc = Join-Path $UtsmDir 'kernel\panic_logo_data.inc'
|
||||
$PanicGenPy = Join-Path $UtsmDir 'kernel\gen_panic_logo.py'
|
||||
if (Test-Path $PanicLogoPng) {
|
||||
$Python = $null
|
||||
foreach ($p in @('C:\Users\林濬哲\AppData\Local\Programs\Python\Python312\python.exe',
|
||||
'C:\msys64\mingw64\bin\python.exe',
|
||||
'python', 'python3')) {
|
||||
try { $cmd = Get-Command $p -ErrorAction Stop; $Python = $cmd.Source; break } catch {}
|
||||
}
|
||||
if ($Python) {
|
||||
if (-not (Test-Path $PanicLogoInc) -or ((Get-Item $PanicLogoPng).LastWriteTime -gt (Get-Item $PanicLogoInc).LastWriteTime)) {
|
||||
Write-Host '[build] Generating panic_logo_data.inc from ohMyLogo.png...'
|
||||
& $Python $PanicGenPy $PanicLogoPng $PanicLogoInc
|
||||
if ($LASTEXITCODE -ne 0) { Write-Host '[build] WARNING: panic_logo_data.inc generation failed, using existing file' }
|
||||
}
|
||||
} else {
|
||||
Write-Host '[build] WARNING: Python not found, cannot regenerate panic_logo_data.inc'
|
||||
}
|
||||
} else {
|
||||
Write-Host '[build] WARNING: ohMyLogo.png not found (panic screen keeps embedded data)'
|
||||
}
|
||||
try {
|
||||
& $make -C "$DskDir" -f MAKEFILE "CC=$clang" "LD=$lld"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Deshab Kernel Configuration — dev 变体(build/configs/dev/FUCK)
|
||||
# Deshab Kernel Configuration — dev 变体(build/configs/dev/FUCK)
|
||||
# build.ps1 -Variant dev 打包前注入 SYSTEM/system/deshab64/FUCK
|
||||
# 开发者模式:selftest 开、dev_mode 自动跑 shell.elf 测试、日志持久化、跳过向导直达桌面
|
||||
|
||||
@@ -89,3 +89,5 @@ lib_path=lib
|
||||
linux_lib_guest_path=/usr/lib/deshab
|
||||
linux_lib_sync=1
|
||||
pe_dll_search=1
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
| 编号 | 功能 | 疯的意义 | 状态 | 验收标准 |
|
||||
|------|------|---------|------|---------|
|
||||
| F1 | 内核 panic 统一兜底 | 崩了也得崩出莲花 | ✅ | panic_symbol + 莲花崩溃屏 + 寄存器简表 + DRR 归档后 halt |
|
||||
| F2 | UEFI 帧缓冲控制台 | 疯要有画面 | 🔶 | console_fb 已可出字;统一控制台抽象(无 VGA 回退也出宋体)⬜ |
|
||||
| F2 | UEFI 帧缓冲控制台 | 疯要有画面 | 🔶 | fbcon.h 抽象已落(panic 路径使用);统一控制台后端 ⬜ |
|
||||
| F3 | 构建跨平台(Make/CMake) | 疯不应绑 Windows | ⬜ | 当前 build.ps1 + WSL mkfs;Linux/macOS make iso 待做 |
|
||||
| F4 | 状态机自检 boot_ok | 知道自己是几成疯 | ✅ | 启动分级自检(IDT/UTSM/DKM/调度器/DRR),输出 ✅/🔶 明细 |
|
||||
| F5 | 可跳过 FirstInit | 自由的第一步 | ✅ | FUCK `[dsk] skip_firstinit=1` 直达 desktop;build/configs 模板注入生效 |
|
||||
|
||||
+2
-1
@@ -15,8 +15,9 @@
|
||||
| LAPIC timer | ✅ | TSC 校准 + 周期模式,[sched] 配置 | M4 QEMU 日志 |
|
||||
| DMA 物理页分配器 | ✅ | bitmap,低 4G 钳位 | e1000 DMA 根治记录 |
|
||||
| 页表映射接口(map/unmap) | ⬜ | mmio 通用映射待做 | — |
|
||||
| panic 统一兜底(F1) | ✅ | 莲花崩溃屏 + panic_symbol + DRR 归档;CPU 异常/驱动 panic 统一入口 | `.build_tmp/qemu_serial_f1panic.log` |
|
||||
| panic 统一兜底(F1) | ✅ | DEAICUP 莲花崩溃屏(ohMyLogo.png 内嵌,背景=图片背景色)+ panic_symbol + DRR 归档;CPU 异常/驱动 panic 统一入口 | `.build_tmp/panic_screen.png` + qemu_serial_f1logo2.log |
|
||||
| boot 分级自检(F4) | ✅ | `[boot] selftest=0\|1\|2`,5 项全过 BOOT-OK | `.build_tmp/qemu_serial_f1f4f5.log` |
|
||||
| 帧缓冲控制台抽象 fbcon(F2) | 🔶 | `include/utsm/fbcon.h`:像素/混合/填充/RGBA 图像/文本(panic 路径已用);统一控制台后端 ⬜ | `CODE/UTSM/include/utsm/fbcon.h` |
|
||||
| 构建系统 | 🔶 | Windows build.ps1 + WSL mkfs;跨平台 ⬜ | build.ps1 |
|
||||
|
||||
## UTSM / UTRW
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
- [x] F1 内核 panic 统一兜底(莲花崩溃屏 + panic_symbol + DRR 归档)
|
||||
- [x] F4 boot_ok 分级启动自检(`[boot] selftest=0|1|2`)
|
||||
- [x] F5 可跳过 FirstInit(`[dsk] skip_firstinit` + build/configs 模板)
|
||||
- [ ] F2 统一帧缓冲控制台抽象(console_fb 雏形 🔶)
|
||||
- [x] F2 统一帧缓冲控制台抽象(fbcon.h:panic 路径已用;统一控制台后端待做)
|
||||
- [ ] F3 跨平台构建(Make/CMake)
|
||||
|
||||
## 🗝️ 二期:仪式(UTSM/UTRW)
|
||||
|
||||
Reference in New Issue
Block a user