FUCKKKK
This commit is contained in:
@@ -0,0 +1,270 @@
|
||||
# 更改桌面启动逻辑
|
||||
|
||||
> **Workspace:** d:\Code\Deshab
|
||||
|
||||
---
|
||||
|
||||
**User**
|
||||
|
||||
更改桌面启动逻辑,用来适配直接在linux下也可以直接启动系统桌面测试
|
||||
|
||||
**Assistant**
|
||||
|
||||
我先了解一下当前桌面启动逻辑的实现,然后再设计适配方案。
|
||||
|
||||
### Relevant Code Snippets
|
||||
1. d:\Code\Deshab\CODE\dsk\main.c:L1055-L1163
|
||||
— DSK 主内核中的 ELF 加载器:校验 `desktop.elf`/模块 ELF 的 magic、机器类型、program headers、PT_LOAD 段和 entry point,将 ELF 映射到 8MB 缓冲,并应用 `R_X86_64_RELATIVE` PIE 重定位。
|
||||
|
||||
2. d:\Code\Deshab\CODE\dsk\main.c:L1166-L1190
|
||||
— DSK 加载并运行 ELF 模块的核心链路:`dsk_load_and_run()` 从 FAT32 根目录按 8.3 名读取文件,调用 `dsk_load_elf()`,然后跳转到 ELF entry;`dsk_run_desktop()` 专门加载 `DESKTOP ELF`,即 `desktop.elf`。
|
||||
|
||||
3. d:\Code\Deshab\CODE\dsk\main.c:L1430-L1437
|
||||
— 非首次启动路径中 DSK 调度桌面:记录加载统计、写 `BOOT_06` 里程碑、调用 `dsk_run_desktop(ctx)`,这是 `deshab.elf` 启动桌面的直接入口。
|
||||
|
||||
4. d:\Code\Deshab\CODE\dsk\main.c:L1440-L1488
|
||||
— 首次启动路径:按 `mouseInit -> netman -> FirstInit -> desktop` 顺序加载运行模块,最终在 `FirstInit` 返回后调用 `dsk_run_desktop(ctx)` 启动桌面。
|
||||
|
||||
5. d:\Code\Deshab\CODE\UTSM\kernel\dsk_loader.c:L221-L342
|
||||
— UTSM 侧 DSK 加载器:通过 block provider 读取 FAT32,定位根目录中的 `DESHAB ELF`,按 FAT 链读取 `deshab.elf` 数据并交给 DSK 加载流程。
|
||||
|
||||
6. d:\Code\Deshab\CODE\UTSM\kernel\dsk_loader.c:L643-L689
|
||||
— UTSM 启动 DSK 的入口逻辑:优先从 FAT32 block provider 加载 `deshab.elf`,失败则回退到 Limine boot module;校验 ELF 后加载映像、构造 boot context,然后跳转。
|
||||
|
||||
7. d:\Code\Deshab\SYSTEM\system\deshab64\FUCK:L76-L82
|
||||
— DSK 启动行为配置:`[dsk]` 分区控制 `show_logo`、`skip_login`、`default_shell`、`mouse_init`、`netman`,影响 DSK 是否显示 Logo、是否跳过登录、是否加载鼠标/网络管理器,以及默认 shell 行为。
|
||||
|
||||
8. d:\Code\Deshab\CODE\desktop\main.c:L224-L233
|
||||
— 桌面进程依赖的运行时资源:保存 framebuffer 地址/宽高/pitch、kernel API、block read/write 回调,以及双缓冲 sprite buffer,说明桌面启动后依赖 framebuffer 和块设备接口。
|
||||
|
||||
让我进一步查看桌面主代码和 DSK 加载桌面的具体逻辑。
|
||||
|
||||
这是个涉及架构决策的复杂任务。让我先充分探索现有的 Linux 兼容层和桌面入口逻辑,再设计适配方案。
|
||||
|
||||
### Relevant Code Snippets
|
||||
1. d:\Code\Deshab\CODE\UTSM\include\utsm\linux_compat.h:L4-L18
|
||||
— Linux 兼容层服务接口说明:UTSM 侧通过 IPC/shared memory 向 Linux daemon 发送 exec 请求,并经由 `reserved[5]` 暴露给 shell/cmd/desktop。
|
||||
|
||||
2. d:\Code\Deshab\CODE\UTSM\include\utsm\linux_compat.h:L24-L96
|
||||
— `linux_compat_service` 完整结构体定义,包含 `is_available`、`exec`、`file_list`、`file_read`、`file_write`、`file_pull`、`file_push`、`status` 等兼容层能力。
|
||||
|
||||
3. d:\Code\Deshab\CODE\UTSM\include\utsm\dsk.h:L30-L64
|
||||
— `dsk_boot_context` 结构体定义;桌面入口函数接收该上下文,其中 `reserved[5]` 用于传递 Linux 兼容层服务指针。
|
||||
|
||||
4. d:\Code\Deshab\CODE\desktop\main.c:L21-L23
|
||||
— `desktop/main.c` 包含 `dsk.h` 与 `linux_compat.h`,表明桌面代码直接依赖 DSK boot context 和 Linux 兼容层服务接口。
|
||||
|
||||
5. d:\Code\Deshab\CODE\desktop\main.c:L42-L50
|
||||
— 桌面入口附近定义 COM1 串口 I/O、`outb/inb`、`rdtsc`,并包含 `tools/desktop_app.h` 的 Linux 桌面应用配置契约。
|
||||
|
||||
6. d:\Code\Deshab\CODE\desktop\main.c:L3517-L3561
|
||||
— 桌面主入口 `dsk_entry(const dsk_boot_context *ctx)`:校验 boot context,初始化 framebuffer/block API,并从 `ctx->reserved[5]` 加载 Linux 兼容层服务。
|
||||
|
||||
7. d:\Code\Deshab\CODE\desktop\main.c:L3604-L3704
|
||||
— 桌面主事件循环:轮询 PS/2 鼠标、处理按键、更新 RTC、按需重绘并 flip framebuffer,循环退出后返回 DSK。
|
||||
|
||||
8. d:\Code\Deshab\CODE\desktop\main.c:L891-L922
|
||||
— PS/2 鼠标端口读取实现:通过 `inb(0x64)` 状态和 `inb(0x60)` 数据读取鼠标包,并更新光标位置与按键状态。
|
||||
|
||||
9. d:\Code\Deshab\CODE\desktop\main.c:L1157-L1320
|
||||
— Linux 兼容层应用执行路径:`lnx_on_create` 创建终端窗口,调用 `g_lxc_svc->exec(...)` 同步执行 Linux 命令并收集 stdout。
|
||||
|
||||
10. d:\Code\Deshab\CODE\desktop\main.c:L1362-L1418
|
||||
— Linux 应用注册逻辑:从 FAT32 根目录读取 `LINUXAPPCNF`,解析 Linux 命令列表,并注册为桌面 Linux 兼容层应用。
|
||||
|
||||
11. d:\Code\Deshab\CODE\tools\desktop_app.h:L433-L496
|
||||
— `DA_LINUXAPP_*` 常量与 `da_linuxapp_parse` 完整实现,用于解析 `LINUXAPP.CNF` 的 `显示名|linux命令` 配置。
|
||||
|
||||
这是个架构级改动。我先查一下项目记忆中是否有相关历史,然后进入计划模式设计方案。
|
||||
|
||||
我已经理清了现状:
|
||||
|
||||
- 桌面 `desktop.elf` 是 freestanding 裸机 ELF,入口 `dsk_entry(ctx)`,直接依赖:framebuffer 显存直写、PS/2 鼠标/键盘端口 I/O(`inb(0x64/0x60)`)、COM1 串口、RTC CMOS、`rdtsc`/`cli`/`hlt`/`pause`、kernel_api block 接口读写 FAT32。
|
||||
- 没有任何 Linux 宿主代码。
|
||||
|
||||
要在 Linux 下直接跑桌面测试,需要引入硬件抽象层 + Linux 宿主。这是个多文件架构改动,有多种实现方式,我先进入计划模式设计方案并和你确认。
|
||||
|
||||
现在进入计划模式的第一阶段:全面梳理桌面代码的硬件依赖与可复用资产。我并行启动探索代理。
|
||||
|
||||
### Relevant Code Snippets
|
||||
1. d:\Code\Deshab\CODE\desktop\main.c:L42-L55
|
||||
— 定义 `COM1=0x3F8`,并提供 `outb/inb` 内联端口 I/O;`sputc` 通过 `inb(COM1+5)` 等待发送缓冲区空,再 `outb(COM1,...)` 写串口日志。
|
||||
|
||||
2. d:\Code\Deshab\CODE\desktop\main.c:L70-L74
|
||||
— `rdtsc()` 内联汇编读取 CPU 时间戳计数器,是 TSC 校准和双击间隔判定的底层来源。
|
||||
|
||||
3. d:\Code\Deshab\CODE\desktop\main.c:L444-L475
|
||||
— RTC/CMOS 直接访问点:`rtc_read` 通过 `outb(0x70, register)` + `inb(0x71)` 读取秒/分/时/日/月/年;`rtc_day_sec()` 转换为当天秒;`tsc_calibrate()` 用 RTC 秒和 `rdtsc()` 测量 TSC/秒,并用 `pause` 等待。
|
||||
|
||||
4. d:\Code\Deshab\CODE\desktop\main.c:L630-L653
|
||||
— framebuffer 直写核心:`flip_buffer()` 将 `SPRITE_BUF_ADDR` sprite buffer 完整拷贝到 `g_real_fb`;`flip_rect()` 按 pitch 计算源/目标地址并复制矩形区域,用于光标/脏矩形更新。
|
||||
|
||||
5. d:\Code\Deshab\CODE\desktop\main.c:L823-L923
|
||||
— PS/2 鼠标直接访问点:`ps2_wait_write/read` 轮询 `0x64` 状态并 `pause`;`ps2_drain` 读取 `0x60` 清空缓冲区;`ps2_mouse_init()` 通过 `0x64/0x60` 配置鼠标;`ps2_mouse_poll()` 读取 `0x64` 和 `0x60` 解析鼠标包。
|
||||
|
||||
6. d:\Code\Deshab\CODE\desktop\main.c:L3517-L3568
|
||||
— boot entry 中的硬件初始化顺序:`cli` 关中断,读取 `dsk_boot_context` 的 framebuffer/kernel API/blocks,设置 `g_real_fb` 和 `g_fb.fb`,调用 `f32_init`、`tsc_calibrate`、`rtc_day_sec`、`ps2_mouse_init`。
|
||||
|
||||
7. d:\Code\Deshab\CODE\desktop\main.c:L3604-L3700
|
||||
— 主事件循环中的硬件轮询与渲染边界:循环读取 PS/2 鼠标、键盘扫描码,读取 RTC 秒 tick,根据脏矩形调用 `redraw_all()`、`flip_buffer()` 或 `flip_rect()`,最后 `pause` 等待下一轮。
|
||||
|
||||
8. d:\Code\Deshab\CODE\desktop\main.c:L1055-L1061
|
||||
— 命令行 reboot/halt 路径直接写 `0x64` 并执行 `hlt`,属于直接硬件控制入口。
|
||||
|
||||
### Relevant Code Snippets
|
||||
1. d:\Code\Deshab\CODE\desktop\main.c:L21-L34
|
||||
— 桌面主入口直接依赖的头文件/源文件:`dsk.h`、`linux_compat.h`、`ascii_bitmaps.c`、`deshab_ui.h`、`fat32_io.h`,是追踪 Linux 用户态宿主兼容层依赖链的起点。
|
||||
|
||||
2. d:\Code\Deshab\CODE\desktop\main.c:L47-L50
|
||||
— 桌面应用配置契约入口:包含 `tools/desktop_app.h`,并定义 `DA_NO_PORTIO` 以避免与宿主自带端口 I/O 冲突。
|
||||
|
||||
3. d:\Code\Deshab\CODE\UTSM\include\utsm\deshab_ui.h:L229-L243
|
||||
— `du_context` 渲染上下文定义及 `du_context_init`,说明 UI 渲染 API 依赖的 framebuffer 基址、宽高、行宽参数。
|
||||
|
||||
4. d:\Code\Deshab\CODE\UTSM\include\utsm\deshab_ui.h:L273-L327
|
||||
— 核心渲染原语:`du_pixel`、`du_pixel_read`、`du_fill_rect`、渐变填充、全屏填充等;这些都是纯内存 framebuffer 操作,不直接访问硬件。
|
||||
|
||||
5. d:\Code\Deshab\CODE\tools\fat32_io.h:L24-L70
|
||||
— FAT32 用户态读写抽象:通过 `f32_init()` 注入 `block_read` / `block_write` 回调,并维护 `f32_disk`、`f32_cluster`、`f32_data` 缓冲。
|
||||
|
||||
6. d:\Code\Deshab\CODE\tools\fat32_io.h:L160-L209
|
||||
— `f32_read_root_file()` 实现根目录文件读取,依赖 FAT 链跟随、目录项查找和 block read 回调,是 Linux 宿主访问 DESHAB FAT32 资产的重要逻辑。
|
||||
|
||||
7. d:\Code\Deshab\build.ps1:L613-L629
|
||||
— `desktop.elf` 构建流程:使用 `make -C CODE/desktop`,由 `MAKEFILE` 驱动编译链接;这是桌面资产进入 `SYSTEM/system/deshab64/desktop.elf` 的路径。
|
||||
|
||||
8. d:\Code\Deshab\SYSTEM\system\deshab64\
|
||||
— 构建产物目录,包含 `desktop.elf`、`shell.elf`、`deshab.elf`、`cmd.elf`、`FUCK` 等,是 FAT32/ESP 镜像中 Linux 宿主需要访问的桌面及相关 ELF 资产。
|
||||
|
||||
信息已经比较充分。让我读取几个关键实现细节,确认 HAL 边界设计可行。
|
||||
|
||||
我已经完全摸清了硬件访问边界。桌面代码分层很清晰:
|
||||
|
||||
- **渲染层**(`du_context` 系列 + `flip_buffer`/`flip_rect`):纯内存像素操作,可原样复用
|
||||
- **FAT32 层**(`f32_init` 注入 block 回调):纯回调驱动,可原样复用
|
||||
- **硬件访问点**(需抽象):COM1 串口日志、PS/2 鼠标 `inb(0x64/0x60)`、PS/2 键盘扫描码、RTC CMOS `0x70/0x71`、`rdtsc`/`tsc_calibrate`、`cli`/`hlt`/`pause`、framebuffer flip 目标地址、reboot/halt
|
||||
|
||||
这意味着只要把约 10 个硬件访问函数 + 几条内联汇编做编译期替换,桌面 UI 主体逻辑就能在 Linux 用户态跑起来。在设计最终方案前,有几个关键决策需要你拍板。
|
||||
|
||||
方案确定:SDL2 + 直读 deshab.img + 编译期 #ifdef。让我再确认几个实施细节(链接脚本、types 兼容性、镜像内容、是否有遗漏的硬件点),然后产出最终计划。
|
||||
|
||||
所有实施细节都已确认。关键发现:
|
||||
|
||||
- `types.h` 是纯 typedef,Linux 用户态完全兼容
|
||||
- `fat32_io.h` 是 static inline 注入回调库,可原样复用
|
||||
- `deshab_ui.h` 渲染原语纯内存操作,可原样复用
|
||||
- `linker.ld` 是裸机 PIE 脚本,Linux 宿主用普通 gcc 链接即可
|
||||
- desktop 的 block 路径走 `ctx->dkm_kernel_api + 0xA8`,宿主只需伪造一个 kernel_api 结构即可让现有代码零改动取到宿主 block 函数
|
||||
|
||||
现在写最终计划文件。
|
||||
|
||||
计划已写好。我来通知你审阅。
|
||||
|
||||
计划已批准。开始实施。先建立任务清单,然后精确定位 main.c 中所有需要改动的位置。
|
||||
|
||||
现在精确定位 main.c 中所有 `__asm__` 出现位置和关键全局变量定义,确保 HAL_* 宏替换无遗漏。
|
||||
|
||||
改动点已全部定位。让我确认双击判定的 TSC 赋值位置,以及 build.ps1 中 ESP 分区偏移(决定 host block 后端实现)。
|
||||
|
||||
ESP 分区起始 LBA=2048(1MB 对齐),类型 GUID `c12a7328-...`。双击 TSC 赋值在 L3320 `g_last_click_tsc = rdtsc()`,host 下用 `host_now_us()` 替换即可。
|
||||
|
||||
设计全部确认。开始写代码。先写 `host_main.h`。
|
||||
|
||||
`host_main.h` 完成。现在写核心宿主实现 `host_main.c`。
|
||||
|
||||
`host_main.c` 完成。现在改 `main.c`。先确认 `rtc_read` 是否在别处调用,以及 `swrite` 的使用范围,确保 #ifdef 包裹无遗漏。
|
||||
|
||||
`rtc_read` 在 L2387 另有调用。让我看那个调用点,host 下也需提供 `rtc_read` 实现。
|
||||
|
||||
`rtc_read` 用于状态栏完整日期时间,host 下用 `localtime` 提供实现。现在开始批量编辑 `main.c`。先处理顶部平台层(HAL 宏、outb/inb/rdtsc/SPRITE_BUF_ADDR/sputc)。
|
||||
|
||||
顶部平台层完成。现在处理 RTC、tsc_calibrate(含 pause→HAL_PAUSE)。
|
||||
|
||||
PS/2 鼠标块需要整体 #ifdef 包裹。让我先确认当前确切文本。
|
||||
|
||||
现在替换整个 PS/2 鼠标块为 #ifdef 分支。
|
||||
|
||||
PS/2 块完成。现在并行处理剩余的 `__asm__` 替换:reboot/halt、dsk_entry 的 cli/hlt、键盘轮询、主循环末尾、anim_delay、busy_delay。
|
||||
|
||||
现在处理键盘轮询循环和主循环末尾 pause——这两个是 host 模式事件接入的关键点。
|
||||
|
||||
所有 main.c 编辑完成。让我验证没有遗漏的 `__asm__`,并确认 #ifdef 配对正确。
|
||||
|
||||
有几处 `__asm__` 似乎未替换。让我确认当前实际内容。
|
||||
|
||||
奇怪——anim_delay、reboot/halt、dsk_entry 的修改似乎未持久化。让我重新读 dsk_entry 确认当前状态,然后重新应用这些编辑。
|
||||
|
||||
确认这 3 处仍是原始 `__asm__`。重新应用这些编辑。
|
||||
|
||||
这次都生效了。再次验证剩余 `__asm__` 是否都在裸机分支内。
|
||||
|
||||
所有 `__asm__` 现在都在裸机 `#else` 分支内,host 编译不会触及。`main.c` 改动完成。
|
||||
|
||||
现在写 `Makefile.linux`。
|
||||
|
||||
`Makefile.linux` 完成。现在写便利脚本 `run_desktop_host.sh`。
|
||||
|
||||
便利脚本完成。现在做验证。先检查 `#ifdef DESHAB_HOST` 配对正确性,然后尝试裸机编译回归。
|
||||
|
||||
9 个 `#ifdef` / 9 个 `#else` / 9 个 `#endif` 完全配对。让我列出所有位置确认覆盖完整。
|
||||
|
||||
只有 9 个,但键盘轮询的 `#ifdef` 不在列表里。让我确认键盘轮询是否生效。
|
||||
|
||||
键盘轮询的编辑也未持久化。重新应用。
|
||||
|
||||
键盘轮询修复完成。现在做最终验证:确认 `#ifdef` 配对完整,然后尝试裸机语法检查(验证回归不影响裸机编译)。
|
||||
|
||||
10 个 `#ifdef` / 10 个 `#endif`,配对完整。现在用 clang 做裸机语法检查,验证回归安全(不带 `-DDESHAB_HOST`)。
|
||||
|
||||
clang 路径不对。让我找 clang 实际位置。
|
||||
|
||||
找到了 clang。现在做裸机语法检查,验证 `#ifdef` 裸机分支完整。
|
||||
|
||||
裸机语法检查通过(零错误零警告),回归安全。现在验证 host 分支语法(用 `-DDESHAB_HOST`,Windows 下可检查 main.c 逻辑,SDL2 部分留待 Linux)。
|
||||
|
||||
host 分支语法检查通过——仅 6 个 warning(`localtime` 在 Windows MSVC 下的安全提示、host 模式下未使用的裸机辅助函数/变量),**零 error**。这些 warning 在 Linux 下不会出现(localtime 非 deprecated)或无害。
|
||||
|
||||
接口一致性也确认匹配。现在做完整裸机编译链接,确保 `desktop.elf` 回归正常。
|
||||
|
||||
裸机编译链接成功,产物 153560 字节,与现有 `desktop.elf` 完全一致——**字节级回归零影响**。清理临时文件。
|
||||
|
||||
所有任务完成。更新最终状态。
|
||||
|
||||
已完成 Linux 桌面宿主适配。下面是变更总结。
|
||||
|
||||
## 改动概览
|
||||
|
||||
通过编译期 `#ifdef DESHAB_HOST` 切换,桌面 UI 主体逻辑(渲染、FAT32、窗口管理、事件处理)**原样复用同一份 `main.c`**,仅替换硬件访问点。裸机 `desktop.elf` 字节级零影响。
|
||||
|
||||
### 新增文件
|
||||
- [host_main.h](file:///d:/Code/Deshab/CODE/desktop/host_main.h) — 宿主对外接口声明(日志、时钟、鼠标/键盘轮询、帧末 present、缓冲 extern)
|
||||
- [host_main.c](file:///d:/Code/Deshab/CODE/desktop/host_main.c) — SDL2 宿主核心:窗口+streaming texture、GPT ESP 解析 + `deshab.img` block 后端(pread/pwrite)、鼠标/键盘事件队列、SDL_Scancode→set-1 映射、伪造 kernel_api 让现有 block 获取路径零改动
|
||||
- [Makefile.linux](file:///d:/Code/Deshab/CODE/desktop/Makefile.linux) — `make -f Makefile.linux` 产出 `desktop_host`,支持 `run` 目标
|
||||
- [run_desktop_host.sh](file:///d:/Code/Deshab/ISO/run_desktop_host.sh) — 检测 SDL2、编译并启动的便利脚本
|
||||
|
||||
### 修改文件
|
||||
- [main.c](file:///d:/Code/Deshab/CODE/desktop/main.c) — 10 处 `#ifdef DESHAB_HOST` 分支 + `HAL_CLI/HAL_HLT/HAL_PAUSE` 宏替换所有散落 `__asm__`:
|
||||
- 平台层(HAL 宏、outb/inb/rdtsc/SPRITE_BUF_ADDR)
|
||||
- 串口日志 sputc/swrite/slog → host_log/fprintf
|
||||
- RTC → localtime、TSC → clock_gettime(微秒)
|
||||
- PS/2 鼠标 → host_mouse_poll、键盘轮询 → host_kb_poll
|
||||
- reboot → exit(0)、主循环末尾 pause → host_pump_and_present
|
||||
|
||||
## 验证结果
|
||||
- **裸机回归**:clang 完整编译链接 `desktop.elf`,产物 153560 字节,与现有镜像**完全一致**,10 个 `#ifdef`/`#endif` 全配对,所有 `__asm__` 仅在裸机 `#else` 分支内
|
||||
- **host 语法**:`-DDESHAB_HOST` 下 main.c 语法检查零 error(6 个 warning 均为 host 模式下未使用的裸机辅助符号 + Windows MSVC 的 localtime 安全提示,Linux 下不出现)
|
||||
|
||||
## 在 Linux 下使用
|
||||
```bash
|
||||
sudo apt install libsdl2-dev # 一次性安装依赖
|
||||
./ISO/run_desktop_host.sh # 编译并启动,默认读 ISO/deshab.img
|
||||
# 或手动:
|
||||
cd CODE/desktop && make -f Makefile.linux && ./desktop_host --img ../../ISO/deshab.img
|
||||
```
|
||||
|
||||
宿主会打开 1280×720 SDL 窗口,直读 `deshab.img` 的 GPT ESP 分区作为 FAT32 block 后端,鼠标/键盘由 SDL 事件注入。首次启动需先在 Windows 下 `build.bat` 生成 `ISO/deshab.img`(确保 `firstInit.txt` 已是 `1`、`USER.CONF` 已存在,从而直接进桌面)。
|
||||
|
||||
> 注意:`host_main.c` 的完整编译需在 Linux 下进行(依赖 SDL2 头),Windows 仅做了语法检查。若 Linux 编译遇问题,把报错贴回来我来修。
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user