mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 18:44:01 +00:00
Compare commits
4 Commits
98897031e8
...
27a51a0986
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27a51a0986 | ||
|
|
16855e4b98 | ||
|
|
dbd88505e6 | ||
|
|
d7e1cb62ee |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
|||||||
[submodule "limine"]
|
[submodule "limine"]
|
||||||
path = limine
|
path = limine
|
||||||
url = https://github.com/limine-bootloader/limine.git
|
url = https://github.com/limine-bootloader/limine.git
|
||||||
|
[submodule "cleonos/third-party/doomgeneric"]
|
||||||
|
path = cleonos/third-party/doomgeneric
|
||||||
|
url = https://github.com/ozkl/doomgeneric.git
|
||||||
|
|||||||
@@ -337,6 +337,24 @@ set(USER_CFLAGS
|
|||||||
"-I${CMAKE_SOURCE_DIR}/cleonos/c/include"
|
"-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
|
set(USER_LDFLAGS
|
||||||
-nostdlib
|
-nostdlib
|
||||||
-z
|
-z
|
||||||
@@ -494,6 +512,23 @@ function(add_user_c_object SRC OUTPUT_VAR)
|
|||||||
set(${OUTPUT_VAR} "${OBJ_PATH}" PARENT_SCOPE)
|
set(${OUTPUT_VAR} "${OBJ_PATH}" PARENT_SCOPE)
|
||||||
endfunction()
|
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)
|
set(KERNEL_OBJECTS)
|
||||||
foreach(SRC IN LISTS C_SOURCES)
|
foreach(SRC IN LISTS C_SOURCES)
|
||||||
add_kernel_c_object("${SRC}" KERNEL_OBJECTS)
|
add_kernel_c_object("${SRC}" KERNEL_OBJECTS)
|
||||||
@@ -565,6 +600,25 @@ set(RAMDISK_DRIVER_APPS)
|
|||||||
set(RAMDISK_SYSTEM_APPS)
|
set(RAMDISK_SYSTEM_APPS)
|
||||||
set(RAMDISK_ROOT_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
|
set(USER_SHELL_COMMAND_APPS
|
||||||
help args ls cat grep head tail wc cut uniq sort pwd cd exec pid spawn wait sleep yield
|
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
|
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"
|
||||||
"${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)
|
list(FIND USER_SHELL_COMMAND_APPS "${_app_name}" _shell_cmd_idx)
|
||||||
if(NOT _shell_cmd_idx EQUAL -1)
|
if(NOT _shell_cmd_idx EQUAL -1)
|
||||||
@@ -626,7 +687,11 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
|
|||||||
continue()
|
continue()
|
||||||
endif()
|
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}")
|
list(APPEND _app_specific_objs "${_extra_obj}")
|
||||||
endforeach()
|
endforeach()
|
||||||
list(REMOVE_DUPLICATES _app_specific_objs)
|
list(REMOVE_DUPLICATES _app_specific_objs)
|
||||||
@@ -635,8 +700,8 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
|
|||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT "${_app_out}"
|
OUTPUT "${_app_out}"
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${USER_APP_DIR}"
|
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}"
|
COMMAND ${USER_LD} ${USER_LDFLAGS} -o "${_app_out}" ${_app_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}"
|
DEPENDS ${_app_common_objects} "${_user_obj}" ${_app_specific_objs} "${USER_RUST_LIB}" "${USER_LINKER_SCRIPT}"
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
1472
cleonos/c/apps/doom/doom_compat.c
Normal file
1472
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(" ansi / ansitest / color");
|
||||||
ush_writeln(" wavplay <file.wav> [steps] [ticks] / wavplay --stop");
|
ush_writeln(" wavplay <file.wav> [steps] [ticks] / wavplay --stop");
|
||||||
ush_writeln(" fastfetch [--plain]");
|
ush_writeln(" fastfetch [--plain]");
|
||||||
|
ush_writeln(" doom [wad_path] (framebuffer bootstrap renderer)");
|
||||||
ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats");
|
ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats");
|
||||||
ush_writeln(" tty [index]");
|
ush_writeln(" tty [index]");
|
||||||
ush_writeln(" dmesg [n]");
|
ush_writeln(" dmesg [n]");
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ static int ush_cmd_help(void) {
|
|||||||
ush_writeln(" ansi / ansitest / color");
|
ush_writeln(" ansi / ansitest / color");
|
||||||
ush_writeln(" wavplay <file.wav> [steps] [ticks] / wavplay --stop");
|
ush_writeln(" wavplay <file.wav> [steps] [ticks] / wavplay --stop");
|
||||||
ush_writeln(" fastfetch [--plain]");
|
ush_writeln(" fastfetch [--plain]");
|
||||||
|
ush_writeln(" doom [wad_path] (framebuffer bootstrap renderer)");
|
||||||
ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats");
|
ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats");
|
||||||
ush_writeln(" tty [index]");
|
ush_writeln(" tty [index]");
|
||||||
ush_writeln(" dmesg [n]");
|
ush_writeln(" dmesg [n]");
|
||||||
|
|||||||
@@ -43,6 +43,23 @@ typedef struct cleonos_proc_snapshot {
|
|||||||
char path[CLEONOS_PROC_PATH_MAX];
|
char path[CLEONOS_PROC_PATH_MAX];
|
||||||
} cleonos_proc_snapshot;
|
} 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_LOG_WRITE 0ULL
|
||||||
#define CLEONOS_SYSCALL_TIMER_TICKS 1ULL
|
#define CLEONOS_SYSCALL_TIMER_TICKS 1ULL
|
||||||
#define CLEONOS_SYSCALL_TASK_COUNT 2ULL
|
#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_CLOSE 78ULL
|
||||||
#define CLEONOS_SYSCALL_DL_SYM 79ULL
|
#define CLEONOS_SYSCALL_DL_SYM 79ULL
|
||||||
#define CLEONOS_SYSCALL_EXEC_PATHV_IO 80ULL
|
#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_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||||
u64 cleonos_sys_log_write(const char *message, u64 length);
|
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_open(const char *path);
|
||||||
u64 cleonos_sys_dl_close(u64 handle);
|
u64 cleonos_sys_dl_close(u64 handle);
|
||||||
u64 cleonos_sys_dl_sym(u64 handle, const char *symbol);
|
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
|
#endif
|
||||||
|
|||||||
@@ -196,6 +196,42 @@ static clio_size_t clio_i64_to_dec(long long value, char *out, clio_size_t out_s
|
|||||||
return offset + len;
|
return offset + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int clio_is_digit(char ch) {
|
||||||
|
return (ch >= '0' && ch <= '9') ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clio_emit_repeat(struct clio_sink *sink, char ch, clio_size_t count) {
|
||||||
|
while (count > 0UL) {
|
||||||
|
if (clio_sink_emit(sink, &ch, 1UL) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clio_emit_with_width(struct clio_sink *sink, const char *text, clio_size_t text_len, int left_align,
|
||||||
|
char pad_char, clio_size_t width) {
|
||||||
|
if (left_align == 0 && width > text_len) {
|
||||||
|
if (clio_emit_repeat(sink, pad_char, width - text_len) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text_len > 0UL && clio_sink_emit(sink, text, text_len) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_align != 0 && width > text_len) {
|
||||||
|
if (clio_emit_repeat(sink, ' ', width - text_len) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int clio_vformat(struct clio_sink *sink, const char *fmt, va_list args) {
|
static int clio_vformat(struct clio_sink *sink, const char *fmt, va_list args) {
|
||||||
const char *cursor = fmt;
|
const char *cursor = fmt;
|
||||||
|
|
||||||
@@ -223,10 +259,43 @@ static int clio_vformat(struct clio_sink *sink, const char *fmt, va_list args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
int left_align = 0;
|
||||||
|
int zero_pad = 0;
|
||||||
|
clio_size_t width = 0UL;
|
||||||
|
int has_precision = 0;
|
||||||
|
clio_size_t precision = 0UL;
|
||||||
int length_mode = 0; /* 0: default, 1: l, 2: ll, 3: z */
|
int length_mode = 0; /* 0: default, 1: l, 2: ll, 3: z */
|
||||||
char spec = *cursor;
|
char spec = *cursor;
|
||||||
char number_buf[64];
|
char number_buf[96];
|
||||||
clio_size_t out_len = 0UL;
|
|
||||||
|
while (spec == '-' || spec == '0') {
|
||||||
|
if (spec == '-') {
|
||||||
|
left_align = 1;
|
||||||
|
} else if (spec == '0') {
|
||||||
|
zero_pad = 1;
|
||||||
|
}
|
||||||
|
cursor++;
|
||||||
|
spec = *cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (clio_is_digit(spec) != 0) {
|
||||||
|
width = (width * 10UL) + (clio_size_t)(unsigned long)(spec - '0');
|
||||||
|
cursor++;
|
||||||
|
spec = *cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spec == '.') {
|
||||||
|
has_precision = 1;
|
||||||
|
precision = 0UL;
|
||||||
|
cursor++;
|
||||||
|
spec = *cursor;
|
||||||
|
|
||||||
|
while (clio_is_digit(spec) != 0) {
|
||||||
|
precision = (precision * 10UL) + (clio_size_t)(unsigned long)(spec - '0');
|
||||||
|
cursor++;
|
||||||
|
spec = *cursor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (spec == 'l') {
|
if (spec == 'l') {
|
||||||
cursor++;
|
cursor++;
|
||||||
@@ -250,24 +319,36 @@ static int clio_vformat(struct clio_sink *sink, const char *fmt, va_list args) {
|
|||||||
|
|
||||||
if (spec == 's') {
|
if (spec == 's') {
|
||||||
const char *text = va_arg(args, const char *);
|
const char *text = va_arg(args, const char *);
|
||||||
|
clio_size_t text_len;
|
||||||
|
|
||||||
if (text == (const char *)0) {
|
if (text == (const char *)0) {
|
||||||
text = "(null)";
|
text = "(null)";
|
||||||
}
|
}
|
||||||
|
|
||||||
out_len = clio_strlen(text);
|
text_len = clio_strlen(text);
|
||||||
|
if (has_precision != 0 && precision < text_len) {
|
||||||
|
text_len = precision;
|
||||||
|
}
|
||||||
|
|
||||||
if (clio_sink_emit(sink, text, out_len) == 0) {
|
if (clio_emit_with_width(sink, text, text_len, left_align, ' ', width) == 0) {
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
} else if (spec == 'c') {
|
} else if (spec == 'c') {
|
||||||
char out = (char)va_arg(args, int);
|
char out = (char)va_arg(args, int);
|
||||||
|
char out_buf[1];
|
||||||
|
|
||||||
if (clio_sink_emit(sink, &out, 1UL) == 0) {
|
out_buf[0] = out;
|
||||||
|
if (clio_emit_with_width(sink, out_buf, 1UL, left_align, ' ', width) == 0) {
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
} else if (spec == 'd' || spec == 'i') {
|
} else if (spec == 'd' || spec == 'i') {
|
||||||
long long value;
|
long long value;
|
||||||
|
char sign_char = '\0';
|
||||||
|
const char *digits = number_buf;
|
||||||
|
clio_size_t digits_len;
|
||||||
|
clio_size_t leading_zeros = 0UL;
|
||||||
|
clio_size_t core_len;
|
||||||
|
int sign_emitted = 0;
|
||||||
|
|
||||||
if (length_mode == 2) {
|
if (length_mode == 2) {
|
||||||
value = va_arg(args, long long);
|
value = va_arg(args, long long);
|
||||||
@@ -279,14 +360,72 @@ static int clio_vformat(struct clio_sink *sink, const char *fmt, va_list args) {
|
|||||||
value = (long long)va_arg(args, int);
|
value = (long long)va_arg(args, int);
|
||||||
}
|
}
|
||||||
|
|
||||||
out_len = clio_i64_to_dec(value, number_buf, (clio_size_t)sizeof(number_buf));
|
digits_len = clio_i64_to_dec(value, number_buf, (clio_size_t)sizeof(number_buf));
|
||||||
if (out_len == 0UL || clio_sink_emit(sink, number_buf, out_len) == 0) {
|
if (digits_len == 0UL) {
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (number_buf[0] == '-') {
|
||||||
|
sign_char = '-';
|
||||||
|
digits = number_buf + 1;
|
||||||
|
digits_len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_precision != 0 && precision == 0UL && value == 0LL) {
|
||||||
|
digits_len = 0UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_precision != 0 && precision > digits_len) {
|
||||||
|
leading_zeros = precision - digits_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
core_len = digits_len + leading_zeros + ((sign_char != '\0') ? 1UL : 0UL);
|
||||||
|
|
||||||
|
if (left_align == 0 && width > core_len) {
|
||||||
|
if (zero_pad != 0 && has_precision == 0) {
|
||||||
|
if (sign_char != '\0') {
|
||||||
|
if (clio_sink_emit(sink, &sign_char, 1UL) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
sign_emitted = 1;
|
||||||
|
}
|
||||||
|
if (clio_emit_repeat(sink, '0', width - core_len) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (clio_emit_repeat(sink, ' ', width - core_len) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sign_char != '\0' && sign_emitted == 0) {
|
||||||
|
if (clio_sink_emit(sink, &sign_char, 1UL) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clio_emit_repeat(sink, '0', leading_zeros) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (digits_len > 0UL && clio_sink_emit(sink, digits, digits_len) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_align != 0 && width > core_len) {
|
||||||
|
if (clio_emit_repeat(sink, ' ', width - core_len) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (spec == 'u' || spec == 'x' || spec == 'X') {
|
} else if (spec == 'u' || spec == 'x' || spec == 'X') {
|
||||||
unsigned long long value;
|
unsigned long long value;
|
||||||
unsigned int base = (spec == 'u') ? 10U : 16U;
|
unsigned int base = (spec == 'u') ? 10U : 16U;
|
||||||
int upper = (spec == 'X') ? 1 : 0;
|
int upper = (spec == 'X') ? 1 : 0;
|
||||||
|
clio_size_t digits_len;
|
||||||
|
clio_size_t leading_zeros = 0UL;
|
||||||
|
clio_size_t core_len;
|
||||||
|
char pad_char = ' ';
|
||||||
|
|
||||||
if (length_mode == 2) {
|
if (length_mode == 2) {
|
||||||
value = va_arg(args, unsigned long long);
|
value = va_arg(args, unsigned long long);
|
||||||
@@ -298,22 +437,98 @@ static int clio_vformat(struct clio_sink *sink, const char *fmt, va_list args) {
|
|||||||
value = (unsigned long long)va_arg(args, unsigned int);
|
value = (unsigned long long)va_arg(args, unsigned int);
|
||||||
}
|
}
|
||||||
|
|
||||||
out_len = clio_u64_to_base(value, base, upper, number_buf, (clio_size_t)sizeof(number_buf));
|
digits_len = clio_u64_to_base(value, base, upper, number_buf, (clio_size_t)sizeof(number_buf));
|
||||||
if (out_len == 0UL || clio_sink_emit(sink, number_buf, out_len) == 0) {
|
if (digits_len == 0UL) {
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_precision != 0 && precision == 0UL && value == 0ULL) {
|
||||||
|
digits_len = 0UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_precision != 0 && precision > digits_len) {
|
||||||
|
leading_zeros = precision - digits_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
core_len = digits_len + leading_zeros;
|
||||||
|
|
||||||
|
if (zero_pad != 0 && has_precision == 0 && left_align == 0) {
|
||||||
|
pad_char = '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_align == 0 && width > core_len) {
|
||||||
|
if (clio_emit_repeat(sink, pad_char, width - core_len) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clio_emit_repeat(sink, '0', leading_zeros) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (digits_len > 0UL && clio_sink_emit(sink, number_buf, digits_len) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_align != 0 && width > core_len) {
|
||||||
|
if (clio_emit_repeat(sink, ' ', width - core_len) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (spec == 'p') {
|
} else if (spec == 'p') {
|
||||||
const void *ptr = va_arg(args, const void *);
|
const void *ptr = va_arg(args, const void *);
|
||||||
unsigned long long value = (unsigned long long)(unsigned long)ptr;
|
unsigned long long value = (unsigned long long)(unsigned long)ptr;
|
||||||
|
clio_size_t digits_len;
|
||||||
|
clio_size_t leading_zeros = 0UL;
|
||||||
|
clio_size_t core_len;
|
||||||
|
|
||||||
|
digits_len = clio_u64_to_base(value, 16U, 0, number_buf, (clio_size_t)sizeof(number_buf));
|
||||||
|
if (digits_len == 0UL) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_precision != 0 && precision == 0UL && value == 0ULL) {
|
||||||
|
digits_len = 0UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_precision != 0 && precision > digits_len) {
|
||||||
|
leading_zeros = precision - digits_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
core_len = 2UL + leading_zeros + digits_len;
|
||||||
|
|
||||||
|
if (left_align == 0 && width > core_len) {
|
||||||
|
if (clio_emit_repeat(sink, ' ', width - core_len) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (clio_sink_emit(sink, "0x", 2UL) == 0) {
|
if (clio_sink_emit(sink, "0x", 2UL) == 0) {
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_len = clio_u64_to_base(value, 16U, 0, number_buf, (clio_size_t)sizeof(number_buf));
|
if (clio_emit_repeat(sink, '0', leading_zeros) == 0) {
|
||||||
if (out_len == 0UL || clio_sink_emit(sink, number_buf, out_len) == 0) {
|
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (digits_len > 0UL && clio_sink_emit(sink, number_buf, digits_len) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_align != 0 && width > core_len) {
|
||||||
|
if (clio_emit_repeat(sink, ' ', width - core_len) == 0) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (spec == 'n') {
|
||||||
|
int *out_count = va_arg(args, int *);
|
||||||
|
if (out_count != (int *)0) {
|
||||||
|
if (sink->count > 0x7FFFFFFFUL) {
|
||||||
|
*out_count = 0x7FFFFFFF;
|
||||||
|
} else {
|
||||||
|
*out_count = (int)sink->count;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
char fallback[2];
|
char fallback[2];
|
||||||
fallback[0] = spec;
|
fallback[0] = spec;
|
||||||
|
|||||||
@@ -355,3 +355,15 @@ u64 cleonos_sys_dl_close(u64 handle) {
|
|||||||
u64 cleonos_sys_dl_sym(u64 handle, const char *symbol) {
|
u64 cleonos_sys_dl_sym(u64 handle, const char *symbol) {
|
||||||
return cleonos_syscall(CLEONOS_SYSCALL_DL_SYM, handle, (u64)symbol, 0ULL);
|
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);
|
u64 clks_exec_success_count(void);
|
||||||
clks_bool clks_exec_is_running(void);
|
clks_bool clks_exec_is_running(void);
|
||||||
clks_bool clks_exec_current_path_is_user(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
|
#endif
|
||||||
|
|||||||
@@ -84,6 +84,9 @@
|
|||||||
#define CLKS_SYSCALL_DL_CLOSE 78ULL
|
#define CLKS_SYSCALL_DL_CLOSE 78ULL
|
||||||
#define CLKS_SYSCALL_DL_SYM 79ULL
|
#define CLKS_SYSCALL_DL_SYM 79ULL
|
||||||
#define CLKS_SYSCALL_EXEC_PATHV_IO 80ULL
|
#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);
|
void clks_syscall_init(void);
|
||||||
u64 clks_syscall_dispatch(void *frame_ptr);
|
u64 clks_syscall_dispatch(void *frame_ptr);
|
||||||
|
|||||||
@@ -2,7 +2,11 @@
|
|||||||
#include <clks/string.h>
|
#include <clks/string.h>
|
||||||
#include <clks/types.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_ALIGN 16ULL
|
||||||
#define CLKS_HEAP_MAGIC 0x434C454F4E4F534FULL
|
#define CLKS_HEAP_MAGIC 0x434C454F4E4F534FULL
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <clks/elf64.h>
|
#include <clks/elf64.h>
|
||||||
#include <clks/heap.h>
|
#include <clks/heap.h>
|
||||||
|
#include <clks/log.h>
|
||||||
#include <clks/string.h>
|
#include <clks/string.h>
|
||||||
#include <clks/types.h>
|
#include <clks/types.h>
|
||||||
|
|
||||||
@@ -17,6 +18,8 @@
|
|||||||
|
|
||||||
#define CLKS_ELF64_EM_X86_64 62U
|
#define CLKS_ELF64_EM_X86_64 62U
|
||||||
|
|
||||||
|
#define CLKS_ELF64_PF_X 0x1U
|
||||||
|
|
||||||
struct clks_elf64_ehdr {
|
struct clks_elf64_ehdr {
|
||||||
u8 e_ident[16];
|
u8 e_ident[16];
|
||||||
u16 e_type;
|
u16 e_type;
|
||||||
@@ -90,6 +93,42 @@ static clks_bool clks_elf64_range_ok(u64 off, u64 len, u64 total) {
|
|||||||
return CLKS_TRUE;
|
return CLKS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clks_elf64_rebase_exec_pointers(struct clks_elf64_loaded_image *loaded, u64 old_base, u64 old_end,
|
||||||
|
u64 delta) {
|
||||||
|
u16 seg_index;
|
||||||
|
|
||||||
|
if (loaded == CLKS_NULL || delta == 0ULL || old_end <= old_base) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (seg_index = 0U; seg_index < loaded->segment_count; seg_index++) {
|
||||||
|
struct clks_elf64_loaded_segment *seg = &loaded->segments[seg_index];
|
||||||
|
u64 scan_len;
|
||||||
|
u64 off;
|
||||||
|
|
||||||
|
/* Skip executable segments to avoid patching instruction bytes. */
|
||||||
|
if ((seg->flags & CLKS_ELF64_PF_X) != 0U) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
scan_len = seg->filesz;
|
||||||
|
if (scan_len < sizeof(u64)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
scan_len -= (scan_len % sizeof(u64));
|
||||||
|
|
||||||
|
for (off = 0ULL; off < scan_len; off += sizeof(u64)) {
|
||||||
|
u64 *slot = (u64 *)((u8 *)seg->base + (usize)off);
|
||||||
|
u64 value = *slot;
|
||||||
|
|
||||||
|
if (value >= old_base && value < old_end) {
|
||||||
|
*slot = value + delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clks_bool clks_elf64_validate(const void *image, u64 size) {
|
clks_bool clks_elf64_validate(const void *image, u64 size) {
|
||||||
const struct clks_elf64_ehdr *eh;
|
const struct clks_elf64_ehdr *eh;
|
||||||
u64 ph_table_size;
|
u64 ph_table_size;
|
||||||
@@ -230,6 +269,10 @@ clks_bool clks_elf64_load(const void *image, u64 size, struct clks_elf64_loaded_
|
|||||||
|
|
||||||
image_base = clks_kmalloc((usize)span);
|
image_base = clks_kmalloc((usize)span);
|
||||||
if (image_base == CLKS_NULL) {
|
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;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,6 +316,17 @@ clks_bool clks_elf64_load(const void *image, u64 size, struct clks_elf64_loaded_
|
|||||||
out_loaded->segment_count++;
|
out_loaded->segment_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eh->e_type == CLKS_ELF64_ET_EXEC) {
|
||||||
|
u64 new_base = (u64)(usize)image_base;
|
||||||
|
u64 old_base = min_vaddr;
|
||||||
|
u64 old_end = max_vaddr_end;
|
||||||
|
|
||||||
|
if (new_base != old_base) {
|
||||||
|
u64 delta = new_base - old_base;
|
||||||
|
clks_elf64_rebase_exec_pointers(out_loaded, old_base, old_end, delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return CLKS_TRUE;
|
return CLKS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
typedef u64 (*clks_exec_entry_fn)(void);
|
typedef u64 (*clks_exec_entry_fn)(void);
|
||||||
|
|
||||||
#define CLKS_EXEC_RUN_STACK_BYTES (64ULL * 1024ULL)
|
#define CLKS_EXEC_RUN_STACK_BYTES (1024ULL * 1024ULL)
|
||||||
#define CLKS_EXEC_MAX_PROCS 64U
|
#define CLKS_EXEC_MAX_PROCS 64U
|
||||||
#define CLKS_EXEC_MAX_DEPTH 16U
|
#define CLKS_EXEC_MAX_DEPTH 16U
|
||||||
#define CLKS_EXEC_PATH_MAX 192U
|
#define CLKS_EXEC_PATH_MAX 192U
|
||||||
@@ -160,6 +160,11 @@ struct clks_exec_dynlib_slot {
|
|||||||
#if defined(CLKS_ARCH_X86_64)
|
#if defined(CLKS_ARCH_X86_64)
|
||||||
extern u64 clks_exec_call_on_stack_x86_64(void *entry_ptr, void *stack_top);
|
extern u64 clks_exec_call_on_stack_x86_64(void *entry_ptr, void *stack_top);
|
||||||
extern void clks_exec_abort_to_caller_x86_64(void);
|
extern void clks_exec_abort_to_caller_x86_64(void);
|
||||||
|
static u64 clks_exec_read_cr2(void) {
|
||||||
|
u64 value = 0ULL;
|
||||||
|
__asm__ volatile("mov %%cr2, %0" : "=r"(value));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static u64 clks_exec_requests = 0ULL;
|
static u64 clks_exec_requests = 0ULL;
|
||||||
@@ -178,6 +183,10 @@ 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 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_begin_stack[CLKS_EXEC_MAX_DEPTH];
|
||||||
static u64 clks_exec_image_end_stack[CLKS_EXEC_MAX_DEPTH];
|
static u64 clks_exec_image_end_stack[CLKS_EXEC_MAX_DEPTH];
|
||||||
|
static u64 clks_exec_image_vaddr_begin_stack[CLKS_EXEC_MAX_DEPTH];
|
||||||
|
static u64 clks_exec_image_vaddr_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 u32 clks_exec_pid_stack_depth = 0U;
|
||||||
static struct clks_exec_dynlib_slot clks_exec_dynlib_table[CLKS_EXEC_DYNLIB_MAX];
|
static struct clks_exec_dynlib_slot clks_exec_dynlib_table[CLKS_EXEC_DYNLIB_MAX];
|
||||||
static u64 clks_exec_next_dynlib_handle = 1ULL;
|
static u64 clks_exec_next_dynlib_handle = 1ULL;
|
||||||
@@ -315,6 +324,48 @@ static clks_bool clks_exec_rip_is_current_user_context(u64 rip) {
|
|||||||
return (rip >= image_begin && rip < image_end) ? CLKS_TRUE : CLKS_FALSE;
|
return (rip >= image_begin && rip < image_end) ? CLKS_TRUE : CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static clks_bool clks_exec_translate_legacy_user_rip(u64 rip, u64 *out_rip) {
|
||||||
|
i32 depth_index;
|
||||||
|
u64 vaddr_begin;
|
||||||
|
u64 vaddr_end;
|
||||||
|
u64 image_begin;
|
||||||
|
u64 image_end;
|
||||||
|
u64 off;
|
||||||
|
u64 translated;
|
||||||
|
|
||||||
|
if (out_rip == CLKS_NULL || clks_exec_pid_stack_depth == 0U) {
|
||||||
|
return CLKS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
depth_index = (i32)(clks_exec_pid_stack_depth - 1U);
|
||||||
|
vaddr_begin = clks_exec_image_vaddr_begin_stack[(u32)depth_index];
|
||||||
|
vaddr_end = clks_exec_image_vaddr_end_stack[(u32)depth_index];
|
||||||
|
image_begin = clks_exec_image_begin_stack[(u32)depth_index];
|
||||||
|
image_end = clks_exec_image_end_stack[(u32)depth_index];
|
||||||
|
|
||||||
|
if (vaddr_begin == 0ULL || vaddr_end <= vaddr_begin || image_begin == 0ULL || image_end <= image_begin) {
|
||||||
|
return CLKS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rip < vaddr_begin || rip >= vaddr_end) {
|
||||||
|
return CLKS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
off = rip - vaddr_begin;
|
||||||
|
|
||||||
|
if (off >= (image_end - image_begin)) {
|
||||||
|
return CLKS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
translated = image_begin + off;
|
||||||
|
if (translated < image_begin || translated >= image_end) {
|
||||||
|
return CLKS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_rip = translated;
|
||||||
|
return CLKS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void clks_exec_copy_path(char *dst, usize dst_size, const char *src) {
|
static void clks_exec_copy_path(char *dst, usize dst_size, const char *src) {
|
||||||
usize i = 0U;
|
usize i = 0U;
|
||||||
|
|
||||||
@@ -362,6 +413,26 @@ static clks_bool clks_exec_range_ok(u64 off, u64 len, u64 total) {
|
|||||||
return CLKS_TRUE;
|
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) {
|
static i32 clks_exec_dynlib_alloc_slot(void) {
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
@@ -1179,6 +1250,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);
|
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;
|
unwind_slot = (((u64)stack_top) & ~0xFULL) - CLKS_EXEC_UNWIND_CTX_BYTES;
|
||||||
clks_exec_unwind_slot_stack[depth_index] = unwind_slot;
|
clks_exec_unwind_slot_stack[depth_index] = unwind_slot;
|
||||||
clks_exec_unwind_slot_valid_stack[depth_index] = CLKS_TRUE;
|
clks_exec_unwind_slot_valid_stack[depth_index] = CLKS_TRUE;
|
||||||
@@ -1192,6 +1265,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. */
|
/* 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_valid_stack[depth_index] = CLKS_FALSE;
|
||||||
clks_exec_unwind_slot_stack[depth_index] = 0ULL;
|
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);
|
clks_exec_restore_interrupt_window(restore_irq_disable);
|
||||||
*out_ret = call_ret;
|
*out_ret = call_ret;
|
||||||
@@ -1254,6 +1329,10 @@ 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_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
|
||||||
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
|
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
|
||||||
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
|
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
|
||||||
|
clks_exec_image_vaddr_begin_stack[(u32)depth_index] = 0ULL;
|
||||||
|
clks_exec_image_vaddr_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++;
|
clks_exec_pid_stack_depth++;
|
||||||
depth_pushed = CLKS_TRUE;
|
depth_pushed = CLKS_TRUE;
|
||||||
|
|
||||||
@@ -1300,6 +1379,8 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
|
|||||||
|
|
||||||
clks_exec_image_begin_stack[(u32)depth_index] = image_begin;
|
clks_exec_image_begin_stack[(u32)depth_index] = image_begin;
|
||||||
clks_exec_image_end_stack[(u32)depth_index] = image_end;
|
clks_exec_image_end_stack[(u32)depth_index] = image_end;
|
||||||
|
clks_exec_image_vaddr_begin_stack[(u32)depth_index] = loaded.image_vaddr_base;
|
||||||
|
clks_exec_image_vaddr_end_stack[(u32)depth_index] = loaded.image_vaddr_base + loaded.image_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
clks_exec_log_info_serial("EXEC RUN START");
|
clks_exec_log_info_serial("EXEC RUN START");
|
||||||
@@ -1348,6 +1429,10 @@ 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_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
|
||||||
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
|
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
|
||||||
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
|
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
|
||||||
|
clks_exec_image_vaddr_begin_stack[(u32)depth_index] = 0ULL;
|
||||||
|
clks_exec_image_vaddr_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--;
|
clks_exec_pid_stack_depth--;
|
||||||
depth_pushed = CLKS_FALSE;
|
depth_pushed = CLKS_FALSE;
|
||||||
}
|
}
|
||||||
@@ -1374,6 +1459,10 @@ fail:
|
|||||||
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
|
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
|
||||||
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
|
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
|
||||||
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
|
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
|
||||||
|
clks_exec_image_vaddr_begin_stack[(u32)depth_index] = 0ULL;
|
||||||
|
clks_exec_image_vaddr_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--;
|
clks_exec_pid_stack_depth--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1484,6 +1573,10 @@ 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_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_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_image_end_stack, 0, sizeof(clks_exec_image_end_stack));
|
||||||
|
clks_memset(clks_exec_image_vaddr_begin_stack, 0, sizeof(clks_exec_image_vaddr_begin_stack));
|
||||||
|
clks_memset(clks_exec_image_vaddr_end_stack, 0, sizeof(clks_exec_image_vaddr_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_proc_table, 0, sizeof(clks_exec_proc_table));
|
||||||
clks_memset(clks_exec_dynlib_table, 0, sizeof(clks_exec_dynlib_table));
|
clks_memset(clks_exec_dynlib_table, 0, sizeof(clks_exec_dynlib_table));
|
||||||
clks_exec_next_dynlib_handle = 1ULL;
|
clks_exec_next_dynlib_handle = 1ULL;
|
||||||
@@ -2419,6 +2512,20 @@ clks_bool clks_exec_handle_exception(u64 vector, u64 error_code, u64 rip, u64 *i
|
|||||||
return CLKS_FALSE;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CLKS_ARCH_X86_64)
|
||||||
|
if (vector == 14ULL && (error_code & 0x10ULL) != 0ULL && io_rip != CLKS_NULL) {
|
||||||
|
u64 translated_rip = 0ULL;
|
||||||
|
|
||||||
|
if (clks_exec_translate_legacy_user_rip(rip, &translated_rip) == CLKS_TRUE) {
|
||||||
|
*io_rip = translated_rip;
|
||||||
|
clks_exec_log_info_serial("USER RIP LEGACY REBASE");
|
||||||
|
clks_exec_log_hex_serial("RIP_OLD", rip);
|
||||||
|
clks_exec_log_hex_serial("RIP_NEW", translated_rip);
|
||||||
|
return CLKS_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
signal = clks_exec_signal_from_vector(vector);
|
signal = clks_exec_signal_from_vector(vector);
|
||||||
status = clks_exec_encode_signal_status(signal, vector, error_code);
|
status = clks_exec_encode_signal_status(signal, vector, error_code);
|
||||||
|
|
||||||
@@ -2437,6 +2544,11 @@ clks_bool clks_exec_handle_exception(u64 vector, u64 error_code, u64 rip, u64 *i
|
|||||||
clks_exec_log_hex_serial("VECTOR", vector);
|
clks_exec_log_hex_serial("VECTOR", vector);
|
||||||
clks_exec_log_hex_serial("ERROR", error_code);
|
clks_exec_log_hex_serial("ERROR", error_code);
|
||||||
clks_exec_log_hex_serial("RIP", rip);
|
clks_exec_log_hex_serial("RIP", rip);
|
||||||
|
#if defined(CLKS_ARCH_X86_64)
|
||||||
|
if (vector == 14ULL) {
|
||||||
|
clks_exec_log_hex_serial("CR2", clks_exec_read_cr2());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CLKS_ARCH_X86_64)
|
#if defined(CLKS_ARCH_X86_64)
|
||||||
if (io_rip == CLKS_NULL || io_rdi == CLKS_NULL || io_rsi == CLKS_NULL) {
|
if (io_rip == CLKS_NULL || io_rdi == CLKS_NULL || io_rsi == CLKS_NULL) {
|
||||||
@@ -2526,3 +2638,39 @@ clks_bool clks_exec_current_path_is_user(void) {
|
|||||||
proc = &clks_exec_proc_table[(u32)slot];
|
proc = &clks_exec_proc_table[(u32)slot];
|
||||||
return clks_exec_path_is_user_program(proc->path);
|
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/cpu.h>
|
||||||
#include <clks/audio.h>
|
#include <clks/audio.h>
|
||||||
#include <clks/exec.h>
|
#include <clks/exec.h>
|
||||||
|
#include <clks/framebuffer.h>
|
||||||
#include <clks/fs.h>
|
#include <clks/fs.h>
|
||||||
#include <clks/heap.h>
|
#include <clks/heap.h>
|
||||||
#include <clks/interrupts.h>
|
#include <clks/interrupts.h>
|
||||||
@@ -32,7 +33,7 @@
|
|||||||
#define CLKS_SYSCALL_KDBG_STACK_WINDOW_BYTES (128ULL * 1024ULL)
|
#define CLKS_SYSCALL_KDBG_STACK_WINDOW_BYTES (128ULL * 1024ULL)
|
||||||
#define CLKS_SYSCALL_KERNEL_SYMBOL_FILE "/system/kernel.sym"
|
#define CLKS_SYSCALL_KERNEL_SYMBOL_FILE "/system/kernel.sym"
|
||||||
#define CLKS_SYSCALL_KERNEL_ADDR_BASE 0xFFFF800000000000ULL
|
#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_STATS_RING_SIZE 256U
|
||||||
#define CLKS_SYSCALL_USC_MAX_ALLOWED_APPS 64U
|
#define CLKS_SYSCALL_USC_MAX_ALLOWED_APPS 64U
|
||||||
|
|
||||||
@@ -131,6 +132,23 @@ struct clks_syscall_exec_io_req {
|
|||||||
u64 stderr_fd;
|
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_ready = CLKS_FALSE;
|
||||||
static clks_bool clks_syscall_user_trace_active = CLKS_FALSE;
|
static clks_bool clks_syscall_user_trace_active = CLKS_FALSE;
|
||||||
static u64 clks_syscall_user_trace_budget = 0ULL;
|
static u64 clks_syscall_user_trace_budget = 0ULL;
|
||||||
@@ -160,16 +178,55 @@ static inline void clks_syscall_outw(u16 port, u16 value) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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) {
|
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;
|
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;
|
return CLKS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i + 1U < dst_size) {
|
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;
|
dst[i] = ch;
|
||||||
|
|
||||||
if (ch == '\0') {
|
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;
|
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);
|
clks_memcpy((void *)dst_addr, src, copy_len);
|
||||||
((char *)dst_addr)[copy_len] = '\0';
|
((char *)dst_addr)[copy_len] = '\0';
|
||||||
return (u64)copy_len;
|
return (u64)copy_len;
|
||||||
@@ -228,6 +289,10 @@ static u64 clks_syscall_log_write(u64 arg0, u64 arg1) {
|
|||||||
len = CLKS_SYSCALL_LOG_MAX_LEN;
|
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++) {
|
for (i = 0ULL; i < len; i++) {
|
||||||
buf[i] = src[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;
|
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++) {
|
for (i = 0ULL; i < len; i++) {
|
||||||
buf[i] = src[i];
|
buf[i] = src[i];
|
||||||
}
|
}
|
||||||
@@ -277,6 +346,127 @@ static u64 clks_syscall_kbd_get_char(void) {
|
|||||||
return (u64)(u8)ch;
|
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) {
|
static u64 clks_syscall_fd_open(u64 arg0, u64 arg1, u64 arg2) {
|
||||||
char path[CLKS_SYSCALL_PATH_MAX];
|
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;
|
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);
|
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;
|
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);
|
return clks_exec_fd_write(arg0, (const void *)arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -878,6 +1076,10 @@ static u64 clks_syscall_kdbg_bt(u64 arg0) {
|
|||||||
return 0ULL;
|
return 0ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_syscall_user_ptr_readable(arg0, (u64)sizeof(req)) == CLKS_FALSE) {
|
||||||
|
return 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
clks_memcpy(&req, (const void *)arg0, sizeof(req));
|
clks_memcpy(&req, (const void *)arg0, sizeof(req));
|
||||||
|
|
||||||
if (req.out_ptr == 0ULL || req.out_size == 0ULL) {
|
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;
|
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) {
|
if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) {
|
||||||
return 0ULL;
|
return 0ULL;
|
||||||
}
|
}
|
||||||
@@ -1215,6 +1421,10 @@ static u64 clks_syscall_fs_read(u64 arg0, u64 arg1, u64 arg2) {
|
|||||||
return 0ULL;
|
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) {
|
if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) {
|
||||||
return 0ULL;
|
return 0ULL;
|
||||||
}
|
}
|
||||||
@@ -1309,6 +1519,10 @@ static u64 clks_syscall_exec_pathv_io(u64 arg0, u64 arg1, u64 arg2) {
|
|||||||
return (u64)-1;
|
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));
|
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) {
|
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);
|
u64 wait_ret = clks_exec_wait_pid(arg0, &status);
|
||||||
|
|
||||||
if (wait_ret == 1ULL && arg1 != 0ULL) {
|
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));
|
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;
|
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;
|
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;
|
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;
|
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;
|
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) {
|
if (clks_exec_proc_pid_at(arg0, &pid) == CLKS_FALSE) {
|
||||||
return 0ULL;
|
return 0ULL;
|
||||||
}
|
}
|
||||||
@@ -1452,6 +1681,10 @@ static u64 clks_syscall_proc_snapshot(u64 arg0, u64 arg1, u64 arg2) {
|
|||||||
return 0ULL;
|
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) {
|
if (clks_exec_proc_snapshot(arg0, &snap) == CLKS_FALSE) {
|
||||||
return 0ULL;
|
return 0ULL;
|
||||||
}
|
}
|
||||||
@@ -1602,6 +1835,10 @@ static u64 clks_syscall_fs_write_common(u64 arg0, u64 arg1, u64 arg2, clks_bool
|
|||||||
return 0ULL;
|
return 0ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_syscall_user_ptr_readable(arg1, arg2) == CLKS_FALSE) {
|
||||||
|
return 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
while (remaining > 0ULL) {
|
while (remaining > 0ULL) {
|
||||||
u64 chunk_len = remaining;
|
u64 chunk_len = remaining;
|
||||||
void *heap_copy;
|
void *heap_copy;
|
||||||
@@ -1668,6 +1905,10 @@ static u64 clks_syscall_log_journal_read(u64 arg0, u64 arg1, u64 arg2) {
|
|||||||
return 0ULL;
|
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) {
|
if (clks_log_journal_read(arg0, line, sizeof(line)) == CLKS_FALSE) {
|
||||||
return 0ULL;
|
return 0ULL;
|
||||||
}
|
}
|
||||||
@@ -2266,6 +2507,12 @@ u64 clks_syscall_dispatch(void *frame_ptr) {
|
|||||||
return clks_syscall_dl_close(frame->rbx);
|
return clks_syscall_dl_close(frame->rbx);
|
||||||
case CLKS_SYSCALL_DL_SYM:
|
case CLKS_SYSCALL_DL_SYM:
|
||||||
return clks_syscall_dl_sym(frame->rbx, frame->rcx);
|
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:
|
default:
|
||||||
return (u64)-1;
|
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. 全局返回规则
|
## 2. 全局返回规则
|
||||||
|
|
||||||
@@ -61,10 +61,10 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
|||||||
|
|
||||||
## 3. 当前实现中的长度/路径限制
|
## 3. 当前实现中的长度/路径限制
|
||||||
|
|
||||||
以下限制由内核 `clks/kernel/syscall.c` 当前实现决定:
|
以下限制由内核 `clks/kernel/runtime/syscall.c` 当前实现决定:
|
||||||
|
|
||||||
- 日志写入 `LOG_WRITE`:最大拷贝 `191` 字节。
|
- 日志写入 `LOG_WRITE`:最大拷贝 `191` 字节。
|
||||||
- TTY 文本写入 `TTY_WRITE`:最大拷贝 `512` 字节。
|
- TTY 文本写入 `TTY_WRITE`:最大拷贝 `2048` 字节。
|
||||||
- 文件读取 `FS_READ`:最多读取 `min(file_size, buffer_size)` 字节。
|
- 文件读取 `FS_READ`:最多读取 `min(file_size, buffer_size)` 字节。
|
||||||
- 文件写入 `FS_WRITE` / `FS_APPEND`:内核按 `65536` 字节分块搬运;这是实现分块大小,不是文件大小上限。
|
- 文件写入 `FS_WRITE` / `FS_APPEND`:内核按 `65536` 字节分块搬运;这是实现分块大小,不是文件大小上限。
|
||||||
- log journal 行读取缓冲:`256` 字节。
|
- log journal 行读取缓冲:`256` 字节。
|
||||||
@@ -83,7 +83,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
|||||||
- `/proc/<pid>`:指定 PID 快照文本
|
- `/proc/<pid>`:指定 PID 快照文本
|
||||||
- `/proc` 为只读;写入类 syscall 不支持。
|
- `/proc` 为只读;写入类 syscall 不支持。
|
||||||
|
|
||||||
## 4. Syscall 列表(0~76)
|
## 4. Syscall 列表(0~83)
|
||||||
|
|
||||||
### 0 `CLEONOS_SYSCALL_LOG_WRITE`
|
### 0 `CLEONOS_SYSCALL_LOG_WRITE`
|
||||||
|
|
||||||
@@ -604,6 +604,61 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
|||||||
- 返回:新 fd;失败 `-1`
|
- 返回:新 fd;失败 `-1`
|
||||||
- 说明:当前为“按值复制”语义(复制 flags/offset/目标对象)。
|
- 说明:当前为“按值复制”语义(复制 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. 用户态封装函数
|
## 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_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_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_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. 开发注意事项
|
## 6. 开发注意事项
|
||||||
|
|
||||||
@@ -639,6 +697,8 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
|||||||
|
|
||||||
## 7. Wine 兼容说明
|
## 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 在运行时崩溃场景下会生成与内核一致格式的“信号编码退出状态”,可通过 `WAITPID` 读取。
|
||||||
- Wine 当前音频 syscall 为占位实现:`AUDIO_AVAILABLE=0`,`AUDIO_PLAY_TONE=0`,`AUDIO_STOP=1`。
|
- 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