feat: Phase 1 网络端到端打通 + FirstInit/Login/DevMode 完善
- 用户态共享网络协议栈 CODE/tools/net_stack.h(eth/ARP/IPv4/ICMP/UDP-DNS/TCP static inline,轮询模型) - shell 内建 ping/curl/run 命令;ping.elf/curl.elf 对齐 net_stack.h 真实协议栈 - shell dev_mode 串口镜像(g_serial_mirror)便于自动化验证 - DSK 启动流程:firstInit.txt 双行格式(firstInit + dev_mode),dev_mode=1 触发 shell 自动回归测试 - FirstInit 完成→持久化 USER.CONF + 翻转 firstInit 0->1(保留 dev_mode) - firstInit=1 时 DSK 加载 login.elf 进行用户选择 + 密码校验后再进 desktop - 新增 CODE/login/ 登录应用、CODE/DKM/dkm_shared.h、Logo.png - ahci/e1000/virtio_net/fat32/console_fb 驱动更新;utsm serial/block/dsk_loader 调整 - build.ps1 打包 ping.elf/curl.elf 进 SATA FAT32 根目录 - 移除 CODE/tools/bash(与 shell.elf 重复)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
/* DKM Console Framebuffer Driver
|
||||
* Stage 1, optional, provides "console".
|
||||
* Light-blue background + centered circular loading animation (4-color arc ring).
|
||||
* Clears the framebuffer to a solid light-blue background so the screen is
|
||||
* clean before DSK takes over and draws the Logo. The former 4-color arc
|
||||
* loading ring has been removed — DSK now shows a static Logo instead.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -51,7 +53,7 @@ __attribute__((visibility("default"), used))
|
||||
const struct dkm_driver_desc driver_desc = {
|
||||
.magic=DKM_DRIVER_MAGIC, .abi_version=DKM_ABI_VERSION,
|
||||
.desc_size=sizeof(struct dkm_driver_desc),
|
||||
.name="console_fb", .version="0.2.0", .vendor="Deshab",
|
||||
.name="console_fb", .version="0.3.0", .vendor="Deshab",
|
||||
.driver_class=5, .stage=1, .flags=0, .priority=0,
|
||||
.depends=NULL, .depends_count=0,
|
||||
.provides=g_provides, .provides_count=1,
|
||||
@@ -61,18 +63,11 @@ const struct dkm_driver_desc driver_desc = {
|
||||
/* ---------------------------------------------------------------
|
||||
* Colors
|
||||
* --------------------------------------------------------------- */
|
||||
static const u32 BG = 0xFFC8E0F0; /* light blue background */
|
||||
static const u32 ARC[4] = { 0xFF4488CC, 0xFF2266AA, 0xFF66AAEE, 0xFF88CCFF };
|
||||
static const u32 BG = 0xFFC8E0F0; /* light blue background — cleared before DSK Logo */
|
||||
|
||||
/* ---------------------------------------------------------------
|
||||
* Drawing helpers – all integer arithmetic, no soft-float
|
||||
* --------------------------------------------------------------- */
|
||||
static u64 fb_w, fb_h, fb_p;
|
||||
|
||||
/* double-buffer sprite for ring area (128×128 = no flicker) */
|
||||
#define SPR_SIZE 128
|
||||
static u32 g_sprite[SPR_SIZE * SPR_SIZE];
|
||||
|
||||
static void fb_fill(u32 *fb, u64 pitch, u64 w, u64 h, u32 color) {
|
||||
for (u64 y = 0; y < h; y++) {
|
||||
u32 *line = (u32 *)((u8 *)fb + y * pitch);
|
||||
@@ -80,105 +75,6 @@ static void fb_fill(u32 *fb, u64 pitch, u64 w, u64 h, u32 color) {
|
||||
}
|
||||
}
|
||||
|
||||
/* alpha-blend c2 over c1, alpha 0-255 */
|
||||
static u32 blend(u32 c1, u32 c2, u32 a) {
|
||||
u32 na = 256 - a;
|
||||
u32 r = ((c1 & 0xFF) * na + (c2 & 0xFF) * a) >> 8;
|
||||
u32 g = (((c1 >> 8) & 0xFF) * na + ((c2 >> 8) & 0xFF) * a) >> 8;
|
||||
u32 b = (((c1 >> 16) & 0xFF) * na + ((c2 >> 16) & 0xFF) * a) >> 8;
|
||||
return 0xFF000000 | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
/* integer sqrt – returns floor(sqrt(v)) */
|
||||
static u64 isqrt(u64 v) {
|
||||
u64 x = v, y = (x + 1) >> 1;
|
||||
while (y < x) { x = y; y = (y + v / y) >> 1; }
|
||||
return x;
|
||||
}
|
||||
|
||||
/* approximate atan2 in degrees (0=right, CCW). dx,dy = pixel offset from center */
|
||||
static i64 approx_angle(i64 dx, i64 dy) {
|
||||
if (dx == 0) return dy < 0 ? 90 : 270;
|
||||
i64 ax = dx < 0 ? -dx : dx;
|
||||
i64 ay = dy < 0 ? -dy : dy;
|
||||
i64 a;
|
||||
if (ax > ay) {
|
||||
a = ay * 45 / ax;
|
||||
} else {
|
||||
a = 90 - ax * 45 / (ay ? ay : 1);
|
||||
}
|
||||
/* quadrant correction */
|
||||
if (dx >= 0 && dy <= 0) return a; /* Q1 */
|
||||
else if (dx < 0 && dy <= 0) return 180 - a; /* Q2 */
|
||||
else if (dx < 0 && dy > 0) return 180 + a; /* Q3 */
|
||||
else return 360 - a; /* Q4 */
|
||||
}
|
||||
|
||||
/* draw one arc segment: rounded caps (6° head/tail), bright mid, comet-tail fade */
|
||||
static void arc_segment(u32 *fb, i64 cx, i64 cy, i64 r, i64 start, i64 sweep, u32 color, i64 thk) {
|
||||
i64 ro = r + thk, ri = r - thk;
|
||||
i64 ri2 = ri * ri, ro2 = (ro + 1) * (ro + 1);
|
||||
i64 rnd = 6; /* rounding zone at each end, in degrees */
|
||||
|
||||
for (i64 dy = -ro - 1; dy <= ro + 1; dy++) {
|
||||
i64 y = cy + dy;
|
||||
if ((u64)y >= fb_h) continue;
|
||||
u32 *line = (u32 *)((u8 *)fb + (u64)y * fb_p);
|
||||
for (i64 dx = -ro - 1; dx <= ro + 1; dx++) {
|
||||
i64 x = cx + dx;
|
||||
if ((u64)x >= fb_w) continue;
|
||||
i64 d2 = dx * dx + dy * dy;
|
||||
if (d2 < ri2 - 2 || d2 > ro2 + 2) continue;
|
||||
|
||||
i64 ang = approx_angle(dx, dy);
|
||||
i64 a = ang - start;
|
||||
if (a < 0) a += 360;
|
||||
if ((u64)a > (u64)sweep) continue;
|
||||
|
||||
/* rounded-cap fade: 0→255 over rnd°, then 255→0 over last rnd° */
|
||||
u32 fade;
|
||||
if ((u64)a < (u64)rnd) {
|
||||
fade = (u32)(a * 255 / rnd);
|
||||
} else if ((u64)a > (u64)(sweep - rnd)) {
|
||||
fade = (u32)((sweep - a) * 255 / rnd);
|
||||
} else {
|
||||
fade = 255;
|
||||
}
|
||||
|
||||
i64 dist = (i64)isqrt((u64)d2);
|
||||
u32 effective = blend(BG, color, fade);
|
||||
if (dist >= ri && dist <= ro) {
|
||||
line[(u64)x] = effective;
|
||||
} else if (dist >= ri - 2 && dist < ri) {
|
||||
line[(u64)x] = blend(BG, effective, (u32)((dist - (ri - 2)) * 85));
|
||||
} else if (dist > ro && dist <= ro + 2) {
|
||||
line[(u64)x] = blend(effective, BG, (u32)((dist - ro) * 85));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* filled disc with anti-aliased edge */
|
||||
static void fill_disc(u32 *fb, i64 cx, i64 cy, i64 r, u32 color) {
|
||||
i64 r2 = r * r, o2 = (r + 1) * (r + 1);
|
||||
for (i64 dy = -r - 2; dy <= r + 2; dy++) {
|
||||
i64 y = cy + dy;
|
||||
if ((u64)y >= fb_h) continue;
|
||||
u32 *line = (u32 *)((u8 *)fb + (u64)y * fb_p);
|
||||
for (i64 dx = -r - 2; dx <= r + 2; dx++) {
|
||||
i64 x = cx + dx;
|
||||
if ((u64)x >= fb_w) continue;
|
||||
i64 d2 = dx * dx + dy * dy;
|
||||
if (d2 <= r2) {
|
||||
line[(u64)x] = color;
|
||||
} else if (d2 <= o2) {
|
||||
u32 a = (u32)((o2 - d2) * 255 / (o2 - r2));
|
||||
line[(u64)x] = blend(BG, color, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------
|
||||
* Driver entry
|
||||
* --------------------------------------------------------------- */
|
||||
@@ -192,61 +88,13 @@ int driver_init(const struct dkm_kernel_api *api,
|
||||
return 0;
|
||||
}
|
||||
|
||||
api->log->info("[console_fb] boot screen");
|
||||
api->log->info("[console_fb] clearing boot screen");
|
||||
|
||||
fb_w = api->fb_width; fb_h = api->fb_height; fb_p = api->fb_pitch;
|
||||
/* Solid background fill only — DSK draws the Logo next. Clearing here
|
||||
* avoids firmware/UEFI leftover garbage being visible during the
|
||||
* UTSM→DSK handoff. */
|
||||
u32 *fb = (u32 *)api->fb_address;
|
||||
i64 cx = (i64)fb_w / 2, cy = (i64)fb_h / 2, r = 48, thk = 4;
|
||||
|
||||
/* light-blue background */
|
||||
fb_fill(fb, fb_p, fb_w, fb_h, BG);
|
||||
|
||||
/* animation: 2000 frames × 2° clockwise × ~1ms, no flicker */
|
||||
i64 spr_p = SPR_SIZE * 4;
|
||||
i64 scx = SPR_SIZE / 2;
|
||||
i64 scy = SPR_SIZE / 2;
|
||||
i64 frame = 0, base = 0;
|
||||
i64 bx = cx - scx; /* screen position of sprite top-left */
|
||||
i64 by = cy - scy;
|
||||
|
||||
while (frame < 2000) {
|
||||
/* draw into sprite buffer — swap globals to sprite layout */
|
||||
u64 save_w = fb_w, save_h = fb_h, save_p = fb_p;
|
||||
fb_w = SPR_SIZE; fb_h = SPR_SIZE; fb_p = spr_p;
|
||||
|
||||
fb_fill(g_sprite, spr_p, SPR_SIZE, SPR_SIZE, BG);
|
||||
|
||||
arc_segment(g_sprite, scx, scy, r, base + 0, 82, ARC[0], thk);
|
||||
arc_segment(g_sprite, scx, scy, r, base + 90, 82, ARC[1], thk);
|
||||
arc_segment(g_sprite, scx, scy, r, base +180, 82, ARC[2], thk);
|
||||
arc_segment(g_sprite, scx, scy, r, base +270, 82, ARC[3], thk);
|
||||
|
||||
fill_disc(g_sprite, scx, scy, r - 8, blend(BG, 0xFFD0F0FF, 80));
|
||||
|
||||
/* restore screen globals for blit */
|
||||
fb_w = save_w; fb_h = save_h; fb_p = save_p;
|
||||
|
||||
/* blit sprite to screen */
|
||||
for (i64 sr = 0; sr < SPR_SIZE; sr++) {
|
||||
i64 sy = by + sr;
|
||||
if ((u64)sy >= fb_h) continue;
|
||||
u32 *dst = (u32 *)((u8 *)fb + (u64)sy * fb_p) + bx;
|
||||
u32 *src = &g_sprite[sr * SPR_SIZE];
|
||||
for (i64 sc = 0; sc < SPR_SIZE; sc++) {
|
||||
i64 sx = bx + sc;
|
||||
if ((u64)sx >= fb_w) continue;
|
||||
dst[sc] = src[sc];
|
||||
}
|
||||
}
|
||||
|
||||
for (volatile u32 d = 0; d < 72000; d++) {
|
||||
__asm__ volatile ("pause");
|
||||
}
|
||||
|
||||
base -= 2;
|
||||
if (base < 0) base += 360;
|
||||
frame++;
|
||||
}
|
||||
fb_fill(fb, api->fb_pitch, api->fb_width, api->fb_height, BG);
|
||||
|
||||
api->log->info("[console_fb] ready");
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user