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:
@@ -116,6 +116,8 @@ void attest_check(const void *cfg) {
|
||||
if (first_required_missing) {
|
||||
panic_full(first_required_missing->errcode,
|
||||
"required capability not ready at boot (attestation)", 0);
|
||||
log_warn("[ATTEST] fallback: booting with required capabilities missing");
|
||||
return;
|
||||
}
|
||||
|
||||
/* 全部缺失项均被 FUCK 显式豁免(设计内白名单),放行 */
|
||||
|
||||
@@ -131,6 +131,6 @@ void boot_panic_test(const ini_config *cfg) {
|
||||
extern int ini_get_bool(const ini_config *cfg, const char *section, const char *key, int defval);
|
||||
if (ini_get_bool(cfg, "boot", "panic_test", 0)) {
|
||||
log_warn("[boot] panic_test=1 -> triggering lotus panic screen");
|
||||
panic_full("UTSM-E42", "lotus panic selftest", 0);
|
||||
panic_halt("UTSM-E42", "lotus panic selftest", 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1026,6 +1026,7 @@ static void dsk_fill_boot_context(dsk_boot_context *ctx) {
|
||||
ctx->abi_version = DSK_BOOT_ABI_VERSION;
|
||||
ctx->size = sizeof(*ctx);
|
||||
ctx->flags = DSK_BOOT_FLAG_FROM_UTSM | DSK_BOOT_FLAG_DKM_READY | DSK_BOOT_FLAG_FAT32_PATH;
|
||||
if (panic_fallback_enabled()) ctx->flags |= DSK_BOOT_FLAG_PANIC_FALLBACK;
|
||||
|
||||
if (g_hhdm_request.response) {
|
||||
ctx->hhdm_offset = g_hhdm_request.response->offset;
|
||||
|
||||
+58
-26
@@ -25,6 +25,8 @@ extern volatile struct limine_module_request g_module_request;
|
||||
/* dkm/manifest.c: 带 FUCK [drivers] 过滤的 manifest 加载入口 */
|
||||
void dsm_load_by_manifest_ex(const ini_config *cfg);
|
||||
void dsm_load_named(const ini_config *cfg, const char *name);
|
||||
/* P0 顺序豁免版:唯一调用方就是下方 VMM 路径(pci+ahci 必须先于 apic) */
|
||||
void dsm_load_named_boot(const ini_config *cfg, const char *name);
|
||||
|
||||
/* dsk_loader.c: 按路径读取 FAT32 文件到 g_dsk_fat32_filedata 静态缓冲。
|
||||
* Phase 1 已支持 LFN 长文件名 + 子目录遍历。 */
|
||||
@@ -51,6 +53,17 @@ int g_sched_enabled_cfg = 1; /* FUCK [sched] enable
|
||||
|
||||
/* 将 FUCK [compat] 区的配置应用到兼容层全局变量。
|
||||
* 必须在 utsm_apply_config 之后调用。 */
|
||||
/* FUCK [panic] mode=strict|fallback(默认 strict)。其余取值按 strict 处理。 */
|
||||
static void utsm_apply_panic_config(const ini_config *cfg) {
|
||||
const char *mode = ini_get(cfg, "panic", "mode");
|
||||
const char *want = "fallback";
|
||||
int fallback = mode ? 1 : 0;
|
||||
for (int i = 0; fallback && (mode[i] || want[i]); i++) {
|
||||
if (mode[i] != want[i]) fallback = 0;
|
||||
}
|
||||
panic_set_fallback(fallback);
|
||||
}
|
||||
|
||||
static void utsm_apply_compat_config(const ini_config *cfg) {
|
||||
if (!cfg) return;
|
||||
const char *lib_path = ini_get(cfg, "compat", "lib_path");
|
||||
@@ -128,6 +141,12 @@ static void utsm_apply_config(const ini_config *cfg) {
|
||||
/* ---- 全局启动配置(从 FUCK 文件读取) ---- */
|
||||
static ini_config g_boot_cfg;
|
||||
static int g_boot_cfg_loaded = 0;
|
||||
|
||||
/* D6 万物互联:FUCK 启动配置只读访问(kern.config.get 总线服务后端,
|
||||
* bus.c 经前向声明调用;未加载时返回 NULL,消费方自行处理缺席)。 */
|
||||
const ini_config *utsm_boot_cfg_get(void) {
|
||||
return g_boot_cfg_loaded ? &g_boot_cfg : 0;
|
||||
}
|
||||
static int g_vmm_init_ok = 0; /* attest: vmm_vmx 能力打点 */
|
||||
|
||||
/* 从 Limine boot module 读取 FUCK 配置。
|
||||
@@ -263,9 +282,9 @@ void kernel_main(void) {
|
||||
if (cr4 & (1ULL << 12)) {
|
||||
log_error("[UTSM] LA57 is ACTIVE — this kernel requires 4-level paging");
|
||||
log_error("[UTSM] Refusing to boot. Disable LA57 in firmware settings.");
|
||||
panic_full("VMM-E11 LA57 ACTIVE REFUSE BOOT",
|
||||
/* 无备用路径:paging.c/mmio.c 的 4 级 walk 会写坏 5 级页表 */
|
||||
panic_halt("VMM-E11 LA57 ACTIVE REFUSE BOOT",
|
||||
"5-level paging active; kernel requires 4-level paging", 0);
|
||||
arch_halt_forever();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,6 +330,8 @@ void kernel_main(void) {
|
||||
* 颜色只走串口,BOOTLOG.TXT 保持纯文本) */
|
||||
log_color_enable(ini_get_bool(cfg, "debug", "color_log", 1));
|
||||
|
||||
utsm_apply_panic_config(cfg);
|
||||
|
||||
/* ---- 插桩: FUCK 配置加载完成 ---- */
|
||||
INSTR_PROBE(BOOT, (u64)g_boot_cfg_loaded, 0, 0, 0);
|
||||
|
||||
@@ -372,9 +393,8 @@ void kernel_main(void) {
|
||||
/* === 封缄内存极早期初始化(UTSM-E01..E04) ===
|
||||
* .sealed 区为空 / root key 缺失 → 此处极早期 panic,绝不带病前进。 */
|
||||
{
|
||||
extern void utsm_sealed_early_init(void);
|
||||
utsm_sealed_early_init();
|
||||
attest_report_ready("sealed_mem", "UTSM-E05");
|
||||
extern int utsm_sealed_early_init(void);
|
||||
attest_report("sealed_mem", "UTSM-E05", utsm_sealed_early_init() == 0);
|
||||
}
|
||||
|
||||
/* === SAS-R0-PCQ 调度器:bootstrap 任务绑定(Phase 7) ===
|
||||
@@ -395,8 +415,11 @@ void kernel_main(void) {
|
||||
* 调度器没有真正立起来,零降级 panic(SAS-E01) */
|
||||
panic_full("SAS-E01 SCHED BOOTSTRAP FAILED",
|
||||
"SAS-R0-PCQ scheduler bootstrap failed (was: non-fatal)", 0);
|
||||
/* fallback:不开 demo 窗口,sched 能力不报就绪 */
|
||||
g_sched_enabled_cfg = 0;
|
||||
} else {
|
||||
attest_report_ready("sched", "SAS-E02");
|
||||
}
|
||||
attest_report_ready("sched", "SAS-E02");
|
||||
}
|
||||
|
||||
INSTR_TS_DECL(ts_dkm);
|
||||
@@ -430,31 +453,38 @@ void kernel_main(void) {
|
||||
|
||||
/* Only pci+ahci before linux_launch. Loading apic/stage0 first
|
||||
* left the guest in an IDTR=0 VM-exit storm. Remaining DKM
|
||||
* still loads after the guest parks. */
|
||||
dsm_load_named(cfg, "pci");
|
||||
dsm_load_named(cfg, "ahci");
|
||||
* still loads after the guest parks.
|
||||
* P0 依赖图:此处用顺序豁免版(pci depends irq/apic 未加载),
|
||||
* 豁免登记见 docs/RE/万物互联与服务总线设计.md §6。 */
|
||||
dsm_load_named_boot(cfg, "pci");
|
||||
dsm_load_named_boot(cfg, "ahci");
|
||||
|
||||
/* === Linux guest — 可通过 FUCK [boot] linux_guest=0 跳过 ===
|
||||
* 严格错误策略:linux_guest=1 即"请求了 guest"——模块缺失、
|
||||
* 启动失败、IPC 失败一律 panic(VMM-E/LNX-E),零降级。 */
|
||||
int run_linux = ini_get_bool(cfg, "boot", "linux_guest", 1);
|
||||
if (run_linux) {
|
||||
if (linux_loader_init() != 0) {
|
||||
panic_full("VMM-E01 LINUX BZIMAGE MISSING",
|
||||
"linux_guest=1 but bzImage boot module not found", 0);
|
||||
}
|
||||
int linux_ready = run_linux;
|
||||
if (run_linux && linux_loader_init() != 0) {
|
||||
panic_full("VMM-E01 LINUX BZIMAGE MISSING",
|
||||
"linux_guest=1 but bzImage boot module not found", 0);
|
||||
linux_ready = 0; /* fallback:跳过 Linux guest */
|
||||
}
|
||||
if (linux_ready) {
|
||||
INSTR_TS_DECL(ts_linux);
|
||||
INSTR_TS_BEGIN(ts_linux);
|
||||
log_info("[UTSM] Linux loader init ok");
|
||||
|
||||
int lin_st = -1;
|
||||
int launched = 0;
|
||||
if (ipc_shm_init() == 0) {
|
||||
log_info("[UTSM] IPC shm init ok");
|
||||
lin_st = linux_launch();
|
||||
launched = 1;
|
||||
} else {
|
||||
panic_full("LNX-E03 IPC SHM INIT FAILED",
|
||||
"IPC shared memory init failed (was: non-fatal)", 0);
|
||||
log_warn("[UTSM] fallback: Linux guest launch skipped (no IPC)");
|
||||
}
|
||||
|
||||
int lin_st = linux_launch();
|
||||
INSTR_TS_END(ts_linux, "linux_launch");
|
||||
if (lin_st == 0) {
|
||||
log_info("[UTSM] Linux guest parked (daemon ready)");
|
||||
@@ -480,14 +510,14 @@ void kernel_main(void) {
|
||||
"vscode tarball install into guest failed", 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (launched) {
|
||||
/* 严格错误策略插桩:guest 启动失败零降级(VMM-E02) */
|
||||
log_error("[UTSM] Linux launch failed");
|
||||
log_hex64("[UTSM] Linux st=", (u64)(i64)lin_st);
|
||||
panic_full("VMM-E02 LINUX LAUNCH FAILED",
|
||||
"linux_guest=1 requested but VMX launch failed", 0);
|
||||
}
|
||||
} else {
|
||||
} else if (!run_linux) {
|
||||
log_warn("[UTSM] Linux guest disabled by FUCK (linux_guest=0)");
|
||||
}
|
||||
} else {
|
||||
@@ -503,11 +533,11 @@ void kernel_main(void) {
|
||||
* 严格错误策略:xj380_guest=1 即"请求了 guest"——模块缺失或
|
||||
* 启动失败一律 panic(VMM-E03/E04),零降级。 */
|
||||
int run_xj380 = ini_get_bool(cfg, "boot", "xj380_guest", 1);
|
||||
if (run_xj380) {
|
||||
if (xj380_loader_init() != 0) {
|
||||
panic_full("VMM-E03 XJ380 KERNEL.KRL MISSING",
|
||||
"xj380_guest=1 but kernel.krl boot module not found", 0);
|
||||
}
|
||||
if (run_xj380 && xj380_loader_init() != 0) {
|
||||
panic_full("VMM-E03 XJ380 KERNEL.KRL MISSING",
|
||||
"xj380_guest=1 but kernel.krl boot module not found", 0);
|
||||
log_warn("[UTSM] fallback: XJ380 guest skipped");
|
||||
} else if (run_xj380) {
|
||||
INSTR_TS_DECL(ts_xj380);
|
||||
INSTR_TS_BEGIN(ts_xj380);
|
||||
log_info("[UTSM] XJ380 loader init ok");
|
||||
@@ -554,7 +584,9 @@ void kernel_main(void) {
|
||||
attest_report("pkg", "PKG-E10", 0);
|
||||
attest_report("brand_anim", "BRAND-E10", 0);
|
||||
attest_report("dkm_hot_unload", "DKM-E60", 0);
|
||||
attest_report("dkm_api_export", "DKM-E61", 0);
|
||||
/* D6 万物互联:dkm_bus 落地,按名服务导出能力翻绿
|
||||
* (kapi 只读表 + bus 双向注册-消费)。 */
|
||||
attest_report("dkm_api_export", "DKM-E61", 1);
|
||||
attest_report("nvme_rw", "NVME-E30", 0);
|
||||
attest_report("virtio_net", "VNET-E30", 0);
|
||||
}
|
||||
@@ -578,7 +610,6 @@ void kernel_main(void) {
|
||||
log_error("[UTSM] SELFTEST FAIL");
|
||||
panic_full("VMM-E14 SELFTEST FAIL",
|
||||
"utsm_selftest_run returned non-zero", 0);
|
||||
arch_halt_forever();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -620,7 +651,8 @@ void kernel_main(void) {
|
||||
|
||||
if (dsk_load_and_jump() != 0) {
|
||||
log_error("[UTSM] DSK jump failed");
|
||||
panic_full("VMM-E15 DSK JUMP FAILED",
|
||||
/* 启动链终点,无可继续的路径:两种模式都上莲花屏 */
|
||||
panic_halt("VMM-E15 DSK JUMP FAILED",
|
||||
"dsk_load_and_jump returned non-zero", 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,18 +106,22 @@ static int net_connect_impl(u32 index, const char *ssid, const char *password) {
|
||||
if (index >= g_net_device_count) return -2;
|
||||
const dkm_net_device_desc *dev = &g_net_devices[index];
|
||||
/* 严格错误策略:无线设备未提供关联回调 = 驱动后端未实现,零降级 panic */
|
||||
if (!dev->connect)
|
||||
if (!dev->connect) {
|
||||
panic_full("NET-E20 WLAN CONNECT NOT SUPPORTED",
|
||||
"wireless netdev has no connect backend (native chip driver pending)", 0);
|
||||
return -3;
|
||||
}
|
||||
return dev->connect(dev->ctx, ssid, password);
|
||||
}
|
||||
|
||||
static int net_disconnect_impl(u32 index) {
|
||||
if (index >= g_net_device_count) return -2;
|
||||
const dkm_net_device_desc *dev = &g_net_devices[index];
|
||||
if (!dev->disconnect)
|
||||
if (!dev->disconnect) {
|
||||
panic_full("NET-E21 WLAN DISCONNECT NOT SUPPORTED",
|
||||
"wireless netdev has no disconnect backend (native chip driver pending)", 0);
|
||||
return -3;
|
||||
}
|
||||
return dev->disconnect(dev->ctx);
|
||||
}
|
||||
|
||||
|
||||
+97
-30
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user