wip: experimental rust support in runtime
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
.cache
|
||||
.vscode
|
||||
build*
|
||||
.venv
|
||||
initrd/image.cpio
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
@@ -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,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");
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
@@ -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)
|
||||
Generated
+14
@@ -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",
|
||||
]
|
||||
@@ -0,0 +1,4 @@
|
||||
[workspace]
|
||||
members = ["rterm", "apps/rtest"]
|
||||
|
||||
resolver = "2"
|
||||
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "rtest"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
rterm = { path = "../../rterm" }
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "rterm"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
@@ -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());
|
||||
}
|
||||
Reference in New Issue
Block a user