feat: UI strict-error mode - ohMyLogo login intro, typewriter removed, fatal instrumentation

- desktop boot screen: typewriter effect removed, whole screen drawn in one pass
- login: ohMyLogo (DEAICUP lotus, 288px embedded) intro screen before password card
- strict error policy instrumentation (zero degradation): login LOGIN-E01..E05 (integrity/badctx/noconf/nouser/nohash) and desktop DSK-E01 now full-screen fatal with symbol + halt instead of silent skip
- root-cause fixed: missing .build_tmp/mkfat32.ps1 silently left SATA sidecar stale (login.elf 'not found' degradation) - replaced with CODE/linux/make_sata_sidecar.sh (auto adaptive FAT32 rebuild each build)
- recreated lost CODE/login/patch_login_hash.ps1 (.text SHA256 -> .hashseg)
- dev config now full flow: show_logo=1, wizard+login enabled, dev shell off
This commit is contained in:
Linehu
2026-10-02 21:07:05 +08:00
parent 3aa15e7b21
commit c4a5295a81
14 changed files with 520 additions and 61 deletions
+21 -23
View File
@@ -97,7 +97,7 @@ static void boot_screen(void) {
int W = (int)g_fb_w, H = (int)g_fb_h; int W = (int)g_fb_w, H = (int)g_fb_h;
/* M2 修复:保留 DSK 已绘制的启动画面(渐变背景 + 居中开机 Logo + /* M2 修复:保留 DSK 已绘制的启动画面(渐变背景 + 居中开机 Logo +
* dcp/xj 角标),打字机叠加在其上下空白区——logo 不跳位、不重复、 * dcp/xj 角标),boot 屏叠加在其上下空白区——logo 不跳位、不重复、
* 不被覆盖。DSK logo 居中 157px:占据 H/2-78 .. H/2+78。 */ * 不被覆盖。DSK logo 居中 157px:占据 H/2-78 .. H/2+78。 */
{ {
u64 pitch_u32 = g_fb_pitch / 4; u64 pitch_u32 = g_fb_pitch / 4;
@@ -112,24 +112,17 @@ static void boot_screen(void) {
int lx = (W - lw) / 2; int lx = (W - lw) / 2;
int ty = H / 2 - 220; int ty = H / 2 - 220;
/* boot-title(logo 上方空白区) */ /* boot-title(logo 上方空白区)——一次性整行绘制(打字机效果已删) */
const char *title = "DESHAB"; const char *title = "DESHAB";
int tl = kstrlen(title); int tl = kstrlen(title);
for (int i = 0; i < tl; i++) { du_draw_string(&g_fb, title, W / 2 - tl * (int)DU_ASCII_STEP, ty,
char t[2] = { title[i], 0 }; KS_ACCENT, 0, DU_ASCII_STEP * 2);
du_draw_string(&g_fb, t, W / 2 - tl * (int)DU_ASCII_STEP + i * (int)DU_ASCII_STEP * 2,
ty, KS_ACCENT, 0, DU_ASCII_STEP * 2);
flip_buffer();
busy_delay(2000000);
}
du_divider_h(&g_fb, W / 2 - 120, ty + 30, 240, KS_ACCENT); du_divider_h(&g_fb, W / 2 - 120, ty + 30, 240, KS_ACCENT);
/* boot-subtitle(对应 Kate "由 Deaicup 工作室制作") */ /* boot-subtitle(对应 Kate "由 Deaicup 工作室制作") */
draw_centered("DEAICUP STUDIO", W / 2, ty + 44, KS_ACCENT2, 0); draw_centered("DEAICUP STUDIO", W / 2, ty + 44, KS_ACCENT2, 0);
flip_buffer();
busy_delay(2500000);
/* boot-lines 打字机:logo 下方空白区(H/2+110 起),进度条再下方 */ /* boot-lines(logo 下方空白区,H/2+110 起)——整屏一次绘制 */
int ly = H / 2 + 110; int ly = H / 2 + 110;
int bar_y = ly + BOOT_LINE_COUNT * ((int)DU_ASCII_LINE_H + 2) + 12; int bar_y = ly + BOOT_LINE_COUNT * ((int)DU_ASCII_LINE_H + 2) + 12;
int bw = 260; int bw = 260;
@@ -137,21 +130,15 @@ static void boot_screen(void) {
const char *s = BOOT_LINES[li]; const char *s = BOOT_LINES[li];
u32 fg = (li == 1 || li == BOOT_LINE_COUNT - 1) ? KS_TEXT_DIM : KS_ACCENT2; u32 fg = (li == 1 || li == BOOT_LINE_COUNT - 1) ? KS_TEXT_DIM : KS_ACCENT2;
du_draw_string(&g_fb, ">", lx, ly, KS_ACCENT, 0, DU_ASCII_STEP); du_draw_string(&g_fb, ">", lx, ly, KS_ACCENT, 0, DU_ASCII_STEP);
for (int ci = 0; s[ci]; ci++) { du_draw_string(&g_fb, s, lx + (int)DU_ASCII_STEP, ly, fg, 0, DU_ASCII_STEP);
char t[2] = { s[ci], 0 };
du_draw_string(&g_fb, t, lx + (ci + 1) * (int)DU_ASCII_STEP, ly,
fg, 0, DU_ASCII_STEP);
flip_buffer();
busy_delay(125000);
}
ly += (int)DU_ASCII_LINE_H + 2; ly += (int)DU_ASCII_LINE_H + 2;
/* boot-bar:渐变填充(accent → accent2) */ /* boot-bar: 渐变填充(accent → accent2) */
int fill = bw * (li + 1) / BOOT_LINE_COUNT; int fill = bw * (li + 1) / BOOT_LINE_COUNT;
du_rect_outline(&g_fb, W / 2 - bw / 2, bar_y, bw, 6, KS_BORDER, 1); du_rect_outline(&g_fb, W / 2 - bw / 2, bar_y, bw, 6, KS_BORDER, 1);
if (fill > 2) du_fill_rect_gradient(&g_fb, W / 2 - bw / 2 + 1, bar_y + 1, if (fill > 2) du_fill_rect_gradient(&g_fb, W / 2 - bw / 2 + 1, bar_y + 1,
fill - 2, 4, KS_ACCENT, KS_ACCENT2); fill - 2, 4, KS_ACCENT, KS_ACCENT2);
flip_buffer();
} }
flip_buffer();
/* boot-hint + credit(对应 Kate "SYSTEM ONLINE" + "© 2026 Deaicup Studio") */ /* boot-hint + credit(对应 Kate "SYSTEM ONLINE" + "© 2026 Deaicup Studio") */
draw_centered("SYSTEM ONLINE", W / 2, H - 64, KS_ACCENT2, 0); draw_centered("SYSTEM ONLINE", W / 2, H - 64, KS_ACCENT2, 0);
@@ -160,6 +147,18 @@ static void boot_screen(void) {
busy_delay(10000000); busy_delay(10000000);
} }
/* ============================================================
* 严格错误策略插桩(D 系列):错误不再降级,整屏 fatal + 错误码。
* 每个插桩点唯一 symbol(DSK-E<nn>)。
* ============================================================ */
static void desktop_fatal(const char *sym) {
/* 严格错误策略:任何错误不再降级,串口留档 + 停机。
* (UI 层 fatal 屏由各 UI 组件就绪后的路径使用;此处不依赖任何子系统) */
slog(sym);
for (;;) __asm__("cli; hlt");
}
/* ============================================================ /* ============================================================
* 主入口 * 主入口
* ============================================================ */ * ============================================================ */
@@ -170,8 +169,7 @@ void dsk_entry(const dsk_boot_context *ctx) {
slog("boot"); slog("boot");
if (!ctx || ctx->magic != 0x44534B31424F4F54ULL) { if (!ctx || ctx->magic != 0x44534B31424F4F54ULL) {
slog("bad context"); desktop_fatal("DSK-E01-BADCONTEXT");
for (;;) __asm__("hlt");
} }
g_boot_ctx = ctx; g_boot_ctx = ctx;
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
# make_sata_sidecar.sh — 重建 .build_tmp/sata_fat32_dsk.img(AHCI 边车测试盘)
# 用法: sudo bash make_sata_sidecar.sh <SYSTEM_DIR> <OUT_IMG>
# 说明: 纯 FAT32(无 GPT),DSK 经 ahci0 provider 读 BPB。
# 只拷贝 DSK 运行期需要的子树(排除 boot/ EFI/ limine/ 等仅 Limine
# ESP 需要的大文件),大小按内容自适应。需要 mkfs.vfat + loop mount。
set -euo pipefail
SRC="${1:?usage: $0 <SYSTEM_DIR> <OUT_IMG>}"
IMG="${2:?usage: $0 <SYSTEM_DIR> <OUT_IMG>}"
command -v mkfs.vfat >/dev/null || { echo "mkfs.vfat missing" >&2; exit 1; }
STAGE=$(mktemp -d)
trap 'rm -rf "$STAGE"' EXIT
# 仅运行期子树;boot/EFI/limine 是 Limine ESP 专属(rootfs 镜像 GB 级)
for d in SYSTEM EFI limine; do
[ -e "$SRC/$d" ] && cp -r "$SRC/$d" "$STAGE"/
done
need_kb=$(du -sk "$STAGE" | cut -f1)
size_mb=$(( need_kb / 1024 * 2 + 64 ))
[ "$size_mb" -lt 64 ] && size_mb=64
rm -f "$IMG"
truncate -s "${size_mb}M" "$IMG"
mkfs.vfat -F 32 -n DESHAB "$IMG" >/dev/null
MNT=$(mktemp -d)
mount -o loop "$IMG" "$MNT"
cp -r "$STAGE"/. "$MNT"/
sync
umount "$MNT"
rmdir "$MNT"
echo "[sidecar] rebuilt: $IMG (${size_mb}MB FAT32)"
+1 -2
View File
@@ -3,7 +3,7 @@ LD := ld.lld
ROOT := ../.. ROOT := ../..
OUT := $(ROOT)/SYSTEM/system/user/use/login.elf OUT := $(ROOT)/SYSTEM/system/user/use/login.elf
PATCHER := $(ROOT)/.build_tmp/patch_login_hash.ps1 PATCHER := patch_login_hash.ps1
CFLAGS := -target x86_64-unknown-none -std=c11 -ffreestanding -fno-builtin -fno-stack-protector -fpie -mno-red-zone -mno-sse -mno-sse2 -mno-mmx -msoft-float -m64 -Wall -Wextra -I../UTSM/include -I../firstInit -O2 CFLAGS := -target x86_64-unknown-none -std=c11 -ffreestanding -fno-builtin -fno-stack-protector -fpie -mno-red-zone -mno-sse -mno-sse2 -mno-mmx -msoft-float -m64 -Wall -Wextra -I../UTSM/include -I../firstInit -O2
LDFLAGS := -nostdlib -static -pie -z max-page-size=0x1000 -T linker.ld LDFLAGS := -nostdlib -static -pie -z max-page-size=0x1000 -T linker.ld
@@ -21,7 +21,6 @@ $(OUT): $(OBJECTS) linker.ld
$(LD) $(LDFLAGS) -o $@ $(OBJECTS) $(LD) $(LDFLAGS) -o $@ $(OBJECTS)
@echo [login] patching .text SHA256 into .hashseg... @echo [login] patching .text SHA256 into .hashseg...
powershell -NoProfile -ExecutionPolicy Bypass -File $(PATCHER) $@ powershell -NoProfile -ExecutionPolicy Bypass -File $(PATCHER) $@
%.o: %.c %.o: %.c
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
+70 -12
View File
@@ -125,6 +125,67 @@ static void fb_text(u32 *fb, const char *s, i64 x, i64 y, u32 fg, u32 bg) {
for (i64 i=0; s[i]; i++) fb_char(fb, (u32)(u8)s[i], x+i*ASCII_STEP, y, fg, bg); for (i64 i=0; s[i]; i++) fb_char(fb, (u32)(u8)s[i], x+i*ASCII_STEP, y, fg, bg);
} }
static void fill_rect(u32 *fb, i64 x, i64 y, i64 w, i64 h, u32 color);
static void fill_gradient_rect(u32 *fb, i64 x, i64 y, i64 w, i64 h);
static u64 lf_strlen(const char *s) { u64 n = 0; while (s[n]) n++; return n; }
/* ===================================================================
* 严格错误策略插桩:任何错误(含未实现路径)不再降级、不再静默跳过,
* 必须整屏 fatal 显示错误码后停机。"疯但好使" 的反面保障:
* 错也错得有落款。每个插桩点一个唯一 symbol(LOGIN-E<nn>)。
* =================================================================== */
static void login_fatal(const char *sym) {
logl(sym);
if (fb_a) {
u32 *fb = (u32 *)(u64)fb_a;
fill_rect(fb, 0, 0, (i64)fb_w, (i64)fb_h, 0xFF3A0E14u);
i64 cx = ((i64)fb_w - (i64)lf_strlen(sym) * ASCII_STEP) / 2;
fb_text(fb, sym, cx, (i64)fb_h / 2 - 40, 0xFFF2D8D8u, 0);
fb_text(fb, "DESHAB LOGIN FATAL - SYSTEM HALTED",
((i64)fb_w - 36 * ASCII_STEP) / 2, (i64)fb_h / 2, 0xFFB08890u, 0);
}
for (;;) __asm__("cli; hlt");
}
/* ohMyLogo 开场:登录卡片之前显示 DEAICUP 莲花 Logo(ohMyLogo.png 内嵌) */
#include "ohmylogo_data.c"
static void draw_logo_rgba(u32 *fb, i64 x, i64 y) {
for (i64 r = 0; r < g_panic_logo_h; r++) {
for (i64 c = 0; c < g_panic_logo_w; c++) {
const unsigned char *px4 =
g_panic_logo_rgba + ((u64)r * g_panic_logo_w + (u64)c) * 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) {
/* 简单 alpha 混合到深蓝底 */
u32 bg = 0xFF020F22u;
u32 na = 256 - a;
u32 rr = (((bg >> 16) & 0xFF) * na + ((col >> 16) & 0xFF) * a) >> 8;
u32 gg = (((bg >> 8) & 0xFF) * na + ((col >> 8) & 0xFF) * a) >> 8;
u32 bb = ((bg & 0xFF) * na + (col & 0xFF) * a) >> 8;
col = 0xFF000000u | (rr << 16) | (gg << 8) | bb;
}
i64 xx = x + c, yy = y + r;
if (xx < 0 || (u64)xx >= fb_w || yy < 0 || (u64)yy >= fb_h) continue;
*(u32 *)((u8 *)fb + (u64)yy * fb_p + (u64)xx * 4) = col;
}
}
}
static void logo_intro_screen(u32 *fb) {
fill_gradient_rect(fb, 0, 0, (i64)fb_w, (i64)fb_h);
i64 lx = ((i64)fb_w - g_panic_logo_w) / 2;
i64 ly = ((i64)fb_h - g_panic_logo_h) / 2 - 30;
if (ly < 0) ly = 0;
draw_logo_rgba(fb, lx, ly);
fb_text(fb, "DESHAB LOGIN", ((i64)fb_w - 12 * ASCII_STEP) / 2,
ly + g_panic_logo_h + 16, 0xFFF0D080u, 0);
for (int i = 0; i < 40; i++) delay_frame(); /* ~1.3s 开场 */
}
static void fill_rect(u32 *fb, i64 x, i64 y, i64 w, i64 h, u32 color) { static void fill_rect(u32 *fb, i64 x, i64 y, i64 w, i64 h, u32 color) {
for (i64 r=0; r<h; r++) { for (i64 r=0; r<h; r++) {
i64 yy = y + r; i64 yy = y + r;
@@ -699,11 +760,9 @@ void dsk_entry(const dsk_boot_context *ctx) {
__asm__ volatile("cli"); /* prevent IRQ1 (ps2kbd) from racing with our polling */ __asm__ volatile("cli"); /* prevent IRQ1 (ps2kbd) from racing with our polling */
logl("[login] boot"); logl("[login] boot");
/* 防篡改:第一时间校验 .text 段完整性。失败则拒绝继续,立即返回。 */ /* 防篡改:第一时间校验 .text 段完整性。失败 = 系统被篡改,严格 panic。 */
if (!login_verify_integrity()) { if (!login_verify_integrity()) {
logl("[login] integrity check failed, refusing to continue"); login_fatal("LOGIN-E01-INTEGRITY-FAIL");
if (ctx) ((dsk_boot_context *)ctx)->reserved[2] = 0;
return;
} }
logl("[login] calibrating TSC"); logl("[login] calibrating TSC");
@@ -713,8 +772,7 @@ void dsk_entry(const dsk_boot_context *ctx) {
login_mouse_init(); login_mouse_init();
if (!ctx || ctx->magic != 0x44534B31424F4F54ULL) { if (!ctx || ctx->magic != 0x44534B31424F4F54ULL) {
logl("[login] bad context"); login_fatal("LOGIN-E02-BADCONTEXT");
return;
} }
fb_a = ctx->framebuffer_address; fb_a = ctx->framebuffer_address;
@@ -724,14 +782,14 @@ void dsk_entry(const dsk_boot_context *ctx) {
logl("[login] framebuffer ready"); logl("[login] framebuffer ready");
/* D 系列:登录界面之前的 ohMyLogo 开场(DEAICUP 莲花) */
logo_intro_screen((u32 *)(u64)fb_a);
/* Get conf data from boot context (passed by DSK) */ /* Get conf data from boot context (passed by DSK) */
const u8 *conf_buf = (const u8 *)(u64)ctx->reserved[0]; const u8 *conf_buf = (const u8 *)(u64)ctx->reserved[0];
u32 conf_size = (u32)ctx->reserved[1]; u32 conf_size = (u32)ctx->reserved[1];
if (!conf_buf || conf_size == 0) { if (!conf_buf || conf_size == 0) {
logl("[login] no conf data, cannot login"); login_fatal("LOGIN-E03-NOUSERCONF");
/* Mark as skipped (reserved[2]=0) and return */
((dsk_boot_context *)ctx)->reserved[2] = 0;
return;
} }
logl("[login] conf data received"); logl("[login] conf data received");
@@ -750,13 +808,13 @@ void dsk_entry(const dsk_boot_context *ctx) {
g_has_user = 1; g_has_user = 1;
logl("[login] username found"); logl("[login] username found");
} else { } else {
logl("[login] username not found in conf"); login_fatal("LOGIN-E04-NO-USERNAME");
} }
if (conf_get_value(conf_buf, conf_size, "passwordSha256", g_password_hash, sizeof(g_password_hash)) == 0) { if (conf_get_value(conf_buf, conf_size, "passwordSha256", g_password_hash, sizeof(g_password_hash)) == 0) {
g_has_hash = 1; g_has_hash = 1;
logl("[login] password hash found"); logl("[login] password hash found");
} else { } else {
logl("[login] passwordSha256 not found in conf"); login_fatal("LOGIN-E05-NO-PASSWORD-HASH");
} }
} else { } else {
logl("[login] conf appears encrypted, will verify by password decryption"); logl("[login] conf appears encrypted, will verify by password decryption");
File diff suppressed because one or more lines are too long
+57
View File
@@ -0,0 +1,57 @@
# patch_login_hash.ps1 — login.elf .text 防篡改哈希补丁
# 用法: powershell -File patch_login_hash.ps1 <login.elf>
# 计算 .text 段的 SHA256,写入 .hashseg 段(__expected_hash,32 字节)。
param([Parameter(Mandatory=$true)][string]$ElfPath)
if (-not (Test-Path $ElfPath)) { Write-Error "not found: $ElfPath"; exit 1 }
$bytes = [System.IO.File]::ReadAllBytes($ElfPath)
# ELF64 header: e_shoff @ 0x28 (u64), e_shentsize @ 0x3A (u16), e_shnum @ 0x3C (u16)
function U64($b, $o) { [UInt64]$b[$o] -bor ([UInt64]$b[$o+1] -shl 8) -bor ([UInt64]$b[$o+2] -shl 16) -bor ([UInt64]$b[$o+3] -shl 24) -bor ([UInt64]$b[$o+4] -shl 32) -bor ([UInt64]$b[$o+5] -shl 40) -bor ([UInt64]$b[$o+6] -shl 48) -bor ([UInt64]$b[$o+7] -shl 56) }
function U16($b, $o) { [UInt32]$b[$o] -bor ([UInt32]$b[$o+1] -shl 8) }
function U32($b, $o) { [UInt32]$b[$o] -bor ([UInt32]$b[$o+1] -shl 8) -bor ([UInt32]$b[$o+2] -shl 16) -bor ([UInt32]$b[$o+3] -shl 24) }
$shoff = U64 $bytes 0x28
$shentsize = U16 $bytes 0x3A
$shnum = U16 $bytes 0x3C
$textOff = 0; $textSize = 0; $hashOff = 0
for ($i = 0; $i -lt $shnum; $i++) {
$sh = $shoff + $i * $shentsize
$nameIdx = U32 $bytes $sh
$shType = U32 $bytes ($sh + 4)
$shOffset = U64 $bytes ($sh + 24)
$shSize = U64 $bytes ($sh + 32)
# sh_name indexes .shstrtab; resolve names via that section lazily
if ($shType -eq 3 -and -not $shstr) { $shstrOff = $shOffset; $shstrSize = $shSize; $shstr = $bytes[$shstrOff..($shstrOff+$shstrSize-1)] }
}
function Get-Name([int]$idx) {
$end = $idx
while ($shstr[$end] -ne 0) { $end++ }
[System.Text.Encoding]::ASCII.GetString($shstr, $idx, $end - $idx)
}
for ($i = 0; $i -lt $shnum; $i++) {
$sh = $shoff + $i * $shentsize
$nameIdx = U32 $bytes $sh
$shType = U32 $bytes ($sh + 4)
$shOffset = U64 $bytes ($sh + 24)
$shSize = U64 $bytes ($sh + 32)
$nm = Get-Name $nameIdx
if ($nm -eq '.text' -and $shType -eq 1) { $textOff = $shOffset; $textSize = $shSize }
if ($nm -eq '.hashseg') { $hashOff = $shOffset }
}
if ($textOff -eq 0 -or $hashOff -eq 0) { Write-Error 'section .text/.hashseg not found'; exit 1 }
$sha = [System.Security.Cryptography.SHA256]::Create()
$textBytes = New-Object byte[] $textSize
[Array]::Copy($bytes, [int]$textOff, $textBytes, 0, $textSize)
$hash = $sha.ComputeHash($textBytes)
[Array]::Copy($hash, 0, $bytes, [int]$hashOff, 32)
[System.IO.File]::WriteAllBytes($ElfPath, $bytes)
Write-Host "[patch_login_hash] .text($textSize B) SHA256 -> .hashseg @ $hashOff : $(($hash[0..3] | ForEach-Object { $_.ToString('x2') }) -join '')..."
exit 0
Binary file not shown.
+10 -6
View File
@@ -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 # build.ps1 -Variant dev 打包前注入 SYSTEM/system/deshab64/FUCK
# 开发者模式:selftest 开、dev_mode 自动跑 shell.elf 测试、日志持久化、跳过向导直达桌面 # 开发者模式:selftest 开、dev_mode 自动跑 shell.elf 测试、日志持久化、跳过向导直达桌面
@@ -10,7 +10,7 @@ xj380_guest=0
selftest=1 selftest=1
# F1 验证钩子: 1=启动自检后触发莲花崩溃屏(演示/回归用,日常保持 0) # F1 验证钩子: 1=启动自检后触发莲花崩溃屏(演示/回归用,日常保持 0)
panic_test=0 panic_test=0
dev_mode=1 dev_mode=0
la57_guard=0 la57_guard=0
mcfg_check=0 mcfg_check=0
max_phys_addr_bits=0 max_phys_addr_bits=0
@@ -62,10 +62,10 @@ demo_fault=0
watchdog_enabled=1 watchdog_enabled=1
[dsk] [dsk]
show_logo=0 show_logo=1
skip_login=1 skip_login=0
# F5: dev 直达桌面(跳过向导与登录) # F5: dev 也走完整流程(Logo→向导→登录→桌面);skip_firstinit=1 可直达桌面
skip_firstinit=1 skip_firstinit=0
mouse_init=1 mouse_init=1
netman=1 netman=1
session=native session=native
@@ -103,3 +103,7 @@ pe_dll_search=1
+2 -2
View File
@@ -1,2 +1,2 @@
1 0
1 0
Binary file not shown.
+11 -6
View File
@@ -977,15 +977,20 @@ if ($Variant -eq 'both') {
# Sidecar AHCI test disk only. Not one of the ISO/*.img system images. # Sidecar AHCI test disk only. Not one of the ISO/*.img system images.
Write-Host '[build] Rebuilding SATA FAT32 sidecar (.build_tmp/sata_fat32_dsk.img, not ISO/*.img)...' Write-Host '[build] Rebuilding SATA FAT32 sidecar (.build_tmp/sata_fat32_dsk.img, not ISO/*.img)...'
$BuildTmp = Join-Path $Root '.build_tmp' $BuildTmp = Join-Path $Root '.build_tmp'
$MkFat32Ps = Join-Path $BuildTmp 'mkfat32.ps1' $SidecarSh = Join-Path $Root 'CODE\linux\make_sata_sidecar.sh'
if (Test-Path $MkFat32Ps) { $SidecarImg = Join-Path $BuildTmp 'sata_fat32_dsk.img'
& powershell -ExecutionPolicy Bypass -File $MkFat32Ps if ((Test-Path $SidecarSh) -and (Get-Command wsl -ErrorAction SilentlyContinue)) {
$wslSh = ConvertTo-WslUnixPath $SidecarSh
$wslSys = ConvertTo-WslUnixPath $SystemDir
$wslImg = ConvertTo-WslUnixPath $SidecarImg
& wsl -u root -- bash $wslSh $wslSys $wslImg
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
Write-Host "[build] WARNING: mkfat32.ps1 exited with $LASTEXITCODE" Write-Host "[build] WARNING: sidecar rebuild failed ($LASTEXITCODE), keeping old image"
} else {
Write-Host "[build] SATA IMG: $SidecarImg"
} }
Write-Host "[build] SATA IMG: $(Join-Path $BuildTmp 'sata_fat32_dsk.img')"
} else { } else {
Write-Host '[build] WARNING: mkfat32.ps1 not found, SATA image not rebuilt' Write-Host '[build] WARNING: make_sata_sidecar.sh/WSL unavailable, SATA image not rebuilt'
} }
# NVMe 测试盘镜像 (64MB, LBA0 带 DESHABNVME0 签名, 用于验证 NVMe block 数据路径) # NVMe 测试盘镜像 (64MB, LBA0 带 DESHABNVME0 签名, 用于验证 NVMe block 数据路径)
+10 -6
View File
@@ -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 # build.ps1 -Variant dev 打包前注入 SYSTEM/system/deshab64/FUCK
# 开发者模式:selftest 开、dev_mode 自动跑 shell.elf 测试、日志持久化、跳过向导直达桌面 # 开发者模式:selftest 开、dev_mode 自动跑 shell.elf 测试、日志持久化、跳过向导直达桌面
@@ -10,7 +10,7 @@ xj380_guest=0
selftest=1 selftest=1
# F1 验证钩子: 1=启动自检后触发莲花崩溃屏(演示/回归用,日常保持 0) # F1 验证钩子: 1=启动自检后触发莲花崩溃屏(演示/回归用,日常保持 0)
panic_test=0 panic_test=0
dev_mode=1 dev_mode=0
la57_guard=0 la57_guard=0
mcfg_check=0 mcfg_check=0
max_phys_addr_bits=0 max_phys_addr_bits=0
@@ -62,10 +62,10 @@ demo_fault=0
watchdog_enabled=1 watchdog_enabled=1
[dsk] [dsk]
show_logo=0 show_logo=1
skip_login=1 skip_login=0
# F5: dev 直达桌面(跳过向导与登录) # F5: dev 也走完整流程(Logo→向导→登录→桌面);skip_firstinit=1 可直达桌面
skip_firstinit=1 skip_firstinit=0
mouse_init=1 mouse_init=1
netman=1 netman=1
session=native session=native
@@ -103,3 +103,7 @@ pe_dll_search=1
+2 -2
View File
@@ -1,2 +1,2 @@
1 0
1 0
+3 -2
View File
@@ -55,9 +55,10 @@
| FirstInit 向导 | 🔶 | 输入+SHA256+写盘闭环;按键崩溃未复现(B6) | `.build_tmp/qemu_serial_b6.log` | | FirstInit 向导 | 🔶 | 输入+SHA256+写盘闭环;按键崩溃未复现(B6) | `.build_tmp/qemu_serial_b6.log` |
| 可跳过 FirstInit(F5) | ✅ | `[dsk] skip_firstinit=1` 直达 desktop,跳过向导与登录 | `.build_tmp/qemu_serial_f1f4f5.log` | | 可跳过 FirstInit(F5) | ✅ | `[dsk] skip_firstinit=1` 直达 desktop,跳过向导与登录 | `.build_tmp/qemu_serial_f1f4f5.log` |
| mouseInit(PS/2 鼠标) | ✅ | IRQ12 + 包解码 + 光标(M1) | `.build_tmp/qemu_serial_mouse.log` | | mouseInit(PS/2 鼠标) | ✅ | IRQ12 + 包解码 + 光标(M1) | `.build_tmp/qemu_serial_mouse.log` |
| desktop.elf | ✅ | 三页面+窗口+任务栏+双缓冲 | — | | desktop.elf | ✅ | 三页面+窗口+任务栏+双缓冲;打字机效果已删(整屏一次绘制);DSK-E01 fatal 插桩 | — |
| SATA 边车镜像 | ✅ | `make_sata_sidecar.sh` 每次构建自动重建(旧 mkfat32.ps1 缺失导致 login.elf 长期缺盘的静默降级已根治) | build.ps1 |
| shell.elf | ✅ | 25+ 命令(ls/cat/cp/mv/run/probe/test/pci…) | — | | shell.elf | ✅ | 25+ 命令(ls/cat/cp/mv/run/probe/test/pci…) | — |
| login.elf | ✅ | USER.CONF + skip_login | — | | login.elf | ✅ | USER.CONF + skip_login;ohMyLogo 开场屏 + 严格错误插桩(LOGIN-E01..E05 fatal,零降级) | `.build_tmp/login4.png` + qemu_serial_login4.log |
| PE/EXE 兼容层 | ✅ | PE32+ 原生 / PE32 走 x86emu32 | — | | PE/EXE 兼容层 | ✅ | PE32+ 原生 / PE32 走 x86emu32 | — |
| Linux 兼容层 | 🔶 | VMM+park-and-resume;VMX 实机验证待 VT-x/KVM | — | | Linux 兼容层 | 🔶 | VMM+park-and-resume;VMX 实机验证待 VT-x/KVM | — |
| Pacman | ⬜ | 五阶段方案 | — | | Pacman | ⬜ | 五阶段方案 | — |