mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 10:40:00 +00:00
doom1
This commit is contained in:
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
||||
[submodule "limine"]
|
||||
path = limine
|
||||
url = https://github.com/limine-bootloader/limine.git
|
||||
url = https://github.com/limine-bootloader/limine.git
|
||||
@@ -337,6 +337,24 @@ set(USER_CFLAGS
|
||||
"-I${CMAKE_SOURCE_DIR}/cleonos/c/include"
|
||||
)
|
||||
|
||||
set(USER_CFLAGS_DOOM
|
||||
-std=c11
|
||||
-ffreestanding
|
||||
-fno-stack-protector
|
||||
-fno-builtin
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-error
|
||||
-Wno-unused-parameter
|
||||
-Wno-missing-field-initializers
|
||||
-Wno-sign-compare
|
||||
-D_DEFAULT_SOURCE
|
||||
-D_POSIX_C_SOURCE=200809L
|
||||
"-I${CMAKE_SOURCE_DIR}/cleonos/third-party/doomgeneric/doomgeneric"
|
||||
"-include"
|
||||
"${CMAKE_SOURCE_DIR}/cleonos/c/apps/doom/doom_shim.h"
|
||||
)
|
||||
|
||||
set(USER_LDFLAGS
|
||||
-nostdlib
|
||||
-z
|
||||
@@ -494,6 +512,23 @@ function(add_user_c_object SRC OUTPUT_VAR)
|
||||
set(${OUTPUT_VAR} "${OBJ_PATH}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(add_user_c_object_doom SRC OUTPUT_VAR)
|
||||
string(REGEX REPLACE "\\.c$" ".o" OBJ_REL "${SRC}")
|
||||
set(OBJ_PATH "${USER_OBJ_ROOT}/${OBJ_REL}")
|
||||
get_filename_component(OBJ_DIR "${OBJ_PATH}" DIRECTORY)
|
||||
set(_deps "${CMAKE_SOURCE_DIR}/${SRC}" ${USER_INC_SOURCES_ABS} ${DOOMGENERIC_DEP_SOURCES_ABS})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${OBJ_PATH}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${OBJ_DIR}"
|
||||
COMMAND ${USER_CC} ${USER_CFLAGS_DOOM} -c "${CMAKE_SOURCE_DIR}/${SRC}" -o "${OBJ_PATH}"
|
||||
DEPENDS ${_deps}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(${OUTPUT_VAR} "${OBJ_PATH}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
set(KERNEL_OBJECTS)
|
||||
foreach(SRC IN LISTS C_SOURCES)
|
||||
add_kernel_c_object("${SRC}" KERNEL_OBJECTS)
|
||||
@@ -565,6 +600,25 @@ set(RAMDISK_DRIVER_APPS)
|
||||
set(RAMDISK_SYSTEM_APPS)
|
||||
set(RAMDISK_ROOT_APPS)
|
||||
|
||||
set(DOOMGENERIC_DIR "${CMAKE_SOURCE_DIR}/cleonos/third-party/doomgeneric/doomgeneric")
|
||||
set(DOOMGENERIC_SRC_BASENAMES
|
||||
dummy am_map doomdef doomstat dstrings d_event d_items d_iwad d_loop d_main d_mode d_net f_finale f_wipe
|
||||
g_game hu_lib hu_stuff info i_cdmus i_endoom i_joystick i_scale i_sound i_system i_timer memio m_argv
|
||||
m_bbox m_cheat m_config m_controls m_fixed m_menu m_misc m_random p_ceilng p_doors p_enemy p_floor
|
||||
p_inter p_lights p_map p_maputl p_mobj p_plats p_pspr p_saveg p_setup p_sight p_spec p_switch p_telept
|
||||
p_tick p_user r_bsp r_data r_draw r_main r_plane r_segs r_sky r_things sha1 sounds statdump st_lib st_stuff
|
||||
s_sound tables v_video wi_stuff w_checksum w_file w_main w_wad z_zone w_file_stdc i_input i_video doomgeneric
|
||||
)
|
||||
set(DOOMGENERIC_APP_SOURCES)
|
||||
foreach(_base IN LISTS DOOMGENERIC_SRC_BASENAMES)
|
||||
list(APPEND DOOMGENERIC_APP_SOURCES "cleonos/third-party/doomgeneric/doomgeneric/${_base}.c")
|
||||
endforeach()
|
||||
file(GLOB_RECURSE DOOMGENERIC_DEP_SOURCES_ABS CONFIGURE_DEPENDS
|
||||
"${CMAKE_SOURCE_DIR}/cleonos/third-party/doomgeneric/doomgeneric/*.h"
|
||||
"${CMAKE_SOURCE_DIR}/cleonos/c/apps/doom/*.h"
|
||||
)
|
||||
list(SORT DOOMGENERIC_DEP_SOURCES_ABS)
|
||||
|
||||
set(USER_SHELL_COMMAND_APPS
|
||||
help args ls cat grep head tail wc cut uniq sort pwd cd exec pid spawn wait sleep yield
|
||||
bg fg jobs kill ps top
|
||||
@@ -610,6 +664,13 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
|
||||
"${CMAKE_SOURCE_DIR}/cleonos/c/apps/${_app_name}_*.c"
|
||||
"${CMAKE_SOURCE_DIR}/cleonos/c/apps/${_app_name}/*.c"
|
||||
)
|
||||
set(_app_common_objects ${USER_COMMON_OBJECTS})
|
||||
|
||||
if(_app_name STREQUAL "doom")
|
||||
foreach(_doom_src IN LISTS DOOMGENERIC_APP_SOURCES)
|
||||
list(APPEND _app_specific_abs "${CMAKE_SOURCE_DIR}/${_doom_src}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
list(FIND USER_SHELL_COMMAND_APPS "${_app_name}" _shell_cmd_idx)
|
||||
if(NOT _shell_cmd_idx EQUAL -1)
|
||||
@@ -626,7 +687,11 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
add_user_c_object("${_extra_rel}" _extra_obj)
|
||||
if(_app_name STREQUAL "doom")
|
||||
add_user_c_object_doom("${_extra_rel}" _extra_obj)
|
||||
else()
|
||||
add_user_c_object("${_extra_rel}" _extra_obj)
|
||||
endif()
|
||||
list(APPEND _app_specific_objs "${_extra_obj}")
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES _app_specific_objs)
|
||||
@@ -635,8 +700,8 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
|
||||
add_custom_command(
|
||||
OUTPUT "${_app_out}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${USER_APP_DIR}"
|
||||
COMMAND ${USER_LD} ${USER_LDFLAGS} -o "${_app_out}" ${USER_COMMON_OBJECTS} "${_user_obj}" ${_app_specific_objs} "${USER_RUST_LIB}"
|
||||
DEPENDS ${USER_COMMON_OBJECTS} "${_user_obj}" ${_app_specific_objs} "${USER_RUST_LIB}" "${USER_LINKER_SCRIPT}"
|
||||
COMMAND ${USER_LD} ${USER_LDFLAGS} -o "${_app_out}" ${_app_common_objects} "${_user_obj}" ${_app_specific_objs} "${USER_RUST_LIB}"
|
||||
DEPENDS ${_app_common_objects} "${_user_obj}" ${_app_specific_objs} "${USER_RUST_LIB}" "${USER_LINKER_SCRIPT}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
|
||||
1340
cleonos/c/apps/doom/doom_compat.c
Normal file
1340
cleonos/c/apps/doom/doom_compat.c
Normal file
File diff suppressed because it is too large
Load Diff
21
cleonos/c/apps/doom/doom_shim.h
Normal file
21
cleonos/c/apps/doom/doom_shim.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef CLEONOS_DOOM_SHIM_H
|
||||
#define CLEONOS_DOOM_SHIM_H
|
||||
|
||||
/* Redirect stdio-family APIs that clash with cleonos/c/src/stdio.c signatures. */
|
||||
#define fopen dg_fopen
|
||||
#define fclose dg_fclose
|
||||
#define fread dg_fread
|
||||
#define fwrite dg_fwrite
|
||||
#define fseek dg_fseek
|
||||
#define ftell dg_ftell
|
||||
#define fflush dg_fflush
|
||||
#define fgets dg_fgets
|
||||
#define fprintf dg_fprintf
|
||||
#define vfprintf dg_vfprintf
|
||||
#define feof dg_feof
|
||||
#define fileno dg_fileno
|
||||
#define perror dg_perror
|
||||
#define sscanf dg_sscanf
|
||||
|
||||
#endif
|
||||
|
||||
197
cleonos/c/apps/doom/doomgeneric_clks.c
Normal file
197
cleonos/c/apps/doom/doomgeneric_clks.c
Normal file
@@ -0,0 +1,197 @@
|
||||
#include "doomgeneric.h"
|
||||
#include "doomkeys.h"
|
||||
|
||||
#include "../../include/cleonos_syscall.h"
|
||||
|
||||
#define CLEONOS_KEY_LEFT 0x01U
|
||||
#define CLEONOS_KEY_RIGHT 0x02U
|
||||
#define CLEONOS_KEY_UP 0x03U
|
||||
#define CLEONOS_KEY_DOWN 0x04U
|
||||
|
||||
#define DG_KEY_QUEUE_CAP 256U
|
||||
|
||||
struct dg_key_event {
|
||||
int pressed;
|
||||
unsigned char key;
|
||||
};
|
||||
|
||||
static struct dg_key_event g_key_queue[DG_KEY_QUEUE_CAP];
|
||||
static u64 g_key_r = 0ULL;
|
||||
static u64 g_key_w = 0ULL;
|
||||
|
||||
static cleonos_fb_info g_fb_info;
|
||||
static cleonos_fb_blit_req g_blit_req;
|
||||
static u64 g_scale = 1ULL;
|
||||
static u64 g_dst_x = 0ULL;
|
||||
static u64 g_dst_y = 0ULL;
|
||||
|
||||
static void dg_push_key(int pressed, unsigned char key) {
|
||||
u64 next = (g_key_w + 1ULL) % DG_KEY_QUEUE_CAP;
|
||||
|
||||
if (next == g_key_r) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_key_queue[g_key_w].pressed = pressed;
|
||||
g_key_queue[g_key_w].key = key;
|
||||
g_key_w = next;
|
||||
}
|
||||
|
||||
static int dg_pop_key(int *pressed, unsigned char *key) {
|
||||
if (g_key_r == g_key_w || pressed == (int *)0 || key == (unsigned char *)0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pressed = g_key_queue[g_key_r].pressed;
|
||||
*key = g_key_queue[g_key_r].key;
|
||||
g_key_r = (g_key_r + 1ULL) % DG_KEY_QUEUE_CAP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned char dg_translate_key(u64 code) {
|
||||
if (code == (u64)CLEONOS_KEY_LEFT) {
|
||||
return KEY_LEFTARROW;
|
||||
}
|
||||
|
||||
if (code == (u64)CLEONOS_KEY_RIGHT) {
|
||||
return KEY_RIGHTARROW;
|
||||
}
|
||||
|
||||
if (code == (u64)CLEONOS_KEY_UP) {
|
||||
return KEY_UPARROW;
|
||||
}
|
||||
|
||||
if (code == (u64)CLEONOS_KEY_DOWN) {
|
||||
return KEY_DOWNARROW;
|
||||
}
|
||||
|
||||
if (code == (u64)'\r' || code == (u64)'\n') {
|
||||
return KEY_ENTER;
|
||||
}
|
||||
|
||||
if (code == (u64)8U || code == (u64)127U) {
|
||||
return KEY_BACKSPACE;
|
||||
}
|
||||
|
||||
if (code == (u64)27U) {
|
||||
return KEY_ESCAPE;
|
||||
}
|
||||
|
||||
if (code == (u64)'\t') {
|
||||
return KEY_TAB;
|
||||
}
|
||||
|
||||
if (code >= 32ULL && code <= 126ULL) {
|
||||
return (unsigned char)(code & 0xFFULL);
|
||||
}
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
static void dg_poll_keyboard(void) {
|
||||
for (;;) {
|
||||
u64 code = cleonos_sys_kbd_get_char();
|
||||
unsigned char key;
|
||||
|
||||
if (code == (u64)-1) {
|
||||
break;
|
||||
}
|
||||
|
||||
key = dg_translate_key(code);
|
||||
|
||||
if (key == 0U) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dg_push_key(1, key);
|
||||
dg_push_key(0, key);
|
||||
}
|
||||
}
|
||||
|
||||
void DG_Init(void) {
|
||||
u64 sx;
|
||||
u64 sy;
|
||||
|
||||
g_key_r = 0ULL;
|
||||
g_key_w = 0ULL;
|
||||
|
||||
g_fb_info.width = 0ULL;
|
||||
g_fb_info.height = 0ULL;
|
||||
g_fb_info.pitch = 0ULL;
|
||||
g_fb_info.bpp = 0ULL;
|
||||
|
||||
if (cleonos_sys_fb_info(&g_fb_info) == 0ULL || g_fb_info.width == 0ULL || g_fb_info.height == 0ULL ||
|
||||
g_fb_info.bpp != 32ULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sx = g_fb_info.width / (u64)DOOMGENERIC_RESX;
|
||||
sy = g_fb_info.height / (u64)DOOMGENERIC_RESY;
|
||||
g_scale = (sx < sy) ? sx : sy;
|
||||
|
||||
if (g_scale == 0ULL) {
|
||||
g_scale = 1ULL;
|
||||
}
|
||||
|
||||
if (g_scale > 4ULL) {
|
||||
g_scale = 4ULL;
|
||||
}
|
||||
|
||||
g_dst_x = (g_fb_info.width > ((u64)DOOMGENERIC_RESX * g_scale)) ? ((g_fb_info.width - ((u64)DOOMGENERIC_RESX * g_scale)) / 2ULL) : 0ULL;
|
||||
g_dst_y = (g_fb_info.height > ((u64)DOOMGENERIC_RESY * g_scale)) ? ((g_fb_info.height - ((u64)DOOMGENERIC_RESY * g_scale)) / 2ULL) : 0ULL;
|
||||
|
||||
g_blit_req.pixels_ptr = 0ULL;
|
||||
g_blit_req.src_width = (u64)DOOMGENERIC_RESX;
|
||||
g_blit_req.src_height = (u64)DOOMGENERIC_RESY;
|
||||
g_blit_req.src_pitch_bytes = (u64)DOOMGENERIC_RESX * 4ULL;
|
||||
g_blit_req.dst_x = g_dst_x;
|
||||
g_blit_req.dst_y = g_dst_y;
|
||||
g_blit_req.scale = g_scale;
|
||||
|
||||
(void)cleonos_sys_fb_clear(0x00000000ULL);
|
||||
}
|
||||
|
||||
void DG_DrawFrame(void) {
|
||||
dg_poll_keyboard();
|
||||
|
||||
if (g_fb_info.width == 0ULL || g_fb_info.height == 0ULL || DG_ScreenBuffer == (pixel_t *)0) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_blit_req.pixels_ptr = (u64)(void *)DG_ScreenBuffer;
|
||||
(void)cleonos_sys_fb_blit(&g_blit_req);
|
||||
}
|
||||
|
||||
void DG_SleepMs(uint32_t ms) {
|
||||
u64 ticks = ((u64)ms + 9ULL) / 10ULL;
|
||||
|
||||
if (ticks == 0ULL && ms != 0U) {
|
||||
ticks = 1ULL;
|
||||
}
|
||||
|
||||
if (ticks > 0ULL) {
|
||||
(void)cleonos_sys_sleep_ticks(ticks);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t DG_GetTicksMs(void) {
|
||||
return (uint32_t)(cleonos_sys_timer_ticks() * 10ULL);
|
||||
}
|
||||
|
||||
int DG_GetKey(int *pressed, unsigned char *key) {
|
||||
dg_poll_keyboard();
|
||||
return dg_pop_key(pressed, key);
|
||||
}
|
||||
|
||||
void DG_SetWindowTitle(const char *title) {
|
||||
(void)title;
|
||||
}
|
||||
|
||||
int cl_doom_run_main(int argc, char **argv) {
|
||||
doomgeneric_Create(argc, argv);
|
||||
|
||||
for (;;) {
|
||||
doomgeneric_Tick();
|
||||
}
|
||||
}
|
||||
|
||||
87
cleonos/c/apps/doom_main.c
Normal file
87
cleonos/c/apps/doom_main.c
Normal file
@@ -0,0 +1,87 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cleonos_syscall.h>
|
||||
|
||||
int cl_doom_run_main(int argc, char **argv);
|
||||
|
||||
static const char *cl_doom_pick_default_wad(void) {
|
||||
static const char *candidates[] = {
|
||||
"/doom1.wad",
|
||||
"/DOOM1.WAD",
|
||||
"/temp/doom1.wad",
|
||||
"/temp/DOOM1.WAD",
|
||||
"/shell/doom1.wad",
|
||||
"/shell/DOOM1.WAD",
|
||||
};
|
||||
u64 i;
|
||||
|
||||
for (i = 0ULL; i < (u64)(sizeof(candidates) / sizeof(candidates[0])); i++) {
|
||||
if (cleonos_sys_fs_stat_size(candidates[i]) != (u64)-1) {
|
||||
return candidates[i];
|
||||
}
|
||||
}
|
||||
|
||||
return (const char *)0;
|
||||
}
|
||||
|
||||
int cleonos_app_main(int argc, char **argv, char **envp) {
|
||||
char *run_argv[32];
|
||||
int run_argc = 0;
|
||||
int i;
|
||||
const char *auto_wad = (const char *)0;
|
||||
int has_iwad = 0;
|
||||
|
||||
(void)envp;
|
||||
|
||||
if (argc <= 0 || argv == (char **)0 || argv[0] == (char *)0) {
|
||||
(void)printf("doom: invalid argv\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (argv[i] != (char *)0 && strcmp(argv[i], "-iwad") == 0) {
|
||||
has_iwad = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
run_argv[run_argc++] = argv[0];
|
||||
|
||||
if (has_iwad == 0) {
|
||||
if (argc > 1 && argv[1] != (char *)0 && argv[1][0] != '-') {
|
||||
run_argv[run_argc++] = "-iwad";
|
||||
run_argv[run_argc++] = argv[1];
|
||||
for (i = 2; i < argc && run_argc + 1 < (int)(sizeof(run_argv) / sizeof(run_argv[0])); i++) {
|
||||
run_argv[run_argc++] = argv[i];
|
||||
}
|
||||
} else {
|
||||
auto_wad = cl_doom_pick_default_wad();
|
||||
if (auto_wad != (const char *)0) {
|
||||
run_argv[run_argc++] = "-iwad";
|
||||
run_argv[run_argc++] = (char *)auto_wad;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc && run_argc + 1 < (int)(sizeof(run_argv) / sizeof(run_argv[0])); i++) {
|
||||
run_argv[run_argc++] = argv[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 1; i < argc && run_argc + 1 < (int)(sizeof(run_argv) / sizeof(run_argv[0])); i++) {
|
||||
run_argv[run_argc++] = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
run_argv[run_argc] = (char *)0;
|
||||
|
||||
if (has_iwad == 0 && auto_wad == (const char *)0 && (argc <= 1 || argv[1] == (char *)0 || argv[1][0] == '-')) {
|
||||
(void)printf("doom: no WAD provided\n");
|
||||
(void)printf("doom: usage: doom /doom1.wad\n");
|
||||
(void)printf("doom: or: doom -iwad /doom1.wad\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
(void)printf("doom: launching doomgeneric\n");
|
||||
return cl_doom_run_main(run_argc, run_argv);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ static int ush_cmd_help(void) {
|
||||
ush_writeln(" ansi / ansitest / color");
|
||||
ush_writeln(" wavplay <file.wav> [steps] [ticks] / wavplay --stop");
|
||||
ush_writeln(" fastfetch [--plain]");
|
||||
ush_writeln(" doom [wad_path] (framebuffer bootstrap renderer)");
|
||||
ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats");
|
||||
ush_writeln(" tty [index]");
|
||||
ush_writeln(" dmesg [n]");
|
||||
|
||||
@@ -137,6 +137,7 @@ static int ush_cmd_help(void) {
|
||||
ush_writeln(" ansi / ansitest / color");
|
||||
ush_writeln(" wavplay <file.wav> [steps] [ticks] / wavplay --stop");
|
||||
ush_writeln(" fastfetch [--plain]");
|
||||
ush_writeln(" doom [wad_path] (framebuffer bootstrap renderer)");
|
||||
ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats");
|
||||
ush_writeln(" tty [index]");
|
||||
ush_writeln(" dmesg [n]");
|
||||
|
||||
@@ -43,6 +43,23 @@ typedef struct cleonos_proc_snapshot {
|
||||
char path[CLEONOS_PROC_PATH_MAX];
|
||||
} cleonos_proc_snapshot;
|
||||
|
||||
typedef struct cleonos_fb_info {
|
||||
u64 width;
|
||||
u64 height;
|
||||
u64 pitch;
|
||||
u64 bpp;
|
||||
} cleonos_fb_info;
|
||||
|
||||
typedef struct cleonos_fb_blit_req {
|
||||
u64 pixels_ptr;
|
||||
u64 src_width;
|
||||
u64 src_height;
|
||||
u64 src_pitch_bytes;
|
||||
u64 dst_x;
|
||||
u64 dst_y;
|
||||
u64 scale;
|
||||
} cleonos_fb_blit_req;
|
||||
|
||||
#define CLEONOS_SYSCALL_LOG_WRITE 0ULL
|
||||
#define CLEONOS_SYSCALL_TIMER_TICKS 1ULL
|
||||
#define CLEONOS_SYSCALL_TASK_COUNT 2ULL
|
||||
@@ -124,6 +141,9 @@ typedef struct cleonos_proc_snapshot {
|
||||
#define CLEONOS_SYSCALL_DL_CLOSE 78ULL
|
||||
#define CLEONOS_SYSCALL_DL_SYM 79ULL
|
||||
#define CLEONOS_SYSCALL_EXEC_PATHV_IO 80ULL
|
||||
#define CLEONOS_SYSCALL_FB_INFO 81ULL
|
||||
#define CLEONOS_SYSCALL_FB_BLIT 82ULL
|
||||
#define CLEONOS_SYSCALL_FB_CLEAR 83ULL
|
||||
|
||||
u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
u64 cleonos_sys_log_write(const char *message, u64 length);
|
||||
@@ -207,5 +227,8 @@ u64 cleonos_sys_fd_dup(u64 fd);
|
||||
u64 cleonos_sys_dl_open(const char *path);
|
||||
u64 cleonos_sys_dl_close(u64 handle);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -355,3 +355,15 @@ u64 cleonos_sys_dl_close(u64 handle) {
|
||||
u64 cleonos_sys_dl_sym(u64 handle, const char *symbol) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_DL_SYM, handle, (u64)symbol, 0ULL);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_fb_info(cleonos_fb_info *out_info) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_FB_INFO, (u64)out_info, 0ULL, 0ULL);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_fb_blit(const cleonos_fb_blit_req *req) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_FB_BLIT, (u64)req, 0ULL, 0ULL);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_fb_clear(u64 rgb) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_FB_CLEAR, rgb, 0ULL, 0ULL);
|
||||
}
|
||||
|
||||
1
cleonos/third-party/doomgeneric
vendored
Submodule
1
cleonos/third-party/doomgeneric
vendored
Submodule
Submodule cleonos/third-party/doomgeneric added at dcb7a8dbc7
@@ -74,5 +74,7 @@ u64 clks_exec_request_count(void);
|
||||
u64 clks_exec_success_count(void);
|
||||
clks_bool clks_exec_is_running(void);
|
||||
clks_bool clks_exec_current_path_is_user(void);
|
||||
clks_bool clks_exec_current_user_ptr_readable(u64 addr, u64 size);
|
||||
clks_bool clks_exec_current_user_ptr_writable(u64 addr, u64 size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -84,6 +84,9 @@
|
||||
#define CLKS_SYSCALL_DL_CLOSE 78ULL
|
||||
#define CLKS_SYSCALL_DL_SYM 79ULL
|
||||
#define CLKS_SYSCALL_EXEC_PATHV_IO 80ULL
|
||||
#define CLKS_SYSCALL_FB_INFO 81ULL
|
||||
#define CLKS_SYSCALL_FB_BLIT 82ULL
|
||||
#define CLKS_SYSCALL_FB_CLEAR 83ULL
|
||||
|
||||
void clks_syscall_init(void);
|
||||
u64 clks_syscall_dispatch(void *frame_ptr);
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
#include <clks/string.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
#define CLKS_HEAP_ARENA_SIZE (1024ULL * 1024ULL)
|
||||
#ifndef CLKS_CFG_HEAP_ARENA_SIZE
|
||||
#define CLKS_CFG_HEAP_ARENA_SIZE (64ULL * 1024ULL * 1024ULL)
|
||||
#endif
|
||||
|
||||
#define CLKS_HEAP_ARENA_SIZE CLKS_CFG_HEAP_ARENA_SIZE
|
||||
#define CLKS_HEAP_ALIGN 16ULL
|
||||
#define CLKS_HEAP_MAGIC 0x434C454F4E4F534FULL
|
||||
|
||||
@@ -173,4 +177,4 @@ struct clks_heap_stats clks_heap_get_stats(void) {
|
||||
stats.free_count = clks_heap_free_count;
|
||||
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <clks/elf64.h>
|
||||
#include <clks/heap.h>
|
||||
#include <clks/log.h>
|
||||
#include <clks/string.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
@@ -230,6 +231,10 @@ clks_bool clks_elf64_load(const void *image, u64 size, struct clks_elf64_loaded_
|
||||
|
||||
image_base = clks_kmalloc((usize)span);
|
||||
if (image_base == CLKS_NULL) {
|
||||
clks_log(CLKS_LOG_WARN, "ELF", "LOAD ALLOC FAILED");
|
||||
clks_log_hex(CLKS_LOG_WARN, "ELF", "SPAN", span);
|
||||
clks_log_hex(CLKS_LOG_WARN, "ELF", "MIN_VADDR", min_vaddr);
|
||||
clks_log_hex(CLKS_LOG_WARN, "ELF", "MAX_VADDR_END", max_vaddr_end);
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,6 +178,8 @@ static u64 clks_exec_unwind_slot_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static clks_bool clks_exec_unwind_slot_valid_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u64 clks_exec_image_begin_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u64 clks_exec_image_end_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u64 clks_exec_stack_begin_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u64 clks_exec_stack_end_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u32 clks_exec_pid_stack_depth = 0U;
|
||||
static struct clks_exec_dynlib_slot clks_exec_dynlib_table[CLKS_EXEC_DYNLIB_MAX];
|
||||
static u64 clks_exec_next_dynlib_handle = 1ULL;
|
||||
@@ -362,6 +364,26 @@ static clks_bool clks_exec_range_ok(u64 off, u64 len, u64 total) {
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_addr_range_in_window(u64 addr, u64 size, u64 begin, u64 end) {
|
||||
if (begin == 0ULL || end <= begin) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (size == 0ULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (addr < begin || addr >= end) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (size > (end - addr)) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
static i32 clks_exec_dynlib_alloc_slot(void) {
|
||||
u32 i;
|
||||
|
||||
@@ -1179,6 +1201,8 @@ static clks_bool clks_exec_invoke_entry(void *entry_ptr, u32 depth_index, u64 *o
|
||||
}
|
||||
|
||||
stack_top = (void *)((u8 *)stack_base + (usize)CLKS_EXEC_RUN_STACK_BYTES);
|
||||
clks_exec_stack_begin_stack[depth_index] = (u64)stack_base;
|
||||
clks_exec_stack_end_stack[depth_index] = (u64)stack_top;
|
||||
unwind_slot = (((u64)stack_top) & ~0xFULL) - CLKS_EXEC_UNWIND_CTX_BYTES;
|
||||
clks_exec_unwind_slot_stack[depth_index] = unwind_slot;
|
||||
clks_exec_unwind_slot_valid_stack[depth_index] = CLKS_TRUE;
|
||||
@@ -1192,6 +1216,8 @@ static clks_bool clks_exec_invoke_entry(void *entry_ptr, u32 depth_index, u64 *o
|
||||
/* Close unwind window immediately after call returns to avoid IRQ race. */
|
||||
clks_exec_unwind_slot_valid_stack[depth_index] = CLKS_FALSE;
|
||||
clks_exec_unwind_slot_stack[depth_index] = 0ULL;
|
||||
clks_exec_stack_begin_stack[depth_index] = 0ULL;
|
||||
clks_exec_stack_end_stack[depth_index] = 0ULL;
|
||||
|
||||
clks_exec_restore_interrupt_window(restore_irq_disable);
|
||||
*out_ret = call_ret;
|
||||
@@ -1254,6 +1280,8 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
|
||||
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
|
||||
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_stack_begin_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_stack_end_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_pid_stack_depth++;
|
||||
depth_pushed = CLKS_TRUE;
|
||||
|
||||
@@ -1348,6 +1376,8 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
|
||||
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
|
||||
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_stack_begin_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_stack_end_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_pid_stack_depth--;
|
||||
depth_pushed = CLKS_FALSE;
|
||||
}
|
||||
@@ -1374,6 +1404,8 @@ fail:
|
||||
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
|
||||
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_stack_begin_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_stack_end_stack[(u32)depth_index] = 0ULL;
|
||||
clks_exec_pid_stack_depth--;
|
||||
}
|
||||
|
||||
@@ -1484,6 +1516,8 @@ void clks_exec_init(void) {
|
||||
clks_memset(clks_exec_unwind_slot_valid_stack, 0, sizeof(clks_exec_unwind_slot_valid_stack));
|
||||
clks_memset(clks_exec_image_begin_stack, 0, sizeof(clks_exec_image_begin_stack));
|
||||
clks_memset(clks_exec_image_end_stack, 0, sizeof(clks_exec_image_end_stack));
|
||||
clks_memset(clks_exec_stack_begin_stack, 0, sizeof(clks_exec_stack_begin_stack));
|
||||
clks_memset(clks_exec_stack_end_stack, 0, sizeof(clks_exec_stack_end_stack));
|
||||
clks_memset(clks_exec_proc_table, 0, sizeof(clks_exec_proc_table));
|
||||
clks_memset(clks_exec_dynlib_table, 0, sizeof(clks_exec_dynlib_table));
|
||||
clks_exec_next_dynlib_handle = 1ULL;
|
||||
@@ -2526,3 +2560,39 @@ clks_bool clks_exec_current_path_is_user(void) {
|
||||
proc = &clks_exec_proc_table[(u32)slot];
|
||||
return clks_exec_path_is_user_program(proc->path);
|
||||
}
|
||||
|
||||
clks_bool clks_exec_current_user_ptr_readable(u64 addr, u64 size) {
|
||||
i32 depth_index;
|
||||
u64 image_begin;
|
||||
u64 image_end;
|
||||
u64 stack_begin;
|
||||
u64 stack_end;
|
||||
|
||||
if (clks_exec_is_running() == CLKS_FALSE || clks_exec_current_path_is_user() == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (size == 0ULL || clks_exec_pid_stack_depth == 0U) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
depth_index = (i32)(clks_exec_pid_stack_depth - 1U);
|
||||
image_begin = clks_exec_image_begin_stack[(u32)depth_index];
|
||||
image_end = clks_exec_image_end_stack[(u32)depth_index];
|
||||
stack_begin = clks_exec_stack_begin_stack[(u32)depth_index];
|
||||
stack_end = clks_exec_stack_end_stack[(u32)depth_index];
|
||||
|
||||
if (clks_exec_addr_range_in_window(addr, size, image_begin, image_end) == CLKS_TRUE) {
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
if (clks_exec_addr_range_in_window(addr, size, stack_begin, stack_end) == CLKS_TRUE) {
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
clks_bool clks_exec_current_user_ptr_writable(u64 addr, u64 size) {
|
||||
return clks_exec_current_user_ptr_readable(addr, size);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <clks/cpu.h>
|
||||
#include <clks/audio.h>
|
||||
#include <clks/exec.h>
|
||||
#include <clks/framebuffer.h>
|
||||
#include <clks/fs.h>
|
||||
#include <clks/heap.h>
|
||||
#include <clks/interrupts.h>
|
||||
@@ -32,7 +33,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_EXEC_PATHV_IO
|
||||
#define CLKS_SYSCALL_STATS_MAX_ID CLKS_SYSCALL_FB_CLEAR
|
||||
#define CLKS_SYSCALL_STATS_RING_SIZE 256U
|
||||
#define CLKS_SYSCALL_USC_MAX_ALLOWED_APPS 64U
|
||||
|
||||
@@ -131,6 +132,23 @@ struct clks_syscall_exec_io_req {
|
||||
u64 stderr_fd;
|
||||
};
|
||||
|
||||
struct clks_syscall_fb_info_user {
|
||||
u64 width;
|
||||
u64 height;
|
||||
u64 pitch;
|
||||
u64 bpp;
|
||||
};
|
||||
|
||||
struct clks_syscall_fb_blit_req {
|
||||
u64 pixels_ptr;
|
||||
u64 src_width;
|
||||
u64 src_height;
|
||||
u64 src_pitch_bytes;
|
||||
u64 dst_x;
|
||||
u64 dst_y;
|
||||
u64 scale;
|
||||
};
|
||||
|
||||
static clks_bool clks_syscall_ready = CLKS_FALSE;
|
||||
static clks_bool clks_syscall_user_trace_active = CLKS_FALSE;
|
||||
static u64 clks_syscall_user_trace_budget = 0ULL;
|
||||
@@ -160,16 +178,55 @@ static inline void clks_syscall_outw(u16 port, u16 value) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static clks_bool clks_syscall_in_user_exec_context(void) {
|
||||
return (clks_exec_is_running() == CLKS_TRUE && clks_exec_current_path_is_user() == CLKS_TRUE) ? CLKS_TRUE
|
||||
: CLKS_FALSE;
|
||||
}
|
||||
|
||||
static clks_bool clks_syscall_user_ptr_readable(u64 addr, u64 size) {
|
||||
if (addr == 0ULL || size == 0ULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (clks_syscall_in_user_exec_context() == CLKS_FALSE) {
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
return clks_exec_current_user_ptr_readable(addr, size);
|
||||
}
|
||||
|
||||
static clks_bool clks_syscall_user_ptr_writable(u64 addr, u64 size) {
|
||||
if (addr == 0ULL || size == 0ULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (clks_syscall_in_user_exec_context() == CLKS_FALSE) {
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
return clks_exec_current_user_ptr_writable(addr, size);
|
||||
}
|
||||
|
||||
static clks_bool clks_syscall_copy_user_string(u64 src_addr, char *dst, usize dst_size) {
|
||||
const char *src = (const char *)src_addr;
|
||||
usize i = 0U;
|
||||
|
||||
if (src == CLKS_NULL || dst == CLKS_NULL || dst_size == 0U) {
|
||||
if (src_addr == 0ULL || dst == CLKS_NULL || dst_size == 0U) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
while (i + 1U < dst_size) {
|
||||
char ch = src[i];
|
||||
u64 char_addr = src_addr + (u64)i;
|
||||
char ch;
|
||||
|
||||
if (char_addr < src_addr) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_readable(char_addr, 1ULL) == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
ch = *(const char *)(usize)char_addr;
|
||||
dst[i] = ch;
|
||||
|
||||
if (ch == '\0') {
|
||||
@@ -209,6 +266,10 @@ static u64 clks_syscall_copy_text_to_user(u64 dst_addr, u64 dst_size, const char
|
||||
copy_len = (usize)dst_size - 1U;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_writable(dst_addr, (u64)copy_len + 1ULL) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
clks_memcpy((void *)dst_addr, src, copy_len);
|
||||
((char *)dst_addr)[copy_len] = '\0';
|
||||
return (u64)copy_len;
|
||||
@@ -228,6 +289,10 @@ static u64 clks_syscall_log_write(u64 arg0, u64 arg1) {
|
||||
len = CLKS_SYSCALL_LOG_MAX_LEN;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_readable((u64)(usize)src, len) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
for (i = 0ULL; i < len; i++) {
|
||||
buf[i] = src[i];
|
||||
}
|
||||
@@ -252,6 +317,10 @@ static u64 clks_syscall_tty_write(u64 arg0, u64 arg1) {
|
||||
len = CLKS_SYSCALL_TTY_MAX_LEN;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_readable((u64)(usize)src, len) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
for (i = 0ULL; i < len; i++) {
|
||||
buf[i] = src[i];
|
||||
}
|
||||
@@ -277,6 +346,127 @@ static u64 clks_syscall_kbd_get_char(void) {
|
||||
return (u64)(u8)ch;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_fb_info(u64 arg0) {
|
||||
struct clks_syscall_fb_info_user *out_info = (struct clks_syscall_fb_info_user *)arg0;
|
||||
struct clks_framebuffer_info fb_info;
|
||||
|
||||
if (arg0 == 0ULL || clks_fb_ready() == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_writable(arg0, (u64)sizeof(*out_info)) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
fb_info = clks_fb_info();
|
||||
out_info->width = (u64)fb_info.width;
|
||||
out_info->height = (u64)fb_info.height;
|
||||
out_info->pitch = (u64)fb_info.pitch;
|
||||
out_info->bpp = (u64)fb_info.bpp;
|
||||
return 1ULL;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_fb_clear(u64 arg0) {
|
||||
if (clks_fb_ready() == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
clks_fb_clear((u32)(arg0 & 0xFFFFFFFFULL));
|
||||
return 1ULL;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_fb_blit(u64 arg0) {
|
||||
struct clks_syscall_fb_blit_req req;
|
||||
const u8 *src_base;
|
||||
struct clks_framebuffer_info fb_info;
|
||||
u64 src_width;
|
||||
u64 src_height;
|
||||
u64 src_pitch_bytes;
|
||||
u64 dst_x;
|
||||
u64 dst_y;
|
||||
u64 scale;
|
||||
u64 y;
|
||||
u64 x;
|
||||
|
||||
if (arg0 == 0ULL || clks_fb_ready() == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_readable(arg0, (u64)sizeof(req)) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
clks_memcpy(&req, (const void *)(usize)arg0, sizeof(req));
|
||||
|
||||
if (req.pixels_ptr == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
src_width = req.src_width;
|
||||
src_height = req.src_height;
|
||||
src_pitch_bytes = req.src_pitch_bytes;
|
||||
dst_x = req.dst_x;
|
||||
dst_y = req.dst_y;
|
||||
scale = req.scale;
|
||||
|
||||
if (src_width == 0ULL || src_height == 0ULL || scale == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (src_width > 4096ULL || src_height > 4096ULL || scale > 8ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (src_pitch_bytes == 0ULL) {
|
||||
src_pitch_bytes = src_width * 4ULL;
|
||||
}
|
||||
|
||||
if (src_pitch_bytes < (src_width * 4ULL)) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (src_pitch_bytes != 0ULL && src_height > (((u64)-1) / src_pitch_bytes)) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_readable(req.pixels_ptr, src_pitch_bytes * src_height) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
src_base = (const u8 *)(usize)req.pixels_ptr;
|
||||
fb_info = clks_fb_info();
|
||||
|
||||
if (dst_x >= (u64)fb_info.width || dst_y >= (u64)fb_info.height) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
for (y = 0ULL; y < src_height; y++) {
|
||||
const u32 *src_row = (const u32 *)(const void *)(src_base + (usize)(y * src_pitch_bytes));
|
||||
u64 draw_y = dst_y + (y * scale);
|
||||
|
||||
if (draw_y >= (u64)fb_info.height) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (x = 0ULL; x < src_width; x++) {
|
||||
u32 color = src_row[x];
|
||||
u64 draw_x = dst_x + (x * scale);
|
||||
|
||||
if (draw_x >= (u64)fb_info.width) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (scale == 1ULL) {
|
||||
clks_fb_draw_pixel((u32)draw_x, (u32)draw_y, color);
|
||||
} else {
|
||||
clks_fb_fill_rect((u32)draw_x, (u32)draw_y, (u32)scale, (u32)scale, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1ULL;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_fd_open(u64 arg0, u64 arg1, u64 arg2) {
|
||||
char path[CLKS_SYSCALL_PATH_MAX];
|
||||
|
||||
@@ -292,6 +482,10 @@ static u64 clks_syscall_fd_read(u64 arg0, u64 arg1, u64 arg2) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (arg2 > 0ULL && clks_syscall_user_ptr_writable(arg1, arg2) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
return clks_exec_fd_read(arg0, (void *)arg1, arg2);
|
||||
}
|
||||
|
||||
@@ -300,6 +494,10 @@ static u64 clks_syscall_fd_write(u64 arg0, u64 arg1, u64 arg2) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (arg2 > 0ULL && clks_syscall_user_ptr_readable(arg1, arg2) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
return clks_exec_fd_write(arg0, (const void *)arg1, arg2);
|
||||
}
|
||||
|
||||
@@ -878,6 +1076,10 @@ static u64 clks_syscall_kdbg_bt(u64 arg0) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_readable(arg0, (u64)sizeof(req)) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
clks_memcpy(&req, (const void *)arg0, sizeof(req));
|
||||
|
||||
if (req.out_ptr == 0ULL || req.out_size == 0ULL) {
|
||||
@@ -1144,6 +1346,10 @@ static u64 clks_syscall_fs_get_child_name(u64 arg0, u64 arg1, u64 arg2) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_writable(arg2, CLKS_SYSCALL_NAME_MAX) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
@@ -1215,6 +1421,10 @@ static u64 clks_syscall_fs_read(u64 arg0, u64 arg1, u64 arg2) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_writable(arg1, arg2) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
@@ -1309,6 +1519,10 @@ static u64 clks_syscall_exec_pathv_io(u64 arg0, u64 arg1, u64 arg2) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_readable(arg2, (u64)sizeof(req)) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
clks_memcpy(&req, (const void *)arg2, sizeof(req));
|
||||
|
||||
if (clks_syscall_copy_user_optional_string(req.env_line_ptr, env_line, sizeof(env_line)) == CLKS_FALSE) {
|
||||
@@ -1372,6 +1586,9 @@ static u64 clks_syscall_waitpid(u64 arg0, u64 arg1) {
|
||||
u64 wait_ret = clks_exec_wait_pid(arg0, &status);
|
||||
|
||||
if (wait_ret == 1ULL && arg1 != 0ULL) {
|
||||
if (clks_syscall_user_ptr_writable(arg1, (u64)sizeof(status)) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
clks_memcpy((void *)arg1, &status, sizeof(status));
|
||||
}
|
||||
|
||||
@@ -1391,6 +1608,10 @@ static u64 clks_syscall_proc_argv(u64 arg0, u64 arg1, u64 arg2) {
|
||||
arg2 = CLKS_SYSCALL_ITEM_MAX;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_writable(arg1, arg2) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
return (clks_exec_copy_current_argv(arg0, (char *)arg1, (usize)arg2) == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||
}
|
||||
|
||||
@@ -1407,6 +1628,10 @@ static u64 clks_syscall_proc_env(u64 arg0, u64 arg1, u64 arg2) {
|
||||
arg2 = CLKS_SYSCALL_ITEM_MAX;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_writable(arg1, arg2) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
return (clks_exec_copy_current_env(arg0, (char *)arg1, (usize)arg2) == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||
}
|
||||
|
||||
@@ -1437,6 +1662,10 @@ static u64 clks_syscall_proc_pid_at(u64 arg0, u64 arg1) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_writable(arg1, (u64)sizeof(pid)) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_exec_proc_pid_at(arg0, &pid) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
@@ -1452,6 +1681,10 @@ static u64 clks_syscall_proc_snapshot(u64 arg0, u64 arg1, u64 arg2) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_writable(arg1, (u64)sizeof(snap)) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_exec_proc_snapshot(arg0, &snap) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
@@ -1602,6 +1835,10 @@ static u64 clks_syscall_fs_write_common(u64 arg0, u64 arg1, u64 arg2, clks_bool
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_readable(arg1, arg2) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
while (remaining > 0ULL) {
|
||||
u64 chunk_len = remaining;
|
||||
void *heap_copy;
|
||||
@@ -1668,6 +1905,10 @@ static u64 clks_syscall_log_journal_read(u64 arg0, u64 arg1, u64 arg2) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_syscall_user_ptr_writable(arg1, arg2) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_log_journal_read(arg0, line, sizeof(line)) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
@@ -2266,6 +2507,12 @@ u64 clks_syscall_dispatch(void *frame_ptr) {
|
||||
return clks_syscall_dl_close(frame->rbx);
|
||||
case CLKS_SYSCALL_DL_SYM:
|
||||
return clks_syscall_dl_sym(frame->rbx, frame->rcx);
|
||||
case CLKS_SYSCALL_FB_INFO:
|
||||
return clks_syscall_fb_info(frame->rbx);
|
||||
case CLKS_SYSCALL_FB_BLIT:
|
||||
return clks_syscall_fb_blit(frame->rbx);
|
||||
case CLKS_SYSCALL_FB_CLEAR:
|
||||
return clks_syscall_fb_clear(frame->rbx);
|
||||
default:
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
|
||||
内核分发位置:
|
||||
|
||||
- `clks/kernel/syscall.c`
|
||||
- `clks/kernel/runtime/syscall.c`
|
||||
|
||||
## 2. 全局返回规则
|
||||
|
||||
@@ -61,10 +61,10 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
|
||||
## 3. 当前实现中的长度/路径限制
|
||||
|
||||
以下限制由内核 `clks/kernel/syscall.c` 当前实现决定:
|
||||
以下限制由内核 `clks/kernel/runtime/syscall.c` 当前实现决定:
|
||||
|
||||
- 日志写入 `LOG_WRITE`:最大拷贝 `191` 字节。
|
||||
- TTY 文本写入 `TTY_WRITE`:最大拷贝 `512` 字节。
|
||||
- TTY 文本写入 `TTY_WRITE`:最大拷贝 `2048` 字节。
|
||||
- 文件读取 `FS_READ`:最多读取 `min(file_size, buffer_size)` 字节。
|
||||
- 文件写入 `FS_WRITE` / `FS_APPEND`:内核按 `65536` 字节分块搬运;这是实现分块大小,不是文件大小上限。
|
||||
- log journal 行读取缓冲:`256` 字节。
|
||||
@@ -83,7 +83,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
- `/proc/<pid>`:指定 PID 快照文本
|
||||
- `/proc` 为只读;写入类 syscall 不支持。
|
||||
|
||||
## 4. Syscall 列表(0~76)
|
||||
## 4. Syscall 列表(0~83)
|
||||
|
||||
### 0 `CLEONOS_SYSCALL_LOG_WRITE`
|
||||
|
||||
@@ -604,6 +604,61 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
- 返回:新 fd;失败 `-1`
|
||||
- 说明:当前为“按值复制”语义(复制 flags/offset/目标对象)。
|
||||
|
||||
### 77 `CLEONOS_SYSCALL_DL_OPEN`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `const char *path`
|
||||
- 返回:动态库句柄(`handle`);失败 `-1`
|
||||
- 说明:将用户态动态库(ELF)加载到当前进程地址空间,供 `DL_SYM` 查询符号。
|
||||
|
||||
### 78 `CLEONOS_SYSCALL_DL_CLOSE`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `u64 handle`
|
||||
- 返回:成功 `0`,失败 `-1`
|
||||
- 说明:关闭/释放由 `DL_OPEN` 返回的动态库句柄。
|
||||
|
||||
### 79 `CLEONOS_SYSCALL_DL_SYM`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `u64 handle`
|
||||
- `arg1`: `const char *symbol`
|
||||
- 返回:符号地址(`u64`);失败返回 `0`
|
||||
- 说明:用于查询库导出符号入口地址。
|
||||
|
||||
### 80 `CLEONOS_SYSCALL_EXEC_PATHV_IO`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `const char *path`
|
||||
- `arg1`: `const char *argv_line`(可为 `0`)
|
||||
- `arg2`: `struct { u64 env_line_ptr; u64 stdin_fd; u64 stdout_fd; u64 stderr_fd; } *req`
|
||||
- 返回:与 `EXEC_PATHV` 一致(成功返回子进程退出状态,失败 `-1`)
|
||||
- 说明:在 `EXEC_PATHV` 基础上增加 I/O 句柄重定向(用于管道与重定向)。
|
||||
|
||||
### 81 `CLEONOS_SYSCALL_FB_INFO`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `cleonos_fb_info *out_info`
|
||||
- 返回:成功 `1`,失败 `0`
|
||||
- 说明:获取 framebuffer 信息(`width/height/pitch/bpp`)。`out_info` 为空或 framebuffer 未就绪时失败。
|
||||
|
||||
### 82 `CLEONOS_SYSCALL_FB_BLIT`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `const cleonos_fb_blit_req *req`
|
||||
- 返回:成功 `1`,失败 `0`
|
||||
- 说明:
|
||||
- 从用户态 `pixels_ptr` 指向的 32bpp 源缓冲拷贝到 framebuffer。
|
||||
- `src_pitch_bytes=0` 时按 `src_width*4` 推导。
|
||||
- 当前实现限制:`src_width<=4096`、`src_height<=4096`、`scale<=8`,且目标坐标需落在屏幕内。
|
||||
|
||||
### 83 `CLEONOS_SYSCALL_FB_CLEAR`
|
||||
|
||||
- 参数:
|
||||
- `arg0`: `u64 rgb`(低 32 位有效)
|
||||
- 返回:成功 `1`,失败 `0`
|
||||
- 说明:用纯色清屏。
|
||||
|
||||
## 5. 用户态封装函数
|
||||
|
||||
用户态封装位于:
|
||||
@@ -629,6 +684,9 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
- `cleonos_sys_kdbg_sym()` / `cleonos_sys_kdbg_bt()` / `cleonos_sys_kdbg_regs()`
|
||||
- `cleonos_sys_stats_total()` / `cleonos_sys_stats_id_count()` / `cleonos_sys_stats_recent_window()` / `cleonos_sys_stats_recent_id()`
|
||||
- `cleonos_sys_fd_open()` / `cleonos_sys_fd_read()` / `cleonos_sys_fd_write()` / `cleonos_sys_fd_close()` / `cleonos_sys_fd_dup()`
|
||||
- `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()`
|
||||
|
||||
## 6. 开发注意事项
|
||||
|
||||
@@ -639,6 +697,8 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
|
||||
## 7. Wine 兼容说明
|
||||
|
||||
- `wine/cleonos_wine_lib/runner.py` 目前以 syscall `0..67` 为主;`68..76`(stats/fd)需同步适配后才能完整覆盖。
|
||||
- `wine/cleonos_wine_lib/runner.py` 当前已覆盖到 `0..80`(含 `stats/fd/exec_pathv_io`)。
|
||||
- `DL_*`(`77..79`)在 Wine 中当前为占位实现:`DL_OPEN=-1`、`DL_CLOSE=0`、`DL_SYM=0`。
|
||||
- framebuffer 相关 syscall(`81..83`)尚未在 Wine 中实现(会返回未支持路径)。
|
||||
- Wine 在运行时崩溃场景下会生成与内核一致格式的“信号编码退出状态”,可通过 `WAITPID` 读取。
|
||||
- Wine 当前音频 syscall 为占位实现:`AUDIO_AVAILABLE=0`,`AUDIO_PLAY_TONE=0`,`AUDIO_STOP=1`。
|
||||
|
||||
BIN
ramdisk/doom1.wad
Normal file
BIN
ramdisk/doom1.wad
Normal file
Binary file not shown.
Reference in New Issue
Block a user