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:
@@ -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.
@@ -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.
@@ -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.
@@ -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);
|
||||
|
||||
@@ -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 \
|
||||
}
|
||||
|
||||
/* ===================================================================
|
||||
|
||||
@@ -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.
@@ -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.
@@ -25,6 +25,9 @@ SECTIONS
|
||||
.data : ALIGN(4K) {
|
||||
*(.data*)
|
||||
*(COMMON)
|
||||
} :data
|
||||
|
||||
.bss : ALIGN(4K) {
|
||||
*(.bss*)
|
||||
} :data
|
||||
}
|
||||
|
||||
@@ -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.
Reference in New Issue
Block a user