From 8803d5a5d4ade86cd9d200f4539b65ff8c708a87 Mon Sep 17 00:00:00 2001 From: Leonmmcoset Date: Sat, 18 Apr 2026 18:03:52 +0800 Subject: [PATCH] /dev --- CMakeLists.txt | 2 +- cleonos/c/apps/fsstat_main.c | 1 + cleonos/c/apps/shell/shell_cmd.c | 1 + cleonos/c/apps/stats_main.c | 1 + clks/kernel/exec.c | 85 ++++++++++++++++++++++++++++++++ clks/kernel/fs.c | 8 ++- clks/kernel/shell.c | 1 + clks/kernel/syscall.c | 41 ++++++++++++++- docs/syscall.md | 2 +- ramdisk/README.txt | 1 + ramdisk/dev/null | 0 ramdisk/dev/random | 0 ramdisk/dev/tty | 0 ramdisk/dev/urandom | 0 ramdisk/dev/zero | 0 15 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 ramdisk/dev/null create mode 100644 ramdisk/dev/random create mode 100644 ramdisk/dev/tty create mode 100644 ramdisk/dev/urandom create mode 100644 ramdisk/dev/zero diff --git a/CMakeLists.txt b/CMakeLists.txt index b6e940c..8bdc1f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -636,7 +636,7 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E rm -rf "${RAMDISK_ROOT}" COMMAND ${CMAKE_COMMAND} -E make_directory "${RAMDISK_ROOT}" COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/ramdisk" "${RAMDISK_ROOT}" - COMMAND ${CMAKE_COMMAND} -E make_directory "${RAMDISK_ROOT}/system" "${RAMDISK_ROOT}/shell" "${RAMDISK_ROOT}/driver" + COMMAND ${CMAKE_COMMAND} -E make_directory "${RAMDISK_ROOT}/system" "${RAMDISK_ROOT}/shell" "${RAMDISK_ROOT}/driver" "${RAMDISK_ROOT}/dev" COMMAND ${CMAKE_COMMAND} -E copy "${KERNEL_SYMBOLS_FILE}" "${RAMDISK_ROOT}/system/kernel.sym" ${RAMDISK_COPY_COMMANDS} COMMAND ${CMAKE_COMMAND} -E touch "${RAMDISK_ROOT_STAMP}" diff --git a/cleonos/c/apps/fsstat_main.c b/cleonos/c/apps/fsstat_main.c index bf713aa..75040e3 100644 --- a/cleonos/c/apps/fsstat_main.c +++ b/cleonos/c/apps/fsstat_main.c @@ -7,6 +7,7 @@ static int ush_cmd_fsstat(void) { ush_print_kv_hex(" SHELL_CHILDREN", cleonos_sys_fs_child_count("/shell")); ush_print_kv_hex(" TEMP_CHILDREN", cleonos_sys_fs_child_count("/temp")); ush_print_kv_hex(" DRIVER_CHILDREN", cleonos_sys_fs_child_count("/driver")); + ush_print_kv_hex(" DEV_CHILDREN", cleonos_sys_fs_child_count("/dev")); return 1; } diff --git a/cleonos/c/apps/shell/shell_cmd.c b/cleonos/c/apps/shell/shell_cmd.c index 012e794..226ceed 100644 --- a/cleonos/c/apps/shell/shell_cmd.c +++ b/cleonos/c/apps/shell/shell_cmd.c @@ -2033,6 +2033,7 @@ static int ush_cmd_fsstat(void) { ush_print_kv_hex(" SHELL_CHILDREN", cleonos_sys_fs_child_count("/shell")); ush_print_kv_hex(" TEMP_CHILDREN", cleonos_sys_fs_child_count("/temp")); ush_print_kv_hex(" DRIVER_CHILDREN", cleonos_sys_fs_child_count("/driver")); + ush_print_kv_hex(" DEV_CHILDREN", cleonos_sys_fs_child_count("/dev")); return 1; } diff --git a/cleonos/c/apps/stats_main.c b/cleonos/c/apps/stats_main.c index 4049452..8c5cbd3 100644 --- a/cleonos/c/apps/stats_main.c +++ b/cleonos/c/apps/stats_main.c @@ -16,6 +16,7 @@ static int ush_cmd_fsstat(void) { ush_print_kv_hex(" SHELL_CHILDREN", cleonos_sys_fs_child_count("/shell")); ush_print_kv_hex(" TEMP_CHILDREN", cleonos_sys_fs_child_count("/temp")); ush_print_kv_hex(" DRIVER_CHILDREN", cleonos_sys_fs_child_count("/driver")); + ush_print_kv_hex(" DEV_CHILDREN", cleonos_sys_fs_child_count("/dev")); return 1; } diff --git a/clks/kernel/exec.c b/clks/kernel/exec.c index 6c48314..f082089 100644 --- a/clks/kernel/exec.c +++ b/clks/kernel/exec.c @@ -55,6 +55,9 @@ enum clks_exec_fd_kind { CLKS_EXEC_FD_KIND_NONE = 0, CLKS_EXEC_FD_KIND_TTY = 1, CLKS_EXEC_FD_KIND_FILE = 2, + CLKS_EXEC_FD_KIND_DEV_NULL = 3, + CLKS_EXEC_FD_KIND_DEV_ZERO = 4, + CLKS_EXEC_FD_KIND_DEV_RANDOM = 5, }; enum clks_exec_proc_state { @@ -159,6 +162,7 @@ static u64 clks_exec_requests = 0ULL; static u64 clks_exec_success = 0ULL; static u32 clks_exec_running_depth = 0U; static clks_bool clks_exec_pending_dispatch_active = CLKS_FALSE; +static u64 clks_exec_random_state = 0xA5A55A5A12345678ULL; static struct clks_exec_proc_record clks_exec_proc_table[CLKS_EXEC_MAX_PROCS]; static u64 clks_exec_next_pid = 1ULL; @@ -800,6 +804,34 @@ static clks_bool clks_exec_path_is_dev_tty(const char *path) { return (path != CLKS_NULL && clks_strcmp(path, "/dev/tty") == 0) ? CLKS_TRUE : CLKS_FALSE; } +static clks_bool clks_exec_path_is_dev_null(const char *path) { + return (path != CLKS_NULL && clks_strcmp(path, "/dev/null") == 0) ? CLKS_TRUE : CLKS_FALSE; +} + +static clks_bool clks_exec_path_is_dev_zero(const char *path) { + return (path != CLKS_NULL && clks_strcmp(path, "/dev/zero") == 0) ? CLKS_TRUE : CLKS_FALSE; +} + +static clks_bool clks_exec_path_is_dev_random(const char *path) { + if (path == CLKS_NULL) { + return CLKS_FALSE; + } + + if (clks_strcmp(path, "/dev/random") == 0) { + return CLKS_TRUE; + } + + return (clks_strcmp(path, "/dev/urandom") == 0) ? CLKS_TRUE : CLKS_FALSE; +} + +static u8 clks_exec_random_next_byte(void) { + clks_exec_random_state ^= (clks_interrupts_timer_ticks() + 0x9E3779B97F4A7C15ULL); + clks_exec_random_state ^= (clks_exec_random_state << 13); + clks_exec_random_state ^= (clks_exec_random_state >> 7); + clks_exec_random_state ^= (clks_exec_random_state << 17); + return (u8)(clks_exec_random_state & 0xFFULL); +} + static void clks_exec_fd_init_defaults(struct clks_exec_proc_record *proc) { if (proc == CLKS_NULL) { return; @@ -1457,6 +1489,7 @@ void clks_exec_init(void) { clks_exec_success = 0ULL; clks_exec_running_depth = 0U; clks_exec_pending_dispatch_active = CLKS_FALSE; + clks_exec_random_state = 0xA5A55A5A12345678ULL; clks_exec_next_pid = 1ULL; clks_exec_pid_stack_depth = 0U; clks_memset(clks_exec_pid_stack, 0, sizeof(clks_exec_pid_stack)); @@ -1647,6 +1680,29 @@ u64 clks_exec_fd_open(const char *path, u64 flags, u64 mode) { return (u64)fd_slot; } + if (clks_exec_path_is_dev_null(path) == CLKS_TRUE || + clks_exec_path_is_dev_zero(path) == CLKS_TRUE || + clks_exec_path_is_dev_random(path) == CLKS_TRUE) { + struct clks_exec_fd_entry *entry = &proc->fds[(u32)fd_slot]; + + clks_memset(entry, 0, sizeof(*entry)); + entry->used = CLKS_TRUE; + entry->flags = flags; + entry->offset = 0ULL; + entry->tty_index = proc->tty_index; + entry->path[0] = '\0'; + + if (clks_exec_path_is_dev_null(path) == CLKS_TRUE) { + entry->kind = CLKS_EXEC_FD_KIND_DEV_NULL; + } else if (clks_exec_path_is_dev_zero(path) == CLKS_TRUE) { + entry->kind = CLKS_EXEC_FD_KIND_DEV_ZERO; + } else { + entry->kind = CLKS_EXEC_FD_KIND_DEV_RANDOM; + } + + return (u64)fd_slot; + } + if (clks_fs_stat(path, &info) == CLKS_FALSE) { if ((flags & CLKS_EXEC_O_CREAT) == 0ULL || clks_exec_fd_can_write(flags) == CLKS_FALSE) { return (u64)-1; @@ -1722,6 +1778,28 @@ u64 clks_exec_fd_read(u64 fd, void *out_buffer, u64 size) { return count; } + if (entry->kind == CLKS_EXEC_FD_KIND_DEV_NULL) { + return 0ULL; + } + + if (entry->kind == CLKS_EXEC_FD_KIND_DEV_ZERO) { + clks_memset(out_buffer, 0, (usize)size); + entry->offset += size; + return size; + } + + if (entry->kind == CLKS_EXEC_FD_KIND_DEV_RANDOM) { + u8 *dst = (u8 *)out_buffer; + u64 i; + + for (i = 0ULL; i < size; i++) { + dst[(usize)i] = clks_exec_random_next_byte(); + } + + entry->offset += size; + return size; + } + if (entry->kind == CLKS_EXEC_FD_KIND_FILE) { return clks_exec_fd_file_read(entry, out_buffer, size); } @@ -1756,6 +1834,13 @@ u64 clks_exec_fd_write(u64 fd, const void *buffer, u64 size) { return size; } + if (entry->kind == CLKS_EXEC_FD_KIND_DEV_NULL || + entry->kind == CLKS_EXEC_FD_KIND_DEV_ZERO || + entry->kind == CLKS_EXEC_FD_KIND_DEV_RANDOM) { + entry->offset += size; + return size; + } + if (entry->kind == CLKS_EXEC_FD_KIND_FILE) { return clks_exec_fd_file_write(entry, buffer, size); } diff --git a/clks/kernel/fs.c b/clks/kernel/fs.c index 02447da..3d6806c 100644 --- a/clks/kernel/fs.c +++ b/clks/kernel/fs.c @@ -535,8 +535,12 @@ void clks_fs_init(void) { return; } + if (clks_fs_require_directory("/dev") == CLKS_FALSE) { + return; + } + clks_fs_ready = CLKS_TRUE; - clks_log(CLKS_LOG_INFO, "FS", "LAYOUT /SYSTEM /SHELL /TEMP /DRIVER OK"); + clks_log(CLKS_LOG_INFO, "FS", "LAYOUT /SYSTEM /SHELL /TEMP /DRIVER /DEV OK"); } clks_bool clks_fs_is_ready(void) { @@ -915,4 +919,4 @@ u64 clks_fs_node_count(void) { } return used; -} \ No newline at end of file +} diff --git a/clks/kernel/shell.c b/clks/kernel/shell.c index 7aacc86..49f0ddc 100644 --- a/clks/kernel/shell.c +++ b/clks/kernel/shell.c @@ -1173,6 +1173,7 @@ static clks_bool clks_shell_cmd_fsstat(void) { clks_shell_print_kv_hex(" SHELL_CHILDREN", clks_fs_count_children("/shell")); clks_shell_print_kv_hex(" TEMP_CHILDREN", clks_fs_count_children("/temp")); clks_shell_print_kv_hex(" DRIVER_CHILDREN", clks_fs_count_children("/driver")); + clks_shell_print_kv_hex(" DEV_CHILDREN", clks_fs_count_children("/dev")); return CLKS_TRUE; } diff --git a/clks/kernel/syscall.c b/clks/kernel/syscall.c index d29b3b7..7d36d12 100644 --- a/clks/kernel/syscall.c +++ b/clks/kernel/syscall.c @@ -279,6 +279,20 @@ static clks_bool clks_syscall_procfs_is_root(const char *path) { return (path != CLKS_NULL && clks_strcmp(path, "/proc") == 0) ? CLKS_TRUE : CLKS_FALSE; } +static clks_bool clks_syscall_fs_is_root(const char *path) { + return (path != CLKS_NULL && clks_strcmp(path, "/") == 0) ? CLKS_TRUE : CLKS_FALSE; +} + +static clks_bool clks_syscall_fs_has_real_proc_dir(void) { + struct clks_fs_node_info info; + + if (clks_fs_stat("/proc", &info) == CLKS_FALSE) { + return CLKS_FALSE; + } + + return (info.type == CLKS_FS_NODE_DIR) ? CLKS_TRUE : CLKS_FALSE; +} + static clks_bool clks_syscall_procfs_is_self(const char *path) { return (path != CLKS_NULL && clks_strcmp(path, "/proc/self") == 0) ? CLKS_TRUE : CLKS_FALSE; } @@ -1059,6 +1073,7 @@ static clks_bool clks_syscall_procfs_render_file(const char *path, static u64 clks_syscall_fs_child_count(u64 arg0) { char path[CLKS_SYSCALL_PATH_MAX]; + u64 base_count; if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) { return (u64)-1; @@ -1068,7 +1083,17 @@ static u64 clks_syscall_fs_child_count(u64 arg0) { return 2ULL + clks_exec_proc_count(); } - return clks_fs_count_children(path); + base_count = clks_fs_count_children(path); + + if (base_count == (u64)-1) { + return (u64)-1; + } + + if (clks_syscall_fs_is_root(path) == CLKS_TRUE && clks_syscall_fs_has_real_proc_dir() == CLKS_FALSE) { + return base_count + 1ULL; + } + + return base_count; } static u64 clks_syscall_fs_get_child_name(u64 arg0, u64 arg1, u64 arg2) { @@ -1117,6 +1142,20 @@ static u64 clks_syscall_fs_get_child_name(u64 arg0, u64 arg1, u64 arg2) { } } + if (clks_syscall_fs_is_root(path) == CLKS_TRUE && clks_syscall_fs_has_real_proc_dir() == CLKS_FALSE) { + if (arg1 == 0ULL) { + clks_memset((void *)arg2, 0, CLKS_SYSCALL_NAME_MAX); + clks_memcpy((void *)arg2, "proc", 5U); + return 1ULL; + } + + if (clks_fs_get_child_name(path, arg1 - 1ULL, (char *)arg2, (usize)CLKS_SYSCALL_NAME_MAX) == CLKS_FALSE) { + return 0ULL; + } + + return 1ULL; + } + if (clks_fs_get_child_name(path, arg1, (char *)arg2, (usize)CLKS_SYSCALL_NAME_MAX) == CLKS_FALSE) { return 0ULL; } diff --git a/docs/syscall.md b/docs/syscall.md index b9e27f4..e73834c 100644 --- a/docs/syscall.md +++ b/docs/syscall.md @@ -565,7 +565,7 @@ u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2); - `arg2`: `u64 mode`(当前保留) - 返回:成功返回 `fd`,失败返回 `-1` - 说明: -- 当前支持普通文件与 `/dev/tty`。 +- 当前支持普通文件与设备文件:`/dev/tty`、`/dev/null`、`/dev/zero`、`/dev/random`、`/dev/urandom`。 - 默认进程会预置 `fd 0/1/2`(stdin/stdout/stderr)。 - 标志位兼容子集:`O_RDONLY/O_WRONLY/O_RDWR/O_CREAT/O_TRUNC/O_APPEND`。 diff --git a/ramdisk/README.txt b/ramdisk/README.txt index 52ab0d8..ad93e25 100644 --- a/ramdisk/README.txt +++ b/ramdisk/README.txt @@ -4,6 +4,7 @@ CLeonOS ramdisk root layout /shell : user shell and command ELF apps /temp : runtime temp/cache files /driver : hardware and peripheral drivers +/dev : device interface nodes (/dev/tty, /dev/null, /dev/zero, /dev/random) Root ELF demos: /hello.elf : Hello world user ELF diff --git a/ramdisk/dev/null b/ramdisk/dev/null new file mode 100644 index 0000000..e69de29 diff --git a/ramdisk/dev/random b/ramdisk/dev/random new file mode 100644 index 0000000..e69de29 diff --git a/ramdisk/dev/tty b/ramdisk/dev/tty new file mode 100644 index 0000000..e69de29 diff --git a/ramdisk/dev/urandom b/ramdisk/dev/urandom new file mode 100644 index 0000000..e69de29 diff --git a/ramdisk/dev/zero b/ramdisk/dev/zero new file mode 100644 index 0000000..e69de29