wip: experimental rust support in runtime

This commit is contained in:
Karina
2026-04-13 23:40:41 +04:00
parent 4909e40cb1
commit b44e1924ed
15 changed files with 190 additions and 12 deletions
+1
View File
@@ -1,4 +1,5 @@
.cache
.vscode
build*
.venv
initrd/image.cpio
+2 -1
View File
@@ -34,6 +34,7 @@ set(SYSTEM_SERVICES
init
debug
termosh
rtest
)
set(VOLUME_ROOT "${CMAKE_BINARY_DIR}/StartupVolume")
@@ -70,7 +71,7 @@ endif()
if(QEMU_EXE)
add_custom_target(run
COMMAND ${QEMU_EXE}
-enable-kvm
#-enable-kvm
-bios ${OVMF_PATH}
-drive file=${IMG_FILE},format=raw
-vga std
+1
View File
@@ -9,5 +9,6 @@ message(STATUS "Building termOS's userspace")
add_subdirectory(libterm)
add_subdirectory(init)
add_subdirectory(rust)
add_subdirectory(debug)
add_subdirectory(termosh)
+1 -8
View File
@@ -1,12 +1,5 @@
#include <termOS.h>
int main() {
for (int i = 0; i < 100; i++) {
UInt64 pid = ProcessSpawn("/System/CoreServices/debug");
if (pid < 0) {
ConsolePrint("[PIDSPAMMER] Error %d\n", pid);
} else {
ConsolePrint("[PIDSPAMMER] %d spawned\n", pid);
}
}
ConsolePrint("Test test test \n Meow meow meow \n");
}
+3
View File
@@ -5,10 +5,13 @@
#include <Types.h>
enum {
kConsoleInput = 0,
kConsoleOutput = 1,
kConsoleEOF = -1,
kConsoleDefaultBufferSize = 1024
};
Int32 ConsolePrintString(const char* string);
Int32 ConsolePrint(const char* format, ...);
Int32 StringFormat(char* destination, UInt64 size, const char* format, ...);
Int32 ConsoleGetCharacter();
+7 -3
View File
@@ -9,7 +9,7 @@ extern UInt64 OSServiceIORead(UInt64 fileDescriptor, void* buffer, UInt64 length
extern UInt64 OSServiceIOWrite(UInt64 fileDescriptor, const void* buffer, UInt64 length);
static void sConsoleWriteCharacter(char character) {
OSServiceIOWrite(1, &character, 1);
OSServiceIOWrite(kConsoleOutput, &character, 1);
}
static inline void sConsoleBufferAdd(char* string, UInt64 size, UInt64* written, char character) {
@@ -105,6 +105,10 @@ Int32 StringFormat(char* destination, usize size, const char* format, ...) {
return returnValue;
}
Int32 ConsolePrintString(const char* string) {
return OSServiceIOWrite(kConsoleOutput, string, StringGetLength(string));
}
Int32 ConsolePrint(const char *format, ...) {
char buffer[kConsoleDefaultBufferSize];
va_list args;
@@ -114,14 +118,14 @@ Int32 ConsolePrint(const char *format, ...) {
va_end(args);
UInt64 writeLength = ((UInt64)length < sizeof(buffer)) ? length : (sizeof(buffer) - 1);
OSServiceIOWrite(1, buffer, writeLength);
OSServiceIOWrite(kConsoleOutput, buffer, writeLength);
return (int)writeLength;
}
Int32 ConsoleGetCharacter() {
char character;
UInt64 serviceCallResult = OSServiceIORead(0, &character, 1);
UInt64 serviceCallResult = OSServiceIORead(kConsoleInput, &character, 1);
if (serviceCallResult <= 0) return kConsoleEOF;
return (int)(unsigned char)character;
}
+9
View File
@@ -0,0 +1,9 @@
[build]
target = "x86_64-unknown-none"
[target.x86_64-unknown-none]
rustflags = [
"-C", "code-model=small",
"-C", "relocation-model=static",
"-C", "no-redzone=y",
]
+42
View File
@@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 3.16)
project(rustApps LANGUAGES C ASM_NASM)
function(add_rust_app NAME)
set(RUST_LIB_FILE "${CMAKE_CURRENT_SOURCE_DIR}/target/x86_64-unknown-none/release/lib${NAME}.a")
add_custom_target(cargo_build_${NAME} ALL
COMMAND cargo build --package ${NAME} --release
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
BYPRODUCTS ${RUST_LIB_FILE}
COMMENT "Cargo: Building bare-metal Rust app '${NAME}'..."
)
add_library(rust_lib_${NAME} STATIC IMPORTED)
set_target_properties(rust_lib_${NAME} PROPERTIES IMPORTED_LOCATION ${RUST_LIB_FILE})
add_dependencies(rust_lib_${NAME} cargo_build_${NAME})
add_executable(${NAME} $<TARGET_OBJECTS:RuntimeEntryObject>)
set_target_properties(${NAME} PROPERTIES LINKER_LANGUAGE C)
target_link_libraries(${NAME} PRIVATE rust_lib_${NAME} term)
target_link_options(${NAME} PRIVATE
-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld
-nostdlib
-static
-mno-red-zone
)
set(ELF2HOT_DIR "${CMAKE_SOURCE_DIR}/tools/elf2hot")
set(STARTUP_VOLUME_DIR "${CMAKE_BINARY_DIR}/StartupVolume/System/CoreServices")
file(MAKE_DIRECTORY "${STARTUP_VOLUME_DIR}")
set(FINAL_HOT_PATH "${STARTUP_VOLUME_DIR}/${NAME}")
add_custom_command(TARGET ${NAME} POST_BUILD
COMMAND cargo run --release --quiet -- $<TARGET_FILE:${NAME}> ${FINAL_HOT_PATH}
WORKING_DIRECTORY ${ELF2HOT_DIR}
COMMENT "elf2hot: Converting ${NAME} to HOT! format..."
VERBATIM
)
endfunction()
add_rust_app(rtest)
+14
View File
@@ -0,0 +1,14 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "rterm"
version = "0.1.0"
[[package]]
name = "rtest"
version = "0.1.0"
dependencies = [
"rterm",
]
+4
View File
@@ -0,0 +1,4 @@
[workspace]
members = ["rterm", "apps/rtest"]
resolver = "2"
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "rtest"
version = "0.1.0"
edition = "2024"
[lib]
crate-type = ["staticlib"]
[dependencies]
rterm = { path = "../../rterm" }
+19
View File
@@ -0,0 +1,19 @@
#![no_std]
extern crate alloc;
use alloc::string::String;
use alloc::vec::Vec;
extern crate rterm;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn main() -> i32 {
let mut my_vec = Vec::new();
my_vec.push(1);
my_vec.push(2);
let text = String::from("Hello from zalupa!");
rterm::print_str(&text);
0
}
+35
View File
@@ -0,0 +1,35 @@
ENTRY(_start)
SECTIONS
{
. = 0x400000;
.text : {
*(.text)
}
.rodata : {
*(.rodata)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
*(COMMON)
}
/DISCARD/ : {
*(.note.gnu.build-id)
*(.note.GNU-stack)
*(.note.gnu.property)
*(.comment)
*(.interp)
*(.dynsym)
*(.dynstr)
*(.hash)
*(.gnu.hash)
}
}
+6
View File
@@ -0,0 +1,6 @@
[package]
name = "rterm"
version = "0.1.0"
edition = "2024"
[dependencies]
+36
View File
@@ -0,0 +1,36 @@
#![no_std]
extern crate alloc;
use core::panic::PanicInfo;
use core::alloc::{GlobalAlloc, Layout};
unsafe extern "C" {
fn MemoryAllocate(size: usize) -> *mut u8;
fn MemoryFree(ptr: *mut u8);
fn ConsolePrintString(s: *const u8);
}
struct TermosAllocator;
unsafe impl GlobalAlloc for TermosAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
MemoryAllocate(layout.size())
}
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
MemoryFree(ptr);
}
}
#[global_allocator]
static ALLOCATOR: TermosAllocator = TermosAllocator;
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
pub unsafe fn print_str(s: &str) {
ConsolePrintString(s.as_ptr());
}