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:
xyou
2026-07-26 21:07:36 +08:00
parent 48dcb5568e
commit efa626ed17
83 changed files with 4993 additions and 1785 deletions
+39 -3
View File
@@ -5,20 +5,56 @@ u8 inb(u16 port);
#define COM1 0x3F8
/* ---- TSC-based timing (实机要求: 用 CPU 频率计算, 不用循环) ---- */
static u64 g_tsc_per_ms = 0;
static inline u64 rdtsc_ser(void) {
u32 lo, hi;
__asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
return ((u64)hi << 32) | lo;
}
/* 用 PIT (8254, 1.193182 MHz) 校准 TSC 频率 */
static void tsc_calibrate_ser(void) {
outb(0x43, 0x30); /* ch0, lo+hi, mode 0, binary */
outb(0x40, 0x7c); /* 11932 low = ~10ms */
outb(0x40, 0x2e); /* 11932 high */
u64 tsc_start = rdtsc_ser();
u16 prev = 0; u64 loops = 0;
for (;;) {
outb(0x43, 0x00);
u16 cur = (u16)inb(0x40) | ((u16)inb(0x40) << 8);
if (cur > prev && loops > 10) break;
prev = cur; loops++;
}
u64 tsc_end = rdtsc_ser();
g_tsc_per_ms = (tsc_end - tsc_start) / 10;
}
static int serial_ready(void) {
return (inb(COM1 + 5) & 0x20) != 0;
}
/* 实机: 基于 TSC 的 100ms 超时等待 */
static int serial_wait_ready(void) {
for (u64 spin = 0; spin < 1000000ULL; spin++) {
if (serial_ready()) {
return 1;
if (!g_tsc_per_ms) {
/* 兜底: 校准未完成时使用循环 */
for (u64 spin = 0; spin < 1000000ULL; spin++) {
if (serial_ready()) return 1;
}
return 0;
}
u64 deadline = rdtsc_ser() + g_tsc_per_ms * 100; /* 100ms 超时 */
while (rdtsc_ser() < deadline) {
if (serial_ready()) return 1;
__asm__ volatile("pause");
}
return 0;
}
void serial_init(void) {
/* 实机要求: 先校准 TSC, 再使用基于 CPU 频率的延迟 */
tsc_calibrate_ser();
outb(COM1 + 1, 0x00);
outb(COM1 + 3, 0x80);
outb(COM1 + 0, 0x03);
Binary file not shown.
Binary file not shown.
+3
View File
@@ -1,6 +1,7 @@
#include <utsm/utsm.h>
#include <utsm/segment.h>
#include <utsm/pckc.h>
#include <utsm/process.h>
#include <utsm/log.h>
static utsm_segment_desc g_segments[UTSM_MAX_SEGMENTS];
@@ -18,6 +19,8 @@ void utsm_init(void) {
log_info("[UTSM] pckc init begin");
utsm_pckc_init();
log_info("[UTSM] pckc init ok");
utsm_process_init();
}
utsm_segment_desc *utsm_get_segment(u32 slot) {
Binary file not shown.
+6 -1
View File
@@ -248,6 +248,9 @@ int dkm_load_elf_rel(const void *address, u64 size, const struct dkm_symbol_scan
const elf64_ehdr *ehdr = (const elf64_ehdr *)address;
const elf64_shdr *sections = (const elf64_shdr *)((const u8 *)address + ehdr->shoff);
u64 image_offset[64];
/* Zero the entire array so non-ALLOC section indices yield offset 0
* instead of stack garbage. */
for (int zi = 0; zi < 64; zi++) image_offset[zi] = 0;
u64 total_size = 0;
u64 max_align = 16;
u16 alloc_count = 0;
@@ -353,7 +356,9 @@ int dkm_load_elf_rel(const void *address, u64 size, const struct dkm_symbol_scan
return -1;
}
if (rela->offset + 8 <= target->size) {
/* Bounds check: use the actual write width, not always 8. */
u32 reloc_width = (reloc_type == R_X86_64_64) ? 8 : 4;
if (rela->offset + reloc_width <= target->size) {
if (reloc_type == R_X86_64_32 || reloc_type == R_X86_64_32S || reloc_type == R_X86_64_PC32) {
*(u32 *)(target_base + rela->offset) = (u32)patch;
} else {
Binary file not shown.
Binary file not shown.
+4
View File
@@ -6,6 +6,7 @@
#define DKM_BLOCK_MAX_DEVICES 8u
typedef int (*dkm_block_read_fn)(void *ctx, u64 lba, u32 count, void *buffer);
typedef int (*dkm_block_write_fn)(void *ctx, u64 lba, u32 count, const void *buffer);
typedef struct dkm_block_device_desc {
const char *name;
@@ -13,14 +14,17 @@ typedef struct dkm_block_device_desc {
u64 sector_count;
void *ctx;
dkm_block_read_fn read;
dkm_block_write_fn write;
} dkm_block_device_desc;
typedef struct dkm_block_api {
int (*register_device)(const dkm_block_device_desc *desc);
u32 (*device_count)(void);
int (*read)(u32 index, u64 lba, u32 count, void *buffer);
int (*write)(u32 index, u64 lba, u32 count, const void *buffer);
u64 (*sector_size)(u32 index);
const char *(*device_name)(u32 index);
int (*set_write_fn)(u32 index, dkm_block_write_fn fn);
} dkm_block_api;
void block_init(void);
+9 -8
View File
@@ -195,12 +195,12 @@ typedef long long du_i64;
#define DU_ANIM_DELAY_NORMAL 100000u /* 标准动画 */
#define DU_ANIM_DELAY_FAST 40000u /* 快速反馈 */
/* 弧线动画参数(DSK spinner 专用) */
/* 弧线动画参数(DSK spinner 专用 — Sealed Arc Comet 设计) */
#define DU_SPINNER_RADIUS 48u
#define DU_SPINNER_THICKNESS 4u
#define DU_SPINNER_ARC_GAP 82u /* 每弧宽度(度) */
#define DU_SPINNER_ARC_COUNT 4u
#define DU_SPINNER_SPEED 2u /* 每帧旋转度数 */
#define DU_SPINNER_THICKNESS 5u
#define DU_SPINNER_HEAD_WIDTH 40u /* 弧头宽度(度) */
#define DU_SPINNER_TAIL_LEN 220u /* 拖尾长度(度) */
#define DU_SPINNER_SPEED 4u /* 每帧旋转度数 */
#define DU_SPINNER_SPRITE 128u /* 精灵缓冲边长 */
/* 渐变动画步进 */
@@ -673,12 +673,13 @@ static inline void du_draw_progress(du_context *ctx,
/* ===================================================================
* Spinner(加载弧) — DSK 启动加载动画
*
* 使用 "Sealed Arc" 四弧旋转设计,弧色取自色板。
* 使用 "Sealed Arc Comet" 单弧彗星尾设计:
* 一个明亮的弧头 + 渐变拖尾,颜色从弧头色过渡到拖尾色。
* =================================================================== */
/* 默认弧色(从亮到暗的青蓝色) */
/* 默认弧色:[0]=弧头色(亮蓝), [1]=拖尾色(紫) */
#define DU_SPINNER_ARCS { \
DP_SEAL_100, DP_SEAL_300, DP_SEAL_500, DP_SEAL_700 \
DP_SEAL_300, DP_SEAL_700, DP_SEAL_500, DP_SEAL_100 \
}
/* ===================================================================
+16 -1
View File
@@ -35,6 +35,13 @@ static int block_read_impl(u32 index, u64 lba, u32 count, void *buffer) {
return dev->read(dev->ctx, lba, count, buffer);
}
static int block_write_impl(u32 index, u64 lba, u32 count, const void *buffer) {
if (index >= g_device_count || !buffer || count == 0) return -1;
dkm_block_device_desc *dev = &g_devices[index];
if (!dev->write) return -2;
return dev->write(dev->ctx, lba, count, buffer);
}
static u64 block_sector_size_impl(u32 index) {
if (index >= g_device_count) return 0;
return g_devices[index].sector_size;
@@ -45,12 +52,20 @@ static const char *block_device_name_impl(u32 index) {
return g_devices[index].name;
}
static int block_set_write_fn_impl(u32 index, dkm_block_write_fn fn) {
if (index >= g_device_count) return -1;
g_devices[index].write = fn;
return 0;
}
static const dkm_block_api g_block_api = {
.register_device = block_register_device_impl,
.device_count = block_device_count_impl,
.read = block_read_impl,
.write = block_write_impl,
.sector_size = block_sector_size_impl,
.device_name = block_device_name_impl
.device_name = block_device_name_impl,
.set_write_fn = block_set_write_fn_impl
};
const dkm_block_api *block_get_api(void) {
Binary file not shown.
+2 -1
View File
@@ -152,7 +152,8 @@ static struct limine_file *dsk_find_module(void) {
/* ---- FAT32 block-provider file reader ---- */
static u8 g_dsk_fat32_disk[65536]; /* 128-sector BPB+FAT+root dir buffer */
static u8 g_dsk_fat32_cluster[4096]; /* 8-sector cluster buffer */
static u8 g_dsk_fat32_filedata[65536]; /* file data buffer */
/* 实机要求: 文件缓冲区足够大容纳 deshab.elf (~1.5MB) */
static u8 g_dsk_fat32_filedata[2097152]; /* 2MB file data buffer */
static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) {
const dkm_kernel_api *api = dkm_get_kernel_api();
Binary file not shown.
Binary file not shown.
+3
View File
@@ -25,6 +25,9 @@ SECTIONS
.data : ALIGN(4K) {
*(.data*)
*(COMMON)
} :data
.bss : ALIGN(4K) {
*(.bss*)
} :data
}
+12 -3
View File
@@ -1,16 +1,25 @@
#include <utsm/utsm.h>
#include <utsm/log.h>
#include <utsm/segment.h>
#include <utsm/arena.h>
int memcmp(const void *a, const void *b, usize len);
usize strlen(const char *s);
int utsm_selftest_run(void) {
utsm_process_context process;
utsm_process_create_test(&process, 1);
log_info("[UTSM] selftest enter");
/* utsm_process_context is ~8KB (256 capabilities × 32 bytes).
* Allocate from arena instead of stack to avoid kernel stack overflow. */
utsm_process_context *process = (utsm_process_context *)kmem_alloc(sizeof(utsm_process_context));
if (!process) {
log_error("[UTSM] selftest: failed to allocate process context");
return UTSM_ERR_NO_MEMORY;
}
utsm_process_create_test(process, 1);
utsm_capability cap;
int status = utsm_create_segment(&process, UTSM_PAGE_SIZE, UTSM_SEG_F_READ | UTSM_SEG_F_WRITE | UTSM_SEG_F_STRONG_RECOVERY, &cap);
int status = utsm_create_segment(process, UTSM_PAGE_SIZE, UTSM_SEG_F_READ | UTSM_SEG_F_WRITE | UTSM_SEG_F_STRONG_RECOVERY, &cap);
if (status != UTSM_OK) {
log_error("[UTSM] selftest create segment failed");
return status;
Binary file not shown.