mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 18:44:01 +00:00
Stage 23
This commit is contained in:
@@ -93,6 +93,7 @@ set(USER_OBJ_ROOT "${USER_BUILD_ROOT}/obj")
|
|||||||
set(USER_APP_DIR "${USER_BUILD_ROOT}/apps")
|
set(USER_APP_DIR "${USER_BUILD_ROOT}/apps")
|
||||||
set(USER_LIB_DIR "${USER_BUILD_ROOT}/lib")
|
set(USER_LIB_DIR "${USER_BUILD_ROOT}/lib")
|
||||||
set(USER_RUST_LIB "${USER_LIB_DIR}/libcleonos_user_rust.a")
|
set(USER_RUST_LIB "${USER_LIB_DIR}/libcleonos_user_rust.a")
|
||||||
|
set(KERNEL_RUST_LIB "${BUILD_ROOT}/libclks_kernel_rust.a")
|
||||||
|
|
||||||
resolve_tool_with_fallback(CC gcc cc clang)
|
resolve_tool_with_fallback(CC gcc cc clang)
|
||||||
resolve_tool_with_fallback(LD ld.lld ld)
|
resolve_tool_with_fallback(LD ld.lld ld)
|
||||||
@@ -299,11 +300,19 @@ foreach(SRC IN LISTS ASM_SOURCES)
|
|||||||
add_kernel_asm_object("${SRC}" KERNEL_OBJECTS)
|
add_kernel_asm_object("${SRC}" KERNEL_OBJECTS)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${KERNEL_RUST_LIB}"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${BUILD_ROOT}"
|
||||||
|
COMMAND ${RUSTC} --crate-type staticlib -C panic=abort -O "${CMAKE_SOURCE_DIR}/clks/rust/src/lib.rs" -o "${KERNEL_RUST_LIB}"
|
||||||
|
DEPENDS "${CMAKE_SOURCE_DIR}/clks/rust/src/lib.rs"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT "${KERNEL_ELF}"
|
OUTPUT "${KERNEL_ELF}"
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${BUILD_ROOT}"
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${BUILD_ROOT}"
|
||||||
COMMAND ${LD} ${LDFLAGS_COMMON} -T "${LINKER_SCRIPT}" -o "${KERNEL_ELF}" ${KERNEL_OBJECTS}
|
COMMAND ${LD} ${LDFLAGS_COMMON} -T "${LINKER_SCRIPT}" -o "${KERNEL_ELF}" ${KERNEL_OBJECTS} "${KERNEL_RUST_LIB}"
|
||||||
DEPENDS ${KERNEL_OBJECTS} "${LINKER_SCRIPT}"
|
DEPENDS ${KERNEL_OBJECTS} "${LINKER_SCRIPT}" "${KERNEL_RUST_LIB}" "${CMAKE_SOURCE_DIR}/clks/rust/src/lib.rs"
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ void clks_kernel_main(void) {
|
|||||||
clks_tty_init();
|
clks_tty_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS Stage22 START");
|
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS Stage23 START");
|
||||||
|
|
||||||
if (boot_fb == CLKS_NULL) {
|
if (boot_fb == CLKS_NULL) {
|
||||||
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
|
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ static u64 clks_shell_cmd_ok = 0ULL;
|
|||||||
static u64 clks_shell_cmd_fail = 0ULL;
|
static u64 clks_shell_cmd_fail = 0ULL;
|
||||||
static u64 clks_shell_cmd_unknown = 0ULL;
|
static u64 clks_shell_cmd_unknown = 0ULL;
|
||||||
|
|
||||||
|
extern void clks_rusttest_hello(void);
|
||||||
|
|
||||||
static clks_bool clks_shell_is_space(char ch) {
|
static clks_bool clks_shell_is_space(char ch) {
|
||||||
return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') ? CLKS_TRUE : CLKS_FALSE;
|
return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') ? CLKS_TRUE : CLKS_FALSE;
|
||||||
}
|
}
|
||||||
@@ -693,6 +695,7 @@ static clks_bool clks_shell_cmd_help(void) {
|
|||||||
clks_shell_writeln(" memstat / fsstat / taskstat");
|
clks_shell_writeln(" memstat / fsstat / taskstat");
|
||||||
clks_shell_writeln(" dmesg [n]");
|
clks_shell_writeln(" dmesg [n]");
|
||||||
clks_shell_writeln(" shstat");
|
clks_shell_writeln(" shstat");
|
||||||
|
clks_shell_writeln(" rusttest");
|
||||||
clks_shell_writeln(" exec <path|name>");
|
clks_shell_writeln(" exec <path|name>");
|
||||||
clks_shell_writeln(" clear");
|
clks_shell_writeln(" clear");
|
||||||
clks_shell_writeln(" kbdstat");
|
clks_shell_writeln(" kbdstat");
|
||||||
@@ -1201,6 +1204,11 @@ static clks_bool clks_shell_cmd_shstat(void) {
|
|||||||
return CLKS_TRUE;
|
return CLKS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static clks_bool clks_shell_cmd_rusttest(void) {
|
||||||
|
clks_rusttest_hello();
|
||||||
|
return CLKS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void clks_shell_execute_line(const char *line) {
|
static void clks_shell_execute_line(const char *line) {
|
||||||
char line_buf[CLKS_SHELL_LINE_MAX];
|
char line_buf[CLKS_SHELL_LINE_MAX];
|
||||||
char cmd[CLKS_SHELL_CMD_MAX];
|
char cmd[CLKS_SHELL_CMD_MAX];
|
||||||
@@ -1261,6 +1269,8 @@ static void clks_shell_execute_line(const char *line) {
|
|||||||
success = clks_shell_cmd_dmesg(arg);
|
success = clks_shell_cmd_dmesg(arg);
|
||||||
} else if (clks_shell_streq(cmd, "shstat") == CLKS_TRUE) {
|
} else if (clks_shell_streq(cmd, "shstat") == CLKS_TRUE) {
|
||||||
success = clks_shell_cmd_shstat();
|
success = clks_shell_cmd_shstat();
|
||||||
|
} else if (clks_shell_streq(cmd, "rusttest") == CLKS_TRUE) {
|
||||||
|
success = clks_shell_cmd_rusttest();
|
||||||
} else if (clks_shell_streq(cmd, "exec") == CLKS_TRUE || clks_shell_streq(cmd, "run") == CLKS_TRUE) {
|
} else if (clks_shell_streq(cmd, "exec") == CLKS_TRUE || clks_shell_streq(cmd, "run") == CLKS_TRUE) {
|
||||||
success = clks_shell_cmd_exec(arg);
|
success = clks_shell_cmd_exec(arg);
|
||||||
} else if (clks_shell_streq(cmd, "clear") == CLKS_TRUE) {
|
} else if (clks_shell_streq(cmd, "clear") == CLKS_TRUE) {
|
||||||
|
|||||||
32
clks/lib/libc_compat.c
Normal file
32
clks/lib/libc_compat.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include <clks/string.h>
|
||||||
|
#include <clks/types.h>
|
||||||
|
|
||||||
|
void *memcpy(void *dst, const void *src, usize count) {
|
||||||
|
return clks_memcpy(dst, src, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memmove(void *dst, const void *src, usize count) {
|
||||||
|
return clks_memmove(dst, src, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memset(void *dst, int value, usize count) {
|
||||||
|
return clks_memset(dst, value, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int memcmp(const void *left, const void *right, usize count) {
|
||||||
|
const u8 *a = (const u8 *)left;
|
||||||
|
const u8 *b = (const u8 *)right;
|
||||||
|
usize i;
|
||||||
|
|
||||||
|
for (i = 0U; i < count; i++) {
|
||||||
|
if (a[i] != b[i]) {
|
||||||
|
return (a[i] < b[i]) ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bcmp(const void *left, const void *right, usize count) {
|
||||||
|
return memcmp(left, right, count);
|
||||||
|
}
|
||||||
27
clks/rust/src/lib.rs
Normal file
27
clks/rust/src/lib.rs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#![no_std]
|
||||||
|
|
||||||
|
use core::hint::spin_loop;
|
||||||
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn clks_tty_write(text: *const i8);
|
||||||
|
}
|
||||||
|
|
||||||
|
const RUSTTEST_TEXT: &[u8] = b"Hello world!\n\0";
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn clks_rusttest_hello() {
|
||||||
|
unsafe {
|
||||||
|
clks_tty_write(RUSTTEST_TEXT.as_ptr() as *const i8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(_info: &PanicInfo) -> ! {
|
||||||
|
loop {
|
||||||
|
spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rust_eh_personality() {}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
- `stage20.md`
|
- `stage20.md`
|
||||||
- `stage21.md`
|
- `stage21.md`
|
||||||
- `stage22.md`
|
- `stage22.md`
|
||||||
|
- `stage23.md`
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- Stage docs use a fixed template: goal, implementation, acceptance criteria, build targets, QEMU command, and debugging notes.
|
- Stage docs use a fixed template: goal, implementation, acceptance criteria, build targets, QEMU command, and debugging notes.
|
||||||
|
|||||||
47
docs/stage23.md
Normal file
47
docs/stage23.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# CLeonOS Stage23
|
||||||
|
|
||||||
|
## Stage Goal
|
||||||
|
- Add a kernel shell command `rusttest`.
|
||||||
|
- Implement `rusttest` logic in Rust (`no_std`) instead of C.
|
||||||
|
- Link Rust object into the kernel ELF so command runs in kernel mode.
|
||||||
|
|
||||||
|
## What Was Implemented
|
||||||
|
- Kernel Rust source added:
|
||||||
|
- `clks/rust/src/lib.rs`
|
||||||
|
- exports `clks_rusttest_hello()`
|
||||||
|
- output text: `Hello world!`
|
||||||
|
- Kernel build integration (CMake):
|
||||||
|
- build `libclks_kernel_rust.a`
|
||||||
|
- link kernel ELF with `${KERNEL_RUST_LIB}`
|
||||||
|
- Shell integration:
|
||||||
|
- add command `rusttest`
|
||||||
|
- `rusttest` calls Rust symbol `clks_rusttest_hello()`
|
||||||
|
- Compatibility symbols for Rust link:
|
||||||
|
- add `clks/lib/libc_compat.c` for `memcpy/memset/memmove/memcmp/bcmp`
|
||||||
|
- Stage banner updated:
|
||||||
|
- `CLEONOS Stage23 START`
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- Kernel boots and prints `CLEONOS Stage23 START`.
|
||||||
|
- `help` contains `rusttest`.
|
||||||
|
- Running `rusttest` prints exactly:
|
||||||
|
- `Hello world!`
|
||||||
|
- No regression to existing shell commands.
|
||||||
|
|
||||||
|
## Build Targets
|
||||||
|
- `make setup`
|
||||||
|
- `make userapps`
|
||||||
|
- `make iso`
|
||||||
|
- `make run`
|
||||||
|
- `make debug`
|
||||||
|
|
||||||
|
## QEMU Command
|
||||||
|
- `qemu-system-x86_64 -M q35 -m 1024M -cdrom build/CLeonOS-x86_64.iso -serial stdio`
|
||||||
|
|
||||||
|
## Common Bugs and Debugging
|
||||||
|
- Rust link undefined symbols (`memcpy/memset/...`):
|
||||||
|
- Ensure `clks/lib/libc_compat.c` is included in kernel source set.
|
||||||
|
- Panic-related undefined symbol:
|
||||||
|
- Ensure Rust file keeps `#[panic_handler]` and `rust_eh_personality` stub.
|
||||||
|
- `rusttest` command not found:
|
||||||
|
- Confirm `help` output includes `rusttest` and shell dispatch branch exists.
|
||||||
Reference in New Issue
Block a user