diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ae5e08..9d5651b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -265,6 +265,7 @@ set(CFLAGS_COMMON -Wextra -Werror "-I${CMAKE_SOURCE_DIR}/clks/include" + "-I${CMAKE_SOURCE_DIR}/common/include" ) set(CXXFLAGS_COMMON @@ -281,6 +282,7 @@ set(CXXFLAGS_COMMON -Wextra -Werror "-I${CMAKE_SOURCE_DIR}/clks/include" + "-I${CMAKE_SOURCE_DIR}/common/include" ) set(ARCH_CFLAGS @@ -357,6 +359,7 @@ set(USER_CFLAGS -Wextra -Werror "-I${CMAKE_SOURCE_DIR}/cleonos/c/include" + "-I${CMAKE_SOURCE_DIR}/common/include" ) set(USER_CFLAGS_DOOM @@ -372,6 +375,7 @@ set(USER_CFLAGS_DOOM -Wno-sign-compare -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L + "-I${CMAKE_SOURCE_DIR}/common/include" "-I${CMAKE_SOURCE_DIR}/cleonos/third-party/doomgeneric/doomgeneric" "-include" "${CMAKE_SOURCE_DIR}/cleonos/c/apps/doom/doom_shim.h" diff --git a/cleonos/c/apps/fastfetch_main.c b/cleonos/c/apps/fastfetch_main.c index 9db73d2..43d8b5b 100644 --- a/cleonos/c/apps/fastfetch_main.c +++ b/cleonos/c/apps/fastfetch_main.c @@ -1,4 +1,5 @@ #include "cmd_runtime.h" +#include static u64 ush_fastfetch_u64_to_dec(char *out, u64 out_size, u64 value) { char rev[32]; u64 digits = 0ULL; @@ -115,6 +116,7 @@ static int ush_cmd_fastfetch(const char *arg) { u64 tty_count; u64 exec_req; u64 exec_ok; + char kernel_version[32]; if (arg != (const char *)0 && arg[0] != '\0') { if (ush_streq(arg, "--plain") != 0) { @@ -132,12 +134,17 @@ static int ush_cmd_fastfetch(const char *arg) { tty_count = cleonos_sys_tty_count(); exec_req = cleonos_sys_exec_request_count(); exec_ok = cleonos_sys_exec_success_count(); + if (cleonos_sys_kernel_version(kernel_version, (u64)sizeof(kernel_version)) == 0ULL) { + ush_copy(kernel_version, (u64)sizeof(kernel_version), "unknown"); + } ush_fastfetch_print_logo(plain); ush_write_char('\n'); ush_fastfetch_print_text(plain, "OS", "CLeonOS x86_64"); ush_fastfetch_print_text(plain, "Shell", "User Shell (/shell/shell.elf)"); + ush_fastfetch_print_text(plain, "CLeonOSVersion", CLEONOS_VERSION_STRING); + ush_fastfetch_print_text(plain, "CLKSVersion", kernel_version); ush_fastfetch_print_u64(plain, "PID", cleonos_sys_getpid()); ush_fastfetch_print_u64(plain, "UptimeTicks", cleonos_sys_timer_ticks()); ush_fastfetch_print_u64(plain, "Tasks", cleonos_sys_task_count()); diff --git a/cleonos/c/include/cleonos_syscall.h b/cleonos/c/include/cleonos_syscall.h index 7d096d4..6c942e7 100644 --- a/cleonos/c/include/cleonos_syscall.h +++ b/cleonos/c/include/cleonos_syscall.h @@ -144,6 +144,7 @@ typedef struct cleonos_fb_blit_req { #define CLEONOS_SYSCALL_FB_INFO 81ULL #define CLEONOS_SYSCALL_FB_BLIT 82ULL #define CLEONOS_SYSCALL_FB_CLEAR 83ULL +#define CLEONOS_SYSCALL_KERNEL_VERSION 84ULL u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2); u64 cleonos_sys_log_write(const char *message, u64 length); @@ -230,5 +231,6 @@ u64 cleonos_sys_dl_sym(u64 handle, const char *symbol); u64 cleonos_sys_fb_info(cleonos_fb_info *out_info); u64 cleonos_sys_fb_blit(const cleonos_fb_blit_req *req); u64 cleonos_sys_fb_clear(u64 rgb); +u64 cleonos_sys_kernel_version(char *out_version, u64 out_size); #endif diff --git a/cleonos/c/src/syscall.c b/cleonos/c/src/syscall.c index 1ea4ba1..3286323 100644 --- a/cleonos/c/src/syscall.c +++ b/cleonos/c/src/syscall.c @@ -367,3 +367,7 @@ u64 cleonos_sys_fb_blit(const cleonos_fb_blit_req *req) { u64 cleonos_sys_fb_clear(u64 rgb) { return cleonos_syscall(CLEONOS_SYSCALL_FB_CLEAR, rgb, 0ULL, 0ULL); } + +u64 cleonos_sys_kernel_version(char *out_version, u64 out_size) { + return cleonos_syscall(CLEONOS_SYSCALL_KERNEL_VERSION, (u64)out_version, out_size, 0ULL); +} diff --git a/clks/include/clks/syscall.h b/clks/include/clks/syscall.h index a2869ce..8bfb8e4 100644 --- a/clks/include/clks/syscall.h +++ b/clks/include/clks/syscall.h @@ -87,6 +87,7 @@ #define CLKS_SYSCALL_FB_INFO 81ULL #define CLKS_SYSCALL_FB_BLIT 82ULL #define CLKS_SYSCALL_FB_CLEAR 83ULL +#define CLKS_SYSCALL_KERNEL_VERSION 84ULL void clks_syscall_init(void); u64 clks_syscall_dispatch(void *frame_ptr); diff --git a/clks/kernel/runtime/syscall.c b/clks/kernel/runtime/syscall.c index 901b434..cec03e9 100644 --- a/clks/kernel/runtime/syscall.c +++ b/clks/kernel/runtime/syscall.c @@ -16,6 +16,7 @@ #include #include #include +#include #define CLKS_SYSCALL_LOG_MAX_LEN 191U #define CLKS_SYSCALL_PATH_MAX 192U @@ -33,7 +34,7 @@ #define CLKS_SYSCALL_KDBG_STACK_WINDOW_BYTES (128ULL * 1024ULL) #define CLKS_SYSCALL_KERNEL_SYMBOL_FILE "/system/kernel.sym" #define CLKS_SYSCALL_KERNEL_ADDR_BASE 0xFFFF800000000000ULL -#define CLKS_SYSCALL_STATS_MAX_ID CLKS_SYSCALL_FB_CLEAR +#define CLKS_SYSCALL_STATS_MAX_ID CLKS_SYSCALL_KERNEL_VERSION #define CLKS_SYSCALL_STATS_RING_SIZE 256U #define CLKS_SYSCALL_USC_MAX_ALLOWED_APPS 64U @@ -467,6 +468,11 @@ static u64 clks_syscall_fb_blit(u64 arg0) { return 1ULL; } +static u64 clks_syscall_kernel_version(u64 arg0, u64 arg1) { + usize len = clks_strlen(CLKS_VERSION_STRING); + return clks_syscall_copy_text_to_user(arg0, arg1, CLKS_VERSION_STRING, len); +} + static u64 clks_syscall_fd_open(u64 arg0, u64 arg1, u64 arg2) { char path[CLKS_SYSCALL_PATH_MAX]; @@ -2513,6 +2519,8 @@ u64 clks_syscall_dispatch(void *frame_ptr) { return clks_syscall_fb_blit(frame->rbx); case CLKS_SYSCALL_FB_CLEAR: return clks_syscall_fb_clear(frame->rbx); + case CLKS_SYSCALL_KERNEL_VERSION: + return clks_syscall_kernel_version(frame->rbx, frame->rcx); default: return (u64)-1; } diff --git a/common/include/cleonos_version.h b/common/include/cleonos_version.h new file mode 100644 index 0000000..6186e5c --- /dev/null +++ b/common/include/cleonos_version.h @@ -0,0 +1,7 @@ +#ifndef CLEONOS_VERSION_H +#define CLEONOS_VERSION_H + +#define CLKS_VERSION_STRING "1.0.0-alpha" +#define CLEONOS_VERSION_STRING "1.0.0-alpha" + +#endif diff --git a/docs/syscall.md b/docs/syscall.md index 32a1a85..786c54c 100644 --- a/docs/syscall.md +++ b/docs/syscall.md @@ -83,7 +83,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2); - `/proc/`:指定 PID 快照文本 - `/proc` 为只读;写入类 syscall 不支持。 -## 4. Syscall 列表(0~83) +## 4. Syscall 列表(0~84) ### 0 `CLEONOS_SYSCALL_LOG_WRITE` @@ -659,6 +659,14 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2); - 返回:成功 `1`,失败 `0` - 说明:用纯色清屏。 +### 84 `CLEONOS_SYSCALL_KERNEL_VERSION` + +- 参数: +- `arg0`: `char *out_version` +- `arg1`: `u64 out_size` +- 返回:实际写入字节数(不含终止符),失败返回 `0` +- 说明:返回 CLKS 内核版本字符串(当前默认 `1.0.0-alpha`),内核会保证输出以 `\0` 结尾。 + ## 5. 用户态封装函数 用户态封装位于: @@ -687,6 +695,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2); - `cleonos_sys_dl_open()` / `cleonos_sys_dl_close()` / `cleonos_sys_dl_sym()` - `cleonos_sys_exec_pathv_io()` - `cleonos_sys_fb_info()` / `cleonos_sys_fb_blit()` / `cleonos_sys_fb_clear()` +- `cleonos_sys_kernel_version()` ## 6. 开发注意事项 @@ -697,7 +706,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2); ## 7. Wine 兼容说明 -- `wine/cleonos_wine_lib/runner.py` 当前已覆盖到 `0..83`(含 `DL_*`、`FB_*`)。 +- `wine/cleonos_wine_lib/runner.py` 当前已覆盖到 `0..84`(含 `DL_*`、`FB_*`、`KERNEL_VERSION`)。 - `DL_*`(`77..79`)在 Wine 中为“可运行兼容”实现: - `DL_OPEN`:加载 guest ELF 到当前 Unicorn 地址空间,返回稳定 `handle`,并做引用计数。 - `DL_SYM`:解析 ELF `SYMTAB/DYNSYM` 并返回 guest 可调用地址。 @@ -708,5 +717,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2); - `FB_BLIT` 实现内核同类参数校验并支持 `scale>=1` 绘制。 - 配合 Wine 参数 `--fb-window` 可将 framebuffer 实时显示到主机窗口(pygame 后端);未启用时保持内存缓冲模式。 - `FB_CLEAR` 支持清屏颜色写入。 +- `KERNEL_VERSION`(`84`)在 Wine 中返回内核版本字符串(当前默认 `1.0.0-alpha`)。 - Wine 在运行时崩溃场景下会生成与内核一致格式的“信号编码退出状态”,可通过 `WAITPID` 读取。 - Wine 当前音频 syscall 为占位实现:`AUDIO_AVAILABLE=0`,`AUDIO_PLAY_TONE=0`,`AUDIO_STOP=1`。 +- Wine 版本号策略固定为 `85.0.0-wine`(`85` = 当前实现 syscall 数量,后续保持不变)。 diff --git a/wine/README.md b/wine/README.md index 4f51dc8..2075c7d 100644 --- a/wine/README.md +++ b/wine/README.md @@ -38,7 +38,7 @@ python wine/cleonos_wine.py build/x86_64/ramdisk_root/shell/shell.elf --rootfs b ## 支持 - ELF64 (x86_64) PT_LOAD 段装载 -- CLeonOS `int 0x80` syscall 0..83(含 `FD_*`、`DL_*`、`FB_*`、`PROC_*`、`STATS_*`、`EXEC_PATHV_IO`) +- CLeonOS `int 0x80` syscall 0..84(含 `FD_*`、`DL_*`、`FB_*`、`PROC_*`、`STATS_*`、`EXEC_PATHV_IO`、`KERNEL_VERSION`) - TTY 输出与键盘输入队列 - rootfs 文件/目录访问(`FS_*`) - `/temp` 写入限制(`FS_MKDIR/WRITE/APPEND/REMOVE`) @@ -51,8 +51,14 @@ python wine/cleonos_wine.py build/x86_64/ramdisk_root/shell/shell.elf --rootfs b - 文件描述符(`FD_OPEN/FD_READ/FD_WRITE/FD_CLOSE/FD_DUP`) - 动态库兼容加载(`DL_OPEN/DL_CLOSE/DL_SYM`,基于 ELF 符号解析) - framebuffer 兼容(`FB_INFO/FB_BLIT/FB_CLEAR`,支持内存缓冲与窗口显示) +- 内核版本查询(`KERNEL_VERSION`) - 异常退出状态编码与故障元信息(`PROC_LAST_SIGNAL/PROC_FAULT_*`) +## 版本策略 + +- CLeonOS-Wine 版本号固定为:`85.0.0-wine` +- 该值来源于“当前实现 syscall 数量 = 85(0..84)”,按项目约定后续不再变更 + ## 参数 - `--no-kbd`:关闭输入线程 diff --git a/wine/cleonos_wine_lib/__pycache__/constants.cpython-313.pyc b/wine/cleonos_wine_lib/__pycache__/constants.cpython-313.pyc index 350f806..a8f38d4 100644 Binary files a/wine/cleonos_wine_lib/__pycache__/constants.cpython-313.pyc and b/wine/cleonos_wine_lib/__pycache__/constants.cpython-313.pyc differ diff --git a/wine/cleonos_wine_lib/__pycache__/runner.cpython-313.pyc b/wine/cleonos_wine_lib/__pycache__/runner.cpython-313.pyc index 8ef94a4..16ac5d4 100644 Binary files a/wine/cleonos_wine_lib/__pycache__/runner.cpython-313.pyc and b/wine/cleonos_wine_lib/__pycache__/runner.cpython-313.pyc differ diff --git a/wine/cleonos_wine_lib/constants.py b/wine/cleonos_wine_lib/constants.py index 5c5be38..9053c76 100644 --- a/wine/cleonos_wine_lib/constants.py +++ b/wine/cleonos_wine_lib/constants.py @@ -7,6 +7,12 @@ MAX_IO_READ = 1 << 20 DEFAULT_MAX_EXEC_DEPTH = 6 FS_NAME_MAX = 96 +CLKS_VERSION_STRING = "1.0.0-alpha" +CLEONOS_VERSION_STRING = "1.0.0-alpha" +WINE_IMPLEMENTED_SYSCALL_COUNT = 85 +# Frozen policy: this version string must not change in future updates. +CLEONOS_WINE_VERSION_STRING = "85.0.0-wine" + # CLeonOS syscall IDs from cleonos/c/include/cleonos_syscall.h SYS_LOG_WRITE = 0 SYS_TIMER_TICKS = 1 @@ -92,6 +98,7 @@ SYS_EXEC_PATHV_IO = 80 SYS_FB_INFO = 81 SYS_FB_BLIT = 82 SYS_FB_CLEAR = 83 +SYS_KERNEL_VERSION = 84 # proc states (from cleonos/c/include/cleonos_syscall.h) PROC_STATE_UNUSED = 0 diff --git a/wine/cleonos_wine_lib/runner.py b/wine/cleonos_wine_lib/runner.py index cffb1de..334e2f7 100644 --- a/wine/cleonos_wine_lib/runner.py +++ b/wine/cleonos_wine_lib/runner.py @@ -9,6 +9,7 @@ from pathlib import Path from typing import Dict, List, Optional, Tuple from .constants import ( + CLKS_VERSION_STRING, DEFAULT_MAX_EXEC_DEPTH, FD_INHERIT, FS_NAME_MAX, @@ -62,6 +63,7 @@ from .constants import ( SYS_FS_STAT_TYPE, SYS_FS_WRITE, SYS_GETPID, + SYS_KERNEL_VERSION, SYS_KBD_BUFFERED, SYS_KBD_DROPPED, SYS_KBD_GET_CHAR, @@ -713,6 +715,8 @@ class CLeonOSWineNative: return self._fb_blit(uc, arg0) if sid == SYS_FB_CLEAR: return self._fb_clear(arg0) + if sid == SYS_KERNEL_VERSION: + return self._kernel_version(uc, arg0, arg1) return u64_neg1() @@ -1889,6 +1893,23 @@ class CLeonOSWineNative: return int(u64(addr)) if addr is not None else 0 + def _kernel_version(self, uc: Uc, out_ptr: int, out_size: int) -> int: + if out_ptr == 0 or out_size <= 0: + return 0 + + max_copy = int(out_size) - 1 + if max_copy < 0: + return 0 + + payload = CLKS_VERSION_STRING.encode("utf-8", errors="replace") + if len(payload) > max_copy: + payload = payload[:max_copy] + + if not self._write_guest_bytes(uc, int(out_ptr), payload + b"\x00"): + return 0 + + return len(payload) + def _fb_info(self, uc: Uc, out_ptr: int) -> int: if out_ptr == 0: return 0