Add the rust std as a custom sysroot
This commit is contained in:
@@ -3,10 +3,9 @@ target = "riscv64.json"
|
||||
|
||||
[unstable]
|
||||
json-target-spec = true
|
||||
build-std = ["core", "compiler_builtins", "alloc"]
|
||||
build-std-features = ["compiler-builtins-mem"]
|
||||
|
||||
[target.riscv64]
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tilm.ld",
|
||||
"--sysroot", "sysroot"
|
||||
]
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,3 +7,5 @@
|
||||
disk.img
|
||||
**/*.mem
|
||||
mnt
|
||||
|
||||
sysroot/lib/rustlib/riscv64
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "library/backtrace"]
|
||||
path = library/backtrace
|
||||
url = https://github.com/rust-lang/backtrace-rs.git
|
||||
@@ -1,6 +1,7 @@
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["crates/bytes-struct","crates/io","crates/os-std", "crates/shared", "user/*"]
|
||||
members = [ "user/*"]
|
||||
exclude = ["library"]
|
||||
|
||||
[package]
|
||||
name = "kernel-rust"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#![feature(iterator_try_collect, iter_order_by)]
|
||||
#![allow(unused_features)]
|
||||
#![cfg_attr(any(not(feature = "std"), target_arch = "riscv64"), no_std)]
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
@@ -7,6 +7,6 @@ edition = "2024"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
image = "0.25"
|
||||
image = { version = "0.25", default-features = false, features = ["png"] }
|
||||
syn = { version = "2", features = ["full"] }
|
||||
zyn = "0.5"
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
[package]
|
||||
name = "os-std-macros"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = { version = "2", features = ["full"] }
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
[package]
|
||||
name = "os-std"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
os-std-macros = { path = "../os-std-macros" }
|
||||
shared = { path = "../shared", features = ["user"] }
|
||||
io = { path = "../io", features = ["alloc"] }
|
||||
@@ -1 +0,0 @@
|
||||
pub use io::SeekFrom;
|
||||
@@ -1,62 +0,0 @@
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
pub mod io;
|
||||
pub mod prelude;
|
||||
|
||||
pub use shared::fs;
|
||||
pub use shared::syscall;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! custom_std_setup {
|
||||
() => {
|
||||
use $crate::prelude::*;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
struct GlobalAllocator;
|
||||
|
||||
#[global_allocator]
|
||||
static GLOBAL_ALLOCATOR: GlobalAllocator = GlobalAllocator;
|
||||
|
||||
unsafe impl core::alloc::GlobalAlloc for GlobalAllocator {
|
||||
unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
|
||||
$crate::syscall::alloc(layout)
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: core::alloc::Layout) {
|
||||
$crate::syscall::dealloc(ptr, layout)
|
||||
}
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_panic_info: &core::panic::PanicInfo) -> ! {
|
||||
// TODO print
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn _start() {
|
||||
main()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($args:expr),*) => {
|
||||
$crate::syscall::write_string_temp(&format!($($args),*))
|
||||
};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! println {
|
||||
() => {
|
||||
$crate::print!("");
|
||||
// $crate::print!("\n\r");
|
||||
};
|
||||
($($args:expr),*) => {
|
||||
$crate::print!($($args),*);
|
||||
// $crate::println!();
|
||||
};
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
pub use crate::print;
|
||||
pub use crate::println;
|
||||
pub use alloc::format;
|
||||
pub use alloc::string::String;
|
||||
pub use alloc::vec;
|
||||
@@ -1,3 +1,7 @@
|
||||
use io::{IoBase, Read, Write};
|
||||
|
||||
use crate::syscall;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct File {
|
||||
fd: u64,
|
||||
@@ -6,7 +10,7 @@ pub struct File {
|
||||
impl File {
|
||||
/// # Safety
|
||||
/// The file descriptor must be valid
|
||||
pub unsafe fn new(fd: u64) -> Self {
|
||||
pub unsafe fn from_raw_fd(fd: u64) -> Self {
|
||||
Self { fd }
|
||||
}
|
||||
|
||||
@@ -14,3 +18,23 @@ impl File {
|
||||
self.fd
|
||||
}
|
||||
}
|
||||
|
||||
impl IoBase for File {
|
||||
type Error = ();
|
||||
}
|
||||
|
||||
impl Read for File {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
||||
Ok(syscall::read(self.as_fd(), buf) as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for File {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
||||
Ok(syscall::write(self.as_fd(), buf) as usize)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,12 @@ pub enum SysCall {
|
||||
Read = 0,
|
||||
Write = 1,
|
||||
Open = 2,
|
||||
Close = 3,
|
||||
Seek = 8,
|
||||
Alloc = 40,
|
||||
Dealloc = 41,
|
||||
Spawn = 58,
|
||||
ExecVE = 59,
|
||||
Exit = 60,
|
||||
NanoSleep = 101,
|
||||
WriteIntTemp = 998,
|
||||
@@ -26,9 +29,12 @@ impl From<u64> for SysCall {
|
||||
0 => SysCall::Read,
|
||||
1 => SysCall::Write,
|
||||
2 => SysCall::Open,
|
||||
3 => SysCall::Close,
|
||||
8 => SysCall::Seek,
|
||||
40 => SysCall::Alloc,
|
||||
41 => SysCall::Dealloc,
|
||||
58 => SysCall::Spawn,
|
||||
59 => SysCall::ExecVE,
|
||||
60 => SysCall::Exit,
|
||||
101 => SysCall::NanoSleep,
|
||||
998 => SysCall::WriteIntTemp,
|
||||
@@ -143,30 +149,53 @@ pub fn open<P: AsRef<Path>>(path: P) -> File {
|
||||
let ptr = path_str.as_ptr();
|
||||
let size = path_str.len();
|
||||
let (fd, ..) = syscall!(SysCall::Open, ptr as u64, size as u64);
|
||||
File::new(fd)
|
||||
File::from_raw_fd(fd)
|
||||
}
|
||||
}
|
||||
pub fn write(file: &mut File, buf: &[u8]) {
|
||||
pub fn close(file_descriptor: u64) {
|
||||
unsafe {
|
||||
syscall!(SysCall::Close, file_descriptor);
|
||||
}
|
||||
}
|
||||
pub fn write(file_descriptor: u64, buf: &[u8]) -> u64 {
|
||||
unsafe {
|
||||
let ptr = buf.as_ptr();
|
||||
let size = buf.len();
|
||||
syscall!(SysCall::Write, file.as_fd(), ptr as u64, size as u64);
|
||||
let (len, ..) = syscall!(SysCall::Write, file_descriptor, ptr as u64, size as u64);
|
||||
len
|
||||
}
|
||||
}
|
||||
pub fn read(file: &mut File, buf: &mut [u8]) {
|
||||
pub fn read(file_descriptor: u64, buf: &mut [u8]) -> u64 {
|
||||
unsafe {
|
||||
let ptr = buf.as_ptr();
|
||||
let size = buf.len();
|
||||
syscall!(SysCall::Read, file.as_fd(), ptr as u64, size as u64);
|
||||
let (len, ..) = syscall!(SysCall::Read, file_descriptor, ptr as u64, size as u64);
|
||||
len
|
||||
}
|
||||
}
|
||||
pub fn seek(file: &mut File, seek: SeekFrom) {
|
||||
pub fn seek(file_descriptor: u64, seek: SeekFrom) {
|
||||
unsafe {
|
||||
let (discriminant, value) = match seek {
|
||||
SeekFrom::Start(v) => (0, v),
|
||||
SeekFrom::End(v) => (1, v as u64),
|
||||
SeekFrom::Current(v) => (2, v as u64),
|
||||
};
|
||||
syscall!(SysCall::Seek, file.as_fd(), discriminant, value);
|
||||
syscall!(SysCall::Seek, file_descriptor, discriminant, value);
|
||||
}
|
||||
}
|
||||
pub fn spawn<P: AsRef<Path>>(path: P) {
|
||||
unsafe {
|
||||
let path_str = path.as_ref().as_str();
|
||||
let ptr = path_str.as_ptr();
|
||||
let size = path_str.len();
|
||||
syscall!(SysCall::Spawn, ptr as u64, size as u64);
|
||||
}
|
||||
}
|
||||
pub fn execve<P: AsRef<Path>>(path: P) {
|
||||
unsafe {
|
||||
let path_str = path.as_ref().as_str();
|
||||
let ptr = path_str.as_ptr();
|
||||
let size = path_str.len();
|
||||
syscall!(SysCall::ExecVE, ptr as u64, size as u64);
|
||||
}
|
||||
}
|
||||
|
||||
2
ilm.ld
2
ilm.ld
@@ -5,7 +5,7 @@ OUTPUT_ARCH(riscv)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY {
|
||||
RAM (wxa) : ORIGIN = 0x80000000, LENGTH = 128M
|
||||
RAM (wxa) : ORIGIN = 0x80000000, LENGTH = 512M
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
|
||||
15
justfile
15
justfile
@@ -12,13 +12,19 @@ mount_filesystem:
|
||||
sync_filesystem:
|
||||
sync
|
||||
|
||||
update-std:
|
||||
@cd library/std && just update-std
|
||||
|
||||
build-sysroot:
|
||||
@cd library/std && just build-sysroot
|
||||
|
||||
build_user_prog prog:
|
||||
RUSTFLAGS="-C relocation-model=pic -C link-arg=-Tuser.ld -C link-arg=-pie" cargo b {{ cargo_flags }} --package {{ prog }}
|
||||
RUSTFLAGS="-C relocation-model=pic -C link-arg=-pie --sysroot {{ justfile_directory() / "sysroot" }}" cargo b {{ cargo_flags }} --package {{ prog }}
|
||||
riscv64-elf-strip {{ bin_path / prog }}
|
||||
cp {{ bin_path / prog }} {{ "mnt/usr/bin" / prog }}
|
||||
|
||||
build: mount_filesystem (map_dir "user" f"just release=\"{{release}}\" cargo_flags=\"{{cargo_flags}}\" build_user_prog")
|
||||
cargo b {{ cargo_flags }}
|
||||
RUSTFLAGS="-Clink-arg=-Tilm.ld --sysroot {{ justfile_directory() / "sysroot" }}" cargo b {{ cargo_flags }}
|
||||
just sync_filesystem
|
||||
|
||||
run: build (runner f"{{bin_path / "kernel-rust"}}")
|
||||
@@ -34,8 +40,8 @@ qemu := f"qemu-system-riscv64 \
|
||||
-device bochs-display \
|
||||
-device virtio-keyboard-pci \
|
||||
-device virtio-mouse-pci \
|
||||
-device loader,file=disk.img,addr=0x90000000 \
|
||||
-bios none -m 512M {{qemu_flags}}"
|
||||
-device loader,file=disk.img,addr=0xA0000000 \
|
||||
-bios none -m 1024M {{qemu_flags}}"
|
||||
|
||||
# -trace \"virtio*\"
|
||||
# -d guest_errors,unimp,int"
|
||||
@@ -53,4 +59,5 @@ runner args:
|
||||
{{ qemu }} -kernel {{ args }}
|
||||
|
||||
clean:
|
||||
cd library && just clean
|
||||
cargo clean
|
||||
|
||||
17
library/.gitignore
vendored
Normal file
17
library/.gitignore
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
portable-simd
|
||||
core_arch
|
||||
core
|
||||
compiler-builtins
|
||||
alloc
|
||||
stdarch
|
||||
unwind
|
||||
std_detect
|
||||
panic_abort
|
||||
panic_unwind
|
||||
rustc-std-workspace-alloc
|
||||
rustc-std-workspace-core
|
||||
rustc-std-workspace-std
|
||||
windows_link
|
||||
profiler_builtins
|
||||
test
|
||||
proc_macro
|
||||
88
library/Cargo.toml
Normal file
88
library/Cargo.toml
Normal file
@@ -0,0 +1,88 @@
|
||||
|
||||
cargo-features = ["profile-rustflags"]
|
||||
|
||||
[workspace]
|
||||
resolver = "1"
|
||||
members = [
|
||||
"std",
|
||||
# "sysroot",
|
||||
# "coretests",
|
||||
# "alloctests",
|
||||
]
|
||||
|
||||
exclude = [
|
||||
# stdarch has its own Cargo workspace
|
||||
"stdarch",
|
||||
"windows_link"
|
||||
]
|
||||
|
||||
[profile.release.package.compiler_builtins]
|
||||
# For compiler-builtins we always use a high number of codegen units.
|
||||
# The goal here is to place every single intrinsic into its own object
|
||||
# file to avoid symbol clashes with the system libgcc if possible. Note
|
||||
# that this number doesn't actually produce this many object files, we
|
||||
# just don't create more than this number of object files.
|
||||
#
|
||||
# It's a bit of a bummer that we have to pass this here, unfortunately.
|
||||
# Ideally this would be specified through an env var to Cargo so Cargo
|
||||
# knows how many CGUs are for this specific crate, but for now
|
||||
# per-crate configuration isn't specifiable in the environment.
|
||||
codegen-units = 10000
|
||||
|
||||
# These dependencies of the standard library implement symbolication for
|
||||
# backtraces on most platforms. Their debuginfo causes both linking to be slower
|
||||
# (more data to chew through) and binaries to be larger without really all that
|
||||
# much benefit. This section turns them all to down to have no debuginfo which
|
||||
# helps to improve link times a little bit.
|
||||
[profile.release.package]
|
||||
addr2line.debug = 0
|
||||
addr2line.opt-level = "s"
|
||||
adler2.debug = 0
|
||||
gimli.debug = 0
|
||||
gimli.opt-level = "s"
|
||||
miniz_oxide.debug = 0
|
||||
miniz_oxide.opt-level = "s"
|
||||
# `opt-level = "s"` for `object` led to a size regression when tried previously
|
||||
object.debug = 0
|
||||
rustc-demangle.debug = 0
|
||||
rustc-demangle.opt-level = "s"
|
||||
|
||||
# panic_abort must always be compiled with panic=abort, even when the rest of the
|
||||
# sysroot is panic=unwind.
|
||||
[profile.dev.package.panic_abort]
|
||||
rustflags = ["-Cpanic=abort"]
|
||||
|
||||
[profile.release.package.panic_abort]
|
||||
rustflags = ["-Cpanic=abort"]
|
||||
|
||||
# The "dist" profile is used by bootstrap for prebuilt libstd artifacts
|
||||
# These settings ensure that the prebuilt artifacts support a variety of features
|
||||
# in the user's profile.
|
||||
[profile.dist]
|
||||
inherits = "release"
|
||||
codegen-units = 1
|
||||
debug = 1 # "limited"
|
||||
rustflags = [
|
||||
# `profile.lto=off` implies `-Cembed-bitcode=no`, but unconditionally embedding
|
||||
# bitcode is necessary for when users enable LTO.
|
||||
# Required until Cargo can re-build the standard library based on the value
|
||||
# of `profile.lto` in the user's profile.
|
||||
"-Cembed-bitcode=yes",
|
||||
# Enable frame pointers
|
||||
"-Zunstable-options",
|
||||
"-Cforce-frame-pointers=non-leaf",
|
||||
]
|
||||
|
||||
[profile.dist.package.panic_abort]
|
||||
rustflags = [
|
||||
"-Cpanic=abort",
|
||||
"-Cembed-bitcode=yes",
|
||||
"-Zunstable-options",
|
||||
"-Cforce-frame-pointers=non-leaf",
|
||||
]
|
||||
|
||||
[patch.crates-io]
|
||||
# See comments in `library/rustc-std-workspace-core/README.md` for what's going on here
|
||||
rustc-std-workspace-core = { path = 'rustc-std-workspace-core' }
|
||||
rustc-std-workspace-alloc = { path = 'rustc-std-workspace-alloc' }
|
||||
# rustc-std-workspace-std = { path = 'rustc-std-workspace-std' }
|
||||
1
library/backtrace
Submodule
1
library/backtrace
Submodule
Submodule library/backtrace added at 28ec93b503
319
library/justfile
Normal file
319
library/justfile
Normal file
@@ -0,0 +1,319 @@
|
||||
SRC_DIR := "std/src"
|
||||
PATCH_DIR := "std/patches"
|
||||
RUST_SRC := `rustc --print sysroot` / "lib/rustlib/src/rust/library"
|
||||
|
||||
patch-std:
|
||||
@echo "Start patching the std..."
|
||||
@find {{ PATCH_DIR }} -type f | while read -r patch_file; do \
|
||||
relative_path="${patch_file#{{ PATCH_DIR }}/}"; \
|
||||
target_file="${relative_path%.sed}.rs"; \
|
||||
if [ -f "{{ SRC_DIR }}/$target_file" ]; then \
|
||||
echo " [SED] $target_file"; \
|
||||
sed -i -f "$patch_file" "{{ SRC_DIR }}/$target_file"; \
|
||||
else \
|
||||
echo "⚠ [WARN] target doesn't exist: $target_file"; \
|
||||
fi; \
|
||||
done
|
||||
@echo "✅ Patching done."
|
||||
|
||||
update-std:
|
||||
@just setup-std
|
||||
@just patch-std
|
||||
|
||||
cp_std path:
|
||||
@echo "Linking {{ path }}"
|
||||
@mkdir {{ "std/src" / parent_directory(path) }} -p
|
||||
@ln -fs {{ RUST_SRC / "std/src" / path }} {{ "std/src" / parent_directory(path) }}
|
||||
|
||||
real_cp_std path:
|
||||
@echo "Copying {{ path }}"
|
||||
@mkdir {{ "std/src" / parent_directory(path) }} -p
|
||||
@cp {{ RUST_SRC / "std/src" / path }} {{ "std/src" / path }}
|
||||
|
||||
setup-std:
|
||||
ln -fs {{ RUST_SRC / "std_detect" }} "."
|
||||
ln -fs {{ RUST_SRC / "panic_abort" }} "."
|
||||
ln -fs {{ RUST_SRC / "panic_unwind" }} "."
|
||||
ln -fs {{ RUST_SRC / "windows_link" }} "."
|
||||
ln -fs {{ RUST_SRC / "unwind" }} "."
|
||||
ln -fs {{ RUST_SRC / "alloc" }} "."
|
||||
ln -fs {{ RUST_SRC / "rustc-std-workspace-alloc" }} "."
|
||||
ln -fs {{ RUST_SRC / "rustc-std-workspace-core" }} "."
|
||||
ln -fs {{ RUST_SRC / "rustc-std-workspace-std" }} "."
|
||||
ln -fs {{ RUST_SRC / "compiler-builtins" }} "."
|
||||
ln -fs {{ RUST_SRC / "core" }} "."
|
||||
ln -fs {{ RUST_SRC / "stdarch" }} "."
|
||||
ln -fs {{ RUST_SRC / "portable-simd" }} "."
|
||||
ln -fs {{ RUST_SRC / "proc_macro" }} "."
|
||||
ln -fs {{ RUST_SRC / "profiler_builtins" }} "."
|
||||
ln -fs {{ RUST_SRC / "test" }} "."
|
||||
|
||||
@just cp_std "../build.rs"
|
||||
@sed -i "59a\ || target_os == \"survos\"" std/build.rs
|
||||
|
||||
@just cp_std "alloc.rs"
|
||||
@just cp_std "ascii.rs"
|
||||
@just cp_std "backtrace.rs"
|
||||
@just cp_std "bstr.rs"
|
||||
@just cp_std "env.rs"
|
||||
@just cp_std "error.rs"
|
||||
@just cp_std "fs.rs"
|
||||
@just cp_std "keyword_docs.rs"
|
||||
@just cp_std "lib.rs"
|
||||
@just cp_std "macros.rs"
|
||||
@just cp_std "panic.rs"
|
||||
@just cp_std "panicking.rs"
|
||||
@just cp_std "pat.rs"
|
||||
@just cp_std "path.rs"
|
||||
@just cp_std "process.rs"
|
||||
@just cp_std "random.rs"
|
||||
@just cp_std "rt.rs"
|
||||
@just cp_std "tests_helpers.rs"
|
||||
@just cp_std "time.rs"
|
||||
|
||||
@just cp_std "backtrace"
|
||||
|
||||
@just cp_std "collections"
|
||||
|
||||
@just cp_std "ffi"
|
||||
|
||||
@just cp_std "fs"
|
||||
|
||||
@just cp_std "hash"
|
||||
|
||||
@just cp_std "io"
|
||||
|
||||
@just cp_std "net"
|
||||
|
||||
@just cp_std "num"
|
||||
|
||||
@just cp_std "os/raw/mod.rs"
|
||||
@just cp_std "os/raw/tests.rs"
|
||||
@just cp_std "os/mod.rs"
|
||||
|
||||
@just cp_std "prelude"
|
||||
|
||||
@just cp_std "process"
|
||||
|
||||
@just cp_std "sync"
|
||||
|
||||
@just cp_std "sys/alloc/mod.rs"
|
||||
|
||||
@just real_cp_std "sys/args/mod.rs"
|
||||
@just cp_std "sys/args/unsupported.rs"
|
||||
|
||||
@just cp_std "sys/env/mod.rs"
|
||||
@just cp_std "sys/env/common.rs"
|
||||
@just cp_std "sys/env/unsupported.rs"
|
||||
|
||||
@just cp_std "sys/fd/mod.rs"
|
||||
|
||||
@just cp_std "sys/fs/mod.rs"
|
||||
@just cp_std "sys/fs/common.rs"
|
||||
@just cp_std "sys/fs/unsupported.rs"
|
||||
|
||||
@just cp_std "sys/helpers/mod.rs"
|
||||
@just cp_std "sys/helpers/small_c_string.rs"
|
||||
@just cp_std "sys/helpers/tests.rs"
|
||||
@just cp_std "sys/helpers/wstr.rs"
|
||||
|
||||
@just cp_std "sys/io/error/generic.rs"
|
||||
@just real_cp_std "sys/io/error/mod.rs"
|
||||
@just cp_std "sys/io/io_slice/unsupported.rs"
|
||||
@just cp_std "sys/io/is_terminal/unsupported.rs"
|
||||
@just cp_std "sys/io/kernel_copy/mod.rs"
|
||||
@just cp_std "sys/io/mod.rs"
|
||||
|
||||
@just cp_std "sys/net/connection/mod.rs"
|
||||
@just cp_std "sys/net/connection/unsupported.rs"
|
||||
@just cp_std "sys/net/hostname/mod.rs"
|
||||
@just cp_std "sys/net/hostname/unsupported.rs"
|
||||
@just cp_std "sys/net/mod.rs"
|
||||
|
||||
@just cp_std "sys/os_str/bytes/tests.rs"
|
||||
@just cp_std "sys/os_str/bytes.rs"
|
||||
@just cp_std "sys/os_str/mod.rs"
|
||||
|
||||
@just real_cp_std "sys/pal/mod.rs"
|
||||
@just cp_std "sys/pal/unsupported/mod.rs"
|
||||
@just cp_std "sys/pal/unsupported/common.rs"
|
||||
@just cp_std "sys/pal/unsupported/os.rs"
|
||||
|
||||
@just cp_std "sys/path/mod.rs"
|
||||
@just cp_std "sys/path/unix.rs"
|
||||
|
||||
@just cp_std "sys/personality/dwarf/eh.rs"
|
||||
@just cp_std "sys/personality/dwarf/mod.rs"
|
||||
@just cp_std "sys/personality/dwarf/tests.rs"
|
||||
@just cp_std "sys/personality/mod.rs"
|
||||
|
||||
@just cp_std "sys/pipe/mod.rs"
|
||||
@just cp_std "sys/pipe/unsupported.rs"
|
||||
|
||||
@just cp_std "sys/platform_version/mod.rs"
|
||||
|
||||
@just cp_std "sys/process/mod.rs"
|
||||
@just cp_std "sys/process/env.rs"
|
||||
@just cp_std "sys/process/unsupported.rs"
|
||||
|
||||
@just real_cp_std "sys/random/mod.rs"
|
||||
@just cp_std "sys/random/unsupported.rs"
|
||||
|
||||
@just cp_std "sys/stdio/mod.rs"
|
||||
@just cp_std "sys/stdio/unsupported.rs"
|
||||
|
||||
@just cp_std "sys/sync/condvar/mod.rs"
|
||||
@just cp_std "sys/sync/condvar/no_threads.rs"
|
||||
@just cp_std "sys/sync/mutex/mod.rs"
|
||||
@just cp_std "sys/sync/mutex/no_threads.rs"
|
||||
@just cp_std "sys/sync/once/mod.rs"
|
||||
@just cp_std "sys/sync/once/no_threads.rs"
|
||||
@just cp_std "sys/sync/rwlock/mod.rs"
|
||||
@just cp_std "sys/sync/rwlock/no_threads.rs"
|
||||
@just cp_std "sys/sync/thread_parking/mod.rs"
|
||||
@just cp_std "sys/sync/thread_parking/unsupported.rs"
|
||||
@just cp_std "sys/sync/mod.rs"
|
||||
@just cp_std "sys/sync/once_box.rs"
|
||||
|
||||
@just cp_std "sys/thread/mod.rs"
|
||||
@just cp_std "sys/thread/unsupported.rs"
|
||||
|
||||
@just real_cp_std "sys/thread_local/mod.rs"
|
||||
@just cp_std "sys/thread_local/no_threads.rs"
|
||||
@just cp_std "sys/thread_local/os.rs"
|
||||
|
||||
@just cp_std "sys/time/mod.rs"
|
||||
@just cp_std "sys/time/unsupported.rs"
|
||||
|
||||
@just cp_std "sys/backtrace.rs"
|
||||
@just cp_std "sys/cmath.rs"
|
||||
@just cp_std "sys/configure_builtins.rs"
|
||||
@just cp_std "sys/env_consts.rs"
|
||||
@just cp_std "sys/exit.rs"
|
||||
@just cp_std "sys/mod.rs"
|
||||
|
||||
@just cp_std "thread"
|
||||
|
||||
STD_FILES := "alloc.rs \
|
||||
ascii.rs \
|
||||
backtrace.rs \
|
||||
bstr.rs \
|
||||
env.rs \
|
||||
error.rs \
|
||||
fs.rs \
|
||||
keyword_docs.rs \
|
||||
lib.rs \
|
||||
macros.rs \
|
||||
panic.rs \
|
||||
panicking.rs \
|
||||
pat.rs \
|
||||
path.rs \
|
||||
process.rs \
|
||||
random.rs \
|
||||
rt.rs \
|
||||
tests_helpers.rs \
|
||||
time.rs \
|
||||
backtrace \
|
||||
collections \
|
||||
ffi \
|
||||
fs \
|
||||
hash \
|
||||
io \
|
||||
net \
|
||||
num \
|
||||
os/raw/mod.rs \
|
||||
os/raw/tests.rs \
|
||||
os/mod.rs \
|
||||
prelude \
|
||||
process \
|
||||
sync \
|
||||
sys/alloc/mod.rs \
|
||||
sys/args/mod.rs \
|
||||
sys/args/unsupported.rs \
|
||||
sys/env/mod.rs \
|
||||
sys/env/common.rs \
|
||||
sys/env/unsupported.rs \
|
||||
sys/fd/mod.rs \
|
||||
sys/fs/mod.rs \
|
||||
sys/fs/common.rs \
|
||||
sys/fs/unsupported.rs \
|
||||
sys/helpers/mod.rs \
|
||||
sys/helpers/small_c_string.rs \
|
||||
sys/helpers/tests.rs \
|
||||
sys/helpers/wstr.rs \
|
||||
sys/io/error/generic.rs \
|
||||
sys/io/error/mod.rs \
|
||||
sys/io/io_slice/unsupported.rs \
|
||||
sys/io/is_terminal/unsupported.rs \
|
||||
sys/io/kernel_copy/mod.rs \
|
||||
sys/io/mod.rs \
|
||||
sys/net/connection/mod.rs \
|
||||
sys/net/connection/unsupported.rs \
|
||||
sys/net/hostname/mod.rs \
|
||||
sys/net/hostname/unsupported.rs \
|
||||
sys/net/mod.rs \
|
||||
sys/os_str/bytes/tests.rs \
|
||||
sys/os_str/bytes.rs \
|
||||
sys/os_str/mod.rs \
|
||||
sys/pal/mod.rs \
|
||||
sys/pal/unsupported/mod.rs \
|
||||
sys/pal/unsupported/common.rs \
|
||||
sys/pal/unsupported/os.rs \
|
||||
sys/path/mod.rs \
|
||||
sys/path/unix.rs \
|
||||
sys/personality/dwarf/eh.rs \
|
||||
sys/personality/dwarf/mod.rs \
|
||||
sys/personality/dwarf/tests.rs \
|
||||
sys/personality/mod.rs \
|
||||
sys/pipe/mod.rs \
|
||||
sys/pipe/unsupported.rs \
|
||||
sys/platform_version/mod.rs \
|
||||
sys/process/mod.rs \
|
||||
sys/process/env.rs \
|
||||
sys/process/unsupported.rs \
|
||||
sys/random/mod.rs \
|
||||
sys/random/unsupported.rs \
|
||||
sys/stdio/mod.rs \
|
||||
sys/stdio/unsupported.rs \
|
||||
sys/sync/condvar/mod.rs \
|
||||
sys/sync/condvar/no_threads.rs \
|
||||
sys/sync/mutex/mod.rs \
|
||||
sys/sync/mutex/no_threads.rs \
|
||||
sys/sync/once/mod.rs \
|
||||
sys/sync/once/no_threads.rs \
|
||||
sys/sync/rwlock/mod.rs \
|
||||
sys/sync/rwlock/no_threads.rs \
|
||||
sys/sync/thread_parking/mod.rs \
|
||||
sys/sync/thread_parking/unsupported.rs \
|
||||
sys/sync/mod.rs \
|
||||
sys/sync/once_box.rs \
|
||||
sys/thread/mod.rs \
|
||||
sys/thread/unsupported.rs \
|
||||
sys/thread_local/mod.rs \
|
||||
sys/thread_local/no_threads.rs \
|
||||
sys/thread_local/os.rs \
|
||||
sys/time/mod.rs \
|
||||
sys/time/unsupported.rs \
|
||||
sys/backtrace.rs \
|
||||
sys/cmath.rs \
|
||||
sys/configure_builtins.rs \
|
||||
sys/env_consts.rs \
|
||||
sys/exit.rs \
|
||||
sys/mod.rs \
|
||||
thread"
|
||||
|
||||
build-sysroot: update-std
|
||||
RUSTFLAGS="-Zforce-unstable-if-unmarked -C relocation-model=pic -C link-arg=-pie" cargo build --target ../riscv64.json
|
||||
mkdir ../sysroot/lib/rustlib/riscv64/lib -p
|
||||
rm ../sysroot/lib/rustlib/riscv64/lib/* -rf
|
||||
cp target/riscv64/debug/deps/*.rlib ../sysroot/lib/rustlib/riscv64/lib
|
||||
|
||||
clean:
|
||||
# cargo clean
|
||||
rm ../sysroot/lib/rustlib/riscv64/lib/* -rf
|
||||
|
||||
for file in {{ STD_FILES }}; do \
|
||||
rm -rf std/src/$file; \
|
||||
done
|
||||
|
||||
rm -rf std/build.rs
|
||||
109
library/std/.gitignore
vendored
Normal file
109
library/std/.gitignore
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
build.rs
|
||||
|
||||
src/alloc.rs
|
||||
src/ascii.rs
|
||||
src/backtrace.rs
|
||||
src/bstr.rs
|
||||
src/env.rs
|
||||
src/error.rs
|
||||
src/fs.rs
|
||||
src/keyword_docs.rs
|
||||
src/lib.rs
|
||||
src/macros.rs
|
||||
src/panic.rs
|
||||
src/panicking.rs
|
||||
src/pat.rs
|
||||
src/path.rs
|
||||
src/process.rs
|
||||
src/random.rs
|
||||
src/rt.rs
|
||||
src/tests_helpers.rs
|
||||
src/time.rs
|
||||
src/backtrace
|
||||
src/collections
|
||||
src/ffi
|
||||
src/fs
|
||||
src/hash
|
||||
src/io
|
||||
src/net
|
||||
src/num
|
||||
src/os/raw/mod.rs
|
||||
src/os/raw/tests.rs
|
||||
src/os/mod.rs
|
||||
src/prelude
|
||||
src/process
|
||||
src/sync
|
||||
src/sys/alloc/mod.rs
|
||||
src/sys/args/mod.rs
|
||||
src/sys/args/unsupported.rs
|
||||
src/sys/env/mod.rs
|
||||
src/sys/env/common.rs
|
||||
src/sys/env/unsupported.rs
|
||||
src/sys/fd/mod.rs
|
||||
src/sys/fs/mod.rs
|
||||
src/sys/fs/common.rs
|
||||
src/sys/fs/unsupported.rs
|
||||
src/sys/helpers/mod.rs
|
||||
src/sys/helpers/small_c_string.rs
|
||||
src/sys/helpers/tests.rs
|
||||
src/sys/helpers/wstr.rs
|
||||
src/sys/io/error/generic.rs
|
||||
src/sys/io/error/mod.rs
|
||||
src/sys/io/io_slice/unsupported.rs
|
||||
src/sys/io/is_terminal/unsupported.rs
|
||||
src/sys/io/kernel_copy/mod.rs
|
||||
src/sys/io/mod.rs
|
||||
src/sys/net/connection/mod.rs
|
||||
src/sys/net/connection/unsupported.rs
|
||||
src/sys/net/hostname/mod.rs
|
||||
src/sys/net/hostname/unsupported.rs
|
||||
src/sys/net/mod.rs
|
||||
src/sys/os_str/bytes/tests.rs
|
||||
src/sys/os_str/bytes.rs
|
||||
src/sys/os_str/mod.rs
|
||||
src/sys/pal/mod.rs
|
||||
src/sys/pal/unsupported/mod.rs
|
||||
src/sys/pal/unsupported/common.rs
|
||||
src/sys/pal/unsupported/os.rs
|
||||
src/sys/path/mod.rs
|
||||
src/sys/path/unix.rs
|
||||
src/sys/personality/dwarf/eh.rs
|
||||
src/sys/personality/dwarf/mod.rs
|
||||
src/sys/personality/dwarf/tests.rs
|
||||
src/sys/personality/mod.rs
|
||||
src/sys/pipe/mod.rs
|
||||
src/sys/pipe/unsupported.rs
|
||||
src/sys/platform_version/mod.rs
|
||||
src/sys/process/mod.rs
|
||||
src/sys/process/env.rs
|
||||
src/sys/process/unsupported.rs
|
||||
src/sys/random/mod.rs
|
||||
src/sys/random/unsupported.rs
|
||||
src/sys/stdio/mod.rs
|
||||
src/sys/stdio/unsupported.rs
|
||||
src/sys/sync/condvar/mod.rs
|
||||
src/sys/sync/condvar/no_threads.rs
|
||||
src/sys/sync/mutex/mod.rs
|
||||
src/sys/sync/mutex/no_threads.rs
|
||||
src/sys/sync/once/mod.rs
|
||||
src/sys/sync/once/no_threads.rs
|
||||
src/sys/sync/rwlock/mod.rs
|
||||
src/sys/sync/rwlock/no_threads.rs
|
||||
src/sys/sync/thread_parking/mod.rs
|
||||
src/sys/sync/thread_parking/unsupported.rs
|
||||
src/sys/sync/mod.rs
|
||||
src/sys/sync/once_box.rs
|
||||
src/sys/thread/mod.rs
|
||||
src/sys/thread/unsupported.rs
|
||||
src/sys/thread_local/mod.rs
|
||||
src/sys/thread_local/no_threads.rs
|
||||
src/sys/thread_local/os.rs
|
||||
src/sys/time/mod.rs
|
||||
src/sys/time/unsupported.rs
|
||||
src/sys/backtrace.rs
|
||||
src/sys/cmath.rs
|
||||
src/sys/configure_builtins.rs
|
||||
src/sys/env_consts.rs
|
||||
src/sys/exit.rs
|
||||
src/sys/mod.rs
|
||||
src/thread
|
||||
177
library/std/Cargo.toml
Normal file
177
library/std/Cargo.toml
Normal file
@@ -0,0 +1,177 @@
|
||||
cargo-features = ["public-dependency"]
|
||||
|
||||
[package]
|
||||
name = "std"
|
||||
version = "0.0.0"
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/rust-lang/rust.git"
|
||||
description = "The Rust Standard Library"
|
||||
edition = "2024"
|
||||
autobenches = false
|
||||
|
||||
[lib]
|
||||
crate-type = ["dylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
alloc = { path = "../alloc", public = true }
|
||||
# std no longer uses cfg-if directly, but the included copy of backtrace does.
|
||||
cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
|
||||
panic_unwind = { path = "../panic_unwind", optional = true }
|
||||
panic_abort = { path = "../panic_abort" }
|
||||
core = { path = "../core", public = true }
|
||||
unwind = { path = "../unwind" }
|
||||
hashbrown = { version = "0.16.1", default-features = false, features = [
|
||||
'rustc-dep-of-std',
|
||||
] }
|
||||
std_detect = { path = "../std_detect", public = true }
|
||||
|
||||
# Dependencies of the `backtrace` crate
|
||||
rustc-demangle = { version = "0.1.27", features = ['rustc-dep-of-std'] }
|
||||
|
||||
[target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies]
|
||||
miniz_oxide = { version = "0.8.0", optional = true, default-features = false }
|
||||
addr2line = { version = "0.25.0", optional = true, default-features = false }
|
||||
|
||||
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
|
||||
libc = { version = "0.2.178", default-features = false, features = [
|
||||
'rustc-dep-of-std',
|
||||
], public = true }
|
||||
|
||||
[target.'cfg(all(not(target_os = "aix"), not(all(windows, target_env = "msvc", not(target_vendor = "uwp")))))'.dependencies]
|
||||
object = { version = "0.37.1", default-features = false, optional = true, features = [
|
||||
'read_core',
|
||||
'elf',
|
||||
'macho',
|
||||
'pe',
|
||||
'unaligned',
|
||||
'archive',
|
||||
] }
|
||||
|
||||
[target.'cfg(target_os = "aix")'.dependencies]
|
||||
object = { version = "0.37.1", default-features = false, optional = true, features = [
|
||||
'read_core',
|
||||
'xcoff',
|
||||
'unaligned',
|
||||
'archive',
|
||||
] }
|
||||
|
||||
[target.'cfg(any(windows, target_os = "cygwin"))'.dependencies.windows-link]
|
||||
path = "../windows_link"
|
||||
|
||||
[dev-dependencies]
|
||||
rand = { version = "0.9.0", default-features = false, features = ["alloc"] }
|
||||
rand_xorshift = "0.4.0"
|
||||
|
||||
[target.'cfg(any(all(target_family = "wasm", target_os = "unknown"), target_os = "xous", target_os = "vexos", all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies]
|
||||
dlmalloc = { version = "0.2.10", features = ['rustc-dep-of-std'] }
|
||||
|
||||
[target.x86_64-fortanix-unknown-sgx.dependencies]
|
||||
fortanix-sgx-abi = { version = "0.6.1", features = [
|
||||
'rustc-dep-of-std',
|
||||
], public = true }
|
||||
|
||||
[target.'cfg(target_os = "motor")'.dependencies]
|
||||
moto-rt = { version = "0.16", features = ['rustc-dep-of-std'], public = true }
|
||||
|
||||
[target.'cfg(target_os = "hermit")'.dependencies]
|
||||
hermit-abi = { version = "0.5.0", features = [
|
||||
'rustc-dep-of-std',
|
||||
], public = true }
|
||||
|
||||
[target.'cfg(all(target_os = "wasi", target_env = "p1"))'.dependencies]
|
||||
wasi = { version = "0.11.0", features = [
|
||||
'rustc-dep-of-std',
|
||||
], default-features = false }
|
||||
|
||||
[target.'cfg(all(target_os = "wasi", target_env = "p2"))'.dependencies]
|
||||
wasip2 = { version = '0.14.4', features = [
|
||||
'rustc-dep-of-std',
|
||||
], default-features = false, package = 'wasi' }
|
||||
|
||||
[target.'cfg(all(target_os = "wasi", target_env = "p3"))'.dependencies]
|
||||
wasip2 = { version = '0.14.4', features = [
|
||||
'rustc-dep-of-std',
|
||||
], default-features = false, package = 'wasi' }
|
||||
|
||||
[target.'cfg(target_os = "uefi")'.dependencies]
|
||||
r-efi = { version = "5.2.0", features = ['rustc-dep-of-std'] }
|
||||
r-efi-alloc = { version = "2.0.0", features = ['rustc-dep-of-std'] }
|
||||
|
||||
[target.'cfg(target_os = "vexos")'.dependencies]
|
||||
vex-sdk = { version = "0.27.0", features = [
|
||||
'rustc-dep-of-std',
|
||||
], default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["compiler-builtins-mem"]
|
||||
backtrace = [
|
||||
'addr2line/rustc-dep-of-std',
|
||||
'object/rustc-dep-of-std',
|
||||
'miniz_oxide/rustc-dep-of-std',
|
||||
]
|
||||
# Disable symbolization in backtraces. For use with -Zbuild-std.
|
||||
# FIXME: Ideally this should be an additive backtrace-symbolization feature
|
||||
backtrace-trace-only = []
|
||||
|
||||
panic-unwind = ["dep:panic_unwind"]
|
||||
compiler-builtins-c = ["alloc/compiler-builtins-c"]
|
||||
compiler-builtins-mem = ["alloc/compiler-builtins-mem"]
|
||||
llvm-libunwind = ["unwind/llvm-libunwind"]
|
||||
system-llvm-libunwind = ["unwind/system-llvm-libunwind"]
|
||||
|
||||
# Choose algorithms that are optimized for binary size instead of runtime performance
|
||||
optimize_for_size = ["core/optimize_for_size", "alloc/optimize_for_size"]
|
||||
|
||||
# Make `RefCell` store additional debugging information, which is printed out when
|
||||
# a borrow error occurs
|
||||
debug_refcell = ["core/debug_refcell"]
|
||||
|
||||
llvm_enzyme = ["core/llvm_enzyme"]
|
||||
|
||||
# Enable using raw-dylib for Windows imports.
|
||||
# This will eventually be the default.
|
||||
windows_raw_dylib = ["windows-link/windows_raw_dylib"]
|
||||
|
||||
[package.metadata.fortanix-sgx]
|
||||
# Maximum possible number of threads when testing
|
||||
threads = 125
|
||||
# Maximum heap size
|
||||
heap_size = 0x8000000
|
||||
|
||||
[[test]]
|
||||
name = "pipe-subprocess"
|
||||
path = "tests/pipe_subprocess.rs"
|
||||
harness = false
|
||||
|
||||
[[test]]
|
||||
name = "sync"
|
||||
path = "tests/sync/lib.rs"
|
||||
|
||||
[[test]]
|
||||
name = "thread_local"
|
||||
path = "tests/thread_local/lib.rs"
|
||||
|
||||
[[bench]]
|
||||
name = "stdbenches"
|
||||
path = "benches/lib.rs"
|
||||
test = true
|
||||
|
||||
[lints.rust.unexpected_cfgs]
|
||||
level = "warn"
|
||||
check-cfg = [
|
||||
# std use #[path] imports to portable-simd `std_float` crate
|
||||
# and to the `backtrace` crate which messes-up with Cargo list
|
||||
# of declared features, we therefor expect any feature cfg
|
||||
'cfg(feature, values(any()))',
|
||||
# Internal features aren't marked known config by default, we use these to
|
||||
# gate tests.
|
||||
'cfg(target_has_reliable_f16)',
|
||||
'cfg(target_has_reliable_f16_math)',
|
||||
'cfg(target_has_reliable_f128)',
|
||||
'cfg(target_has_reliable_f128_math)',
|
||||
]
|
||||
|
||||
|
||||
|
||||
# shared = { path = "../shared", features = ["user"] }
|
||||
# io_crate = { package = "io", path = "../io", features = ["alloc_crate"] }
|
||||
4
library/std/patches/sys/args/mod.sed
Normal file
4
library/std/patches/sys/args/mod.sed
Normal file
@@ -0,0 +1,4 @@
|
||||
# 55a \ target_os = "survos" => { \
|
||||
# mod survos; \
|
||||
# pub use survos::*; \
|
||||
# }
|
||||
1
library/std/patches/sys/io/error/mod.sed
Normal file
1
library/std/patches/sys/io/error/mod.sed
Normal file
@@ -0,0 +1 @@
|
||||
45a \ target_os = "survos",
|
||||
6
library/std/patches/sys/pal/mod.sed
Normal file
6
library/std/patches/sys/pal/mod.sed
Normal file
@@ -0,0 +1,6 @@
|
||||
62a \ target_os = "survos" => { \
|
||||
mod unsupported; \
|
||||
pub use self::unsupported::*; \
|
||||
mod survos; \
|
||||
pub use self::survos::*; \
|
||||
}
|
||||
2
library/std/patches/sys/random/mod.sed
Normal file
2
library/std/patches/sys/random/mod.sed
Normal file
@@ -0,0 +1,2 @@
|
||||
108a \target_os = "survos",
|
||||
124a \target_os = "survos",
|
||||
6
library/std/patches/sys/thread_local/mod.sed
Normal file
6
library/std/patches/sys/thread_local/mod.sed
Normal file
@@ -0,0 +1,6 @@
|
||||
32a \ target_os = "survos",
|
||||
|
||||
129a \ target_os = "survos" => { \
|
||||
// todo \
|
||||
pub(crate) fn enable() {} \
|
||||
}
|
||||
22
library/std/riscv64.json
Normal file
22
library/std/riscv64.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"llvm-target": "riscv64",
|
||||
"llvm-abiname": "lp64",
|
||||
"abi": "lp64",
|
||||
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": 64,
|
||||
"arch": "riscv64",
|
||||
"os": "survos",
|
||||
"vendor": "unknown",
|
||||
"env": "",
|
||||
"features": "+i,+m,+a,+zicsr",
|
||||
"linker": "ld.lld",
|
||||
"linker-flavor": "ld",
|
||||
"executables": true,
|
||||
"panic-strategy": "abort",
|
||||
"relocation-model": "static",
|
||||
"disable-redzone": true,
|
||||
"emit-debug-gdb-scripts": false,
|
||||
"eh-frame-header": false,
|
||||
"code-model": "medium"
|
||||
}
|
||||
11
library/std/src/sys/pal/survos.rs
Normal file
11
library/std/src/sys/pal/survos.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
/// # Safety
|
||||
/// `argc` and `argv` are passed by the kernel
|
||||
#[unsafe(no_mangle)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe extern "C" fn _start(argc: isize, argv: *const *const u8) -> isize {
|
||||
unsafe extern "C" {
|
||||
fn main(argc: isize, argv: *const *const u8) -> isize;
|
||||
}
|
||||
|
||||
unsafe { main(argc, argv) }
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": 64,
|
||||
"arch": "riscv64",
|
||||
"os": "none",
|
||||
"os": "survos",
|
||||
"vendor": "unknown",
|
||||
"env": "",
|
||||
"features": "+i,+m,+a,+zicsr",
|
||||
|
||||
2
src/drivers.rs
Normal file
2
src/drivers.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod keyboard;
|
||||
pub mod mouse;
|
||||
67
src/drivers/keyboard.rs
Normal file
67
src/drivers/keyboard.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
use crate::{
|
||||
keymap::{KeyType, ModifierType, map_keycode},
|
||||
tty::TTY0,
|
||||
virtio::{
|
||||
Virtqueue,
|
||||
input::{EventCodeValue, VirtioInputEvent, VirtioPciDriver},
|
||||
},
|
||||
virtual_fs::{FILE_SYSTEM, VirtualFileSystem},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct KeyboardState {
|
||||
// ctrl_modifier: bool,
|
||||
pub shift_modifier: bool,
|
||||
pub alt_gr_modifier: bool,
|
||||
}
|
||||
|
||||
impl KeyboardState {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
// ctrl_modifier: false,
|
||||
shift_modifier: false,
|
||||
alt_gr_modifier: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mut KBD_QUEUE: Virtqueue = unsafe { core::mem::zeroed() };
|
||||
pub static mut KBD_DRIVER: VirtioPciDriver<KeyboardState> = unsafe {
|
||||
VirtioPciDriver::new(
|
||||
|state, event| {
|
||||
let mut kbd_buffer = FILE_SYSTEM.open("/dev/input/keyboard".as_ref()).unwrap();
|
||||
kbd_buffer
|
||||
.write(core::mem::transmute::<
|
||||
&VirtioInputEvent,
|
||||
&[u8; size_of::<VirtioInputEvent>()],
|
||||
>(event))
|
||||
.unwrap();
|
||||
|
||||
if event.is_key() {
|
||||
let event = event.as_key_event();
|
||||
#[allow(clippy::single_match)]
|
||||
match map_keycode(event.code, state) {
|
||||
KeyType::Ascii(c) if event.value == EventCodeValue::Pressed => {
|
||||
let mut buf = [0; 4];
|
||||
let to_send = c.encode_utf8(&mut buf);
|
||||
for c in to_send.as_bytes() {
|
||||
TTY0.buffer.borrow_mut().push(*c);
|
||||
}
|
||||
}
|
||||
KeyType::Modifier(ModifierType::Shift) => {
|
||||
state.shift_modifier = !state.shift_modifier;
|
||||
}
|
||||
KeyType::Modifier(ModifierType::AltGr) => {
|
||||
state.alt_gr_modifier = !state.alt_gr_modifier;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
// println!("event: {:#?}", event);
|
||||
} else {
|
||||
// println!("key pressed, {:#?}", event);
|
||||
}
|
||||
},
|
||||
KeyboardState::new(),
|
||||
&mut KBD_QUEUE,
|
||||
)
|
||||
};
|
||||
38
src/drivers/mouse.rs
Normal file
38
src/drivers/mouse.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use crate::{
|
||||
cursor::{clear_cursor, draw_cursor},
|
||||
vga::Vga,
|
||||
virtio::{self, Virtqueue, input::VirtioPciDriver},
|
||||
};
|
||||
|
||||
pub static mut MOUSE_POSITION: (u16, u16) = (0, 0);
|
||||
|
||||
static mut MOUSE_QUEUE: Virtqueue = unsafe { core::mem::zeroed() };
|
||||
pub static mut MOUSE_DRIVER: VirtioPciDriver<()> = unsafe {
|
||||
VirtioPciDriver::new(
|
||||
|_, event| {
|
||||
if event.is_relative() {
|
||||
let event = event.as_relative_event();
|
||||
|
||||
clear_cursor(&mut Vga, MOUSE_POSITION.0, MOUSE_POSITION.1);
|
||||
|
||||
match event.code {
|
||||
virtio::input::EventCodeRelative::X => {
|
||||
MOUSE_POSITION.0 = (MOUSE_POSITION.0 as i32 + event.value) as u16
|
||||
}
|
||||
virtio::input::EventCodeRelative::Y => {
|
||||
MOUSE_POSITION.1 = (MOUSE_POSITION.1 as i32 + event.value) as u16
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
draw_cursor(&mut Vga, MOUSE_POSITION.0, MOUSE_POSITION.1);
|
||||
|
||||
// println!("mouse moved relatively, {:#?}", event);
|
||||
} else {
|
||||
// println!("mouse moved, {:#?}", event);
|
||||
}
|
||||
},
|
||||
(),
|
||||
&mut MOUSE_QUEUE,
|
||||
)
|
||||
};
|
||||
@@ -12,7 +12,7 @@ use io::{IoBase, Read, Seek, Write};
|
||||
|
||||
use crate::virtual_fs::{VirtualFileSystem, VirtualNode};
|
||||
|
||||
const DISK_ADDR: *const u8 = 0x9000_0000 as *const _;
|
||||
const DISK_ADDR: *const u8 = 0xA000_0000 as *const _;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Simple disk backend that reads from a fixed memory region.
|
||||
|
||||
@@ -9,9 +9,9 @@ use log::info;
|
||||
use shared::syscall::SysCall;
|
||||
|
||||
use crate::{
|
||||
KBD_DRIVER, MOUSE_DRIVER,
|
||||
boot::sbi::{ExtensionID, TimerFunctionID},
|
||||
clear_csr,
|
||||
drivers::{keyboard::KBD_DRIVER, mouse::MOUSE_DRIVER},
|
||||
process::{ExecutionContext, exit_process, sleep},
|
||||
read_csr,
|
||||
riscv::{disable_interrupt, dump_cpu},
|
||||
@@ -160,6 +160,15 @@ unsafe extern "C" fn supervisor_trap_handler(
|
||||
|
||||
unsafe { (*interrupt_state).a[0] = fd as u64 };
|
||||
}
|
||||
SysCall::Close => {
|
||||
let fd = a1;
|
||||
|
||||
let mut scheduler = SCHEDULER.lock();
|
||||
let current_process = scheduler.get_current_process();
|
||||
let mut vnode = current_process.fd_table[fd as usize].take().unwrap();
|
||||
|
||||
vnode.close();
|
||||
}
|
||||
SysCall::Write => {
|
||||
let fd = a1;
|
||||
let buf =
|
||||
@@ -168,7 +177,8 @@ unsafe extern "C" fn supervisor_trap_handler(
|
||||
let mut scheduler = SCHEDULER.lock();
|
||||
let current_process = scheduler.get_current_process();
|
||||
let vnode = current_process.fd_table[fd as usize].as_mut().unwrap();
|
||||
vnode.write(buf).unwrap();
|
||||
let res = vnode.write(buf).unwrap();
|
||||
unsafe { (*interrupt_state).a[0] = res as u64 };
|
||||
}
|
||||
SysCall::Read => {
|
||||
let fd = a1;
|
||||
@@ -182,6 +192,8 @@ unsafe extern "C" fn supervisor_trap_handler(
|
||||
if res == 0 && !buf.is_empty() {
|
||||
loop_syscall(interrupt_state);
|
||||
scheduler.schedule(&mut interrupt_state);
|
||||
} else {
|
||||
unsafe { (*interrupt_state).a[0] = res as u64 };
|
||||
}
|
||||
}
|
||||
SysCall::Seek => {
|
||||
@@ -197,6 +209,17 @@ unsafe extern "C" fn supervisor_trap_handler(
|
||||
let vnode = current_process.fd_table[fd as usize].as_mut().unwrap();
|
||||
vnode.seek(seek).unwrap();
|
||||
}
|
||||
SysCall::Spawn => {
|
||||
let path = unsafe { str::from_raw_parts(a1 as *const u8, a2 as usize) };
|
||||
let mut scheduler = SCHEDULER.lock();
|
||||
scheduler.create_process_from_file(path, 0, core::ptr::null());
|
||||
}
|
||||
SysCall::ExecVE => {
|
||||
// let path = unsafe { str::from_raw_parts(a1 as *const u8, a2 as usize) };
|
||||
// let mut scheduler = SCHEDULER.lock();
|
||||
// scheduler.create_process_from_file(path, &[]);
|
||||
unimplemented!("ExecVE is not implemented")
|
||||
}
|
||||
SysCall::Alloc => {
|
||||
let layout = Layout::from_size_align(a1 as usize, a2 as usize).unwrap();
|
||||
// Allocate memory and put the pointer in a0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::KeyboardState;
|
||||
use crate::drivers::keyboard::KeyboardState;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive_const(PartialEq, Eq)]
|
||||
|
||||
125
src/main.rs
125
src/main.rs
@@ -12,7 +12,8 @@
|
||||
arbitrary_self_types_pointers,
|
||||
derive_const,
|
||||
const_cmp,
|
||||
const_trait_impl
|
||||
const_trait_impl,
|
||||
trait_alias
|
||||
)]
|
||||
|
||||
use core::sync::atomic::AtomicBool;
|
||||
@@ -22,20 +23,15 @@ use embedded_alloc::LlffHeap as Heap;
|
||||
use log::info;
|
||||
|
||||
use crate::{
|
||||
cursor::{clear_cursor, draw_cursor},
|
||||
drivers::{keyboard::KBD_DRIVER, mouse::MOUSE_DRIVER},
|
||||
io::init_log,
|
||||
keymap::{KeyType, ModifierType, map_keycode},
|
||||
pci::{PciDeviceIterator, scan_virtio_devices},
|
||||
pci::scan_virtio_devices,
|
||||
riscv::enable_supervisor_interrupt,
|
||||
scheduler::{SCHEDULER, idle},
|
||||
tty::TTY0,
|
||||
user::{proc2, test},
|
||||
vga::Vga,
|
||||
virtio::{
|
||||
Virtqueue,
|
||||
input::{EventCodeValue, VirtioInputEvent, VirtioPciDriver, init_plic_pci},
|
||||
},
|
||||
virtual_fs::{FILE_SYSTEM, VirtualFileSystem, init_file_system},
|
||||
virtio::input::init_plic_pci,
|
||||
virtual_fs::init_file_system,
|
||||
};
|
||||
|
||||
extern crate alloc;
|
||||
@@ -44,6 +40,7 @@ mod critical_section;
|
||||
mod cursor;
|
||||
mod data_structures;
|
||||
mod draw;
|
||||
mod drivers;
|
||||
mod fs;
|
||||
mod interrupt;
|
||||
mod io;
|
||||
@@ -75,97 +72,6 @@ const _: () = assert!(core::mem::size_of::<usize>() == core::mem::size_of::<u64>
|
||||
#[cfg(not(target_endian = "little"))]
|
||||
compile_error! {"This kernel implementation assume endianness is little-endian. Some memory access like PCI could not work in big-endian."}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct KeyboardState {
|
||||
// ctrl_modifier: bool,
|
||||
pub shift_modifier: bool,
|
||||
pub alt_gr_modifier: bool,
|
||||
}
|
||||
|
||||
impl KeyboardState {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
// ctrl_modifier: false,
|
||||
shift_modifier: false,
|
||||
alt_gr_modifier: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mut KBD_QUEUE: Virtqueue = unsafe { core::mem::zeroed() };
|
||||
pub static mut KBD_DRIVER: VirtioPciDriver<KeyboardState> = unsafe {
|
||||
VirtioPciDriver::new(
|
||||
|state, event| {
|
||||
let mut kbd_buffer = FILE_SYSTEM.open("/dev/input/keyboard".as_ref()).unwrap();
|
||||
kbd_buffer
|
||||
.write(core::mem::transmute::<
|
||||
&VirtioInputEvent,
|
||||
&[u8; size_of::<VirtioInputEvent>()],
|
||||
>(event))
|
||||
.unwrap();
|
||||
|
||||
if event.is_key() {
|
||||
let event = event.as_key_event();
|
||||
#[allow(clippy::single_match)]
|
||||
match map_keycode(event.code, state) {
|
||||
KeyType::Ascii(c) if event.value == EventCodeValue::Pressed => {
|
||||
let mut buf = [0; 4];
|
||||
let to_send = c.encode_utf8(&mut buf);
|
||||
for c in to_send.as_bytes() {
|
||||
TTY0.buffer.borrow_mut().push(*c);
|
||||
}
|
||||
}
|
||||
KeyType::Modifier(ModifierType::Shift) => {
|
||||
state.shift_modifier = !state.shift_modifier;
|
||||
}
|
||||
KeyType::Modifier(ModifierType::AltGr) => {
|
||||
state.alt_gr_modifier = !state.alt_gr_modifier;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
println!("event: {:#?}", event);
|
||||
} else {
|
||||
// println!("key pressed, {:#?}", event);
|
||||
}
|
||||
},
|
||||
KeyboardState::new(),
|
||||
&mut KBD_QUEUE,
|
||||
)
|
||||
};
|
||||
|
||||
pub static mut MOUSE_POSITION: (u16, u16) = (0, 0);
|
||||
|
||||
static mut MOUSE_QUEUE: Virtqueue = unsafe { core::mem::zeroed() };
|
||||
pub static mut MOUSE_DRIVER: VirtioPciDriver<()> = unsafe {
|
||||
VirtioPciDriver::new(
|
||||
|_, event| {
|
||||
if event.is_relative() {
|
||||
let event = event.as_relative_event();
|
||||
|
||||
clear_cursor(&mut Vga, MOUSE_POSITION.0, MOUSE_POSITION.1);
|
||||
|
||||
match event.code {
|
||||
virtio::input::EventCodeRelative::X => {
|
||||
MOUSE_POSITION.0 = (MOUSE_POSITION.0 as i32 + event.value) as u16
|
||||
}
|
||||
virtio::input::EventCodeRelative::Y => {
|
||||
MOUSE_POSITION.1 = (MOUSE_POSITION.1 as i32 + event.value) as u16
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
draw_cursor(&mut Vga, MOUSE_POSITION.0, MOUSE_POSITION.1);
|
||||
|
||||
// println!("mouse moved relatively, {:#?}", event);
|
||||
} else {
|
||||
// println!("mouse moved, {:#?}", event);
|
||||
}
|
||||
},
|
||||
(),
|
||||
&mut MOUSE_QUEUE,
|
||||
)
|
||||
};
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn supervisor_mode_entry() {
|
||||
unsafe {
|
||||
@@ -180,19 +86,20 @@ pub extern "C" fn supervisor_mode_entry() {
|
||||
info!("Hello World !");
|
||||
// unsafe { Vga.draw_string(10, 10, "Hello World !", Color::WHITE, Color::BLACK) };
|
||||
|
||||
SCHEDULER.lock().create_process(Box::new(test), "proc1");
|
||||
SCHEDULER.lock().create_process(Box::new(proc2), "proc2");
|
||||
// let binding = Box::leak(Box::new(["coucou".as_bytes()]));
|
||||
SCHEDULER
|
||||
.lock()
|
||||
.create_process(Box::new(test), "proc1", 0, core::ptr::null());
|
||||
SCHEDULER
|
||||
.lock()
|
||||
.create_process(Box::new(proc2), "proc2", 0, core::ptr::null());
|
||||
|
||||
SCHEDULER
|
||||
.lock()
|
||||
.create_process_from_file("/usr/bin/test_pic");
|
||||
.create_process_from_file("/usr/bin/test_pic", 0, core::ptr::null());
|
||||
|
||||
enable_supervisor_interrupt();
|
||||
|
||||
for pci in PciDeviceIterator::new() {
|
||||
println!("{:x?}", pci.vendor_and_device_id())
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let (pci_keyboard, pci_mouse) = scan_virtio_devices();
|
||||
let (pci_keyboard, pci_mouse) = (pci_keyboard.unwrap(), pci_mouse.unwrap());
|
||||
@@ -214,5 +121,5 @@ pub extern "C" fn supervisor_mode_entry() {
|
||||
init_plic_pci(pci_keyboard.irq);
|
||||
init_plic_pci(pci_mouse.irq);
|
||||
}
|
||||
idle();
|
||||
idle(0, core::ptr::null());
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ use crate::{
|
||||
riscv::SStatus,
|
||||
scheduler::{ACTIVE_PID, SCHEDULER, Scheduler},
|
||||
time::elapsed_time_since_startup,
|
||||
tty::TTY0,
|
||||
virtual_fs::{FILE_SYSTEM, VirtualFileSystem, VirtualNode},
|
||||
};
|
||||
|
||||
@@ -66,6 +65,9 @@ pub struct ExecutionContext {
|
||||
pub mstatus: u64,
|
||||
}
|
||||
|
||||
pub trait ProcessEntryTrait = Fn(isize, *const *const u8);
|
||||
pub type ProcessEntry = dyn ProcessEntryTrait;
|
||||
|
||||
/// Represents a process in the system.
|
||||
///
|
||||
/// Each process has its own execution context, stack,
|
||||
@@ -78,13 +80,13 @@ pub struct Process {
|
||||
/// Current state of the process.
|
||||
pub state: ProcessState,
|
||||
/// Optional entry point for the process code.
|
||||
pub entry: Option<Box<dyn Fn()>>,
|
||||
pub entry: Option<Box<ProcessEntry>>,
|
||||
/// Wake time for sleeping processes.
|
||||
pub wake_time: Duration,
|
||||
/// Saved execution context.
|
||||
pub ctx: ExecutionContext,
|
||||
/// Process stack.
|
||||
pub stack: [u64; STACK_SIZE],
|
||||
pub stack: Box<[u64; STACK_SIZE]>,
|
||||
/// File descriptor table.
|
||||
pub fd_table: Vec<Option<Box<dyn VirtualNode>>>,
|
||||
}
|
||||
@@ -109,7 +111,7 @@ impl Default for Process {
|
||||
mepc: core::ptr::null(),
|
||||
mstatus: 0,
|
||||
},
|
||||
stack: [0; _],
|
||||
stack: unsafe { Box::new_zeroed().assume_init() },
|
||||
entry: None,
|
||||
fd_table: Vec::new(),
|
||||
}
|
||||
@@ -150,7 +152,12 @@ impl Scheduler {
|
||||
/// Attempts to open `path`, load its contents into memory and create a new
|
||||
/// kernel process that will execute the loaded binary. Returns the PID of the
|
||||
/// created process, or -1 on failure.
|
||||
pub fn create_process_from_file<T: AsRef<Path>>(&mut self, path: T) -> i64 {
|
||||
pub fn create_process_from_file<T: AsRef<Path>>(
|
||||
&mut self,
|
||||
path: T,
|
||||
argc: isize,
|
||||
argv: *const *const u8,
|
||||
) -> i64 {
|
||||
let path = path.as_ref();
|
||||
let name = path.as_str();
|
||||
|
||||
@@ -231,25 +238,30 @@ impl Scheduler {
|
||||
// Entry point
|
||||
let entry_va = gelf.entry;
|
||||
let entry_addr = unsafe { base.add((entry_va - min_vaddr) as usize) } as *const u8;
|
||||
let entry_fn =
|
||||
unsafe { core::mem::transmute::<*const u8, extern "C" fn()>(entry_addr) };
|
||||
let wrapper = Box::new(move || {
|
||||
entry_fn();
|
||||
});
|
||||
let entry_fn = unsafe {
|
||||
core::mem::transmute::<*const u8, extern "C" fn(isize, *const *const u8)>(
|
||||
entry_addr,
|
||||
)
|
||||
};
|
||||
let wrapper = move |argc, argv| {
|
||||
entry_fn(argc, argv);
|
||||
};
|
||||
println!("Program loaded at : {:x?}", entry_addr);
|
||||
return self.create_process(wrapper, name);
|
||||
return self.create_process(wrapper, name, argc, argv);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: treat the file as a raw binary blob and execute in-place
|
||||
let entry_point = unsafe {
|
||||
core::mem::transmute::<*const u8, extern "C" fn()>(Vec::leak(content).as_ptr())
|
||||
core::mem::transmute::<*const u8, extern "C" fn(isize, *const *const u8)>(
|
||||
Vec::leak(content).as_ptr(),
|
||||
)
|
||||
};
|
||||
let wrapper = move |argc, argv| {
|
||||
entry_point(argc, argv);
|
||||
};
|
||||
let wrapper = Box::new(move || {
|
||||
entry_point();
|
||||
});
|
||||
|
||||
self.create_process(wrapper, name)
|
||||
self.create_process(wrapper, name, argc, argv)
|
||||
}
|
||||
|
||||
/// Creates a new process with the specified code and name.
|
||||
@@ -271,39 +283,48 @@ impl Scheduler {
|
||||
///
|
||||
/// The provided `code` function will be executed when the process is first
|
||||
/// scheduled. Returns the new PID, or -1 if the process table is full.
|
||||
pub fn create_process<T: Into<String>, F: Fn() + 'static + Send>(
|
||||
pub fn create_process<T: Into<String>, F: ProcessEntryTrait + 'static + Send>(
|
||||
&mut self,
|
||||
code: Box<F>,
|
||||
code: F,
|
||||
name: T,
|
||||
argc: isize,
|
||||
argv: *const *const u8,
|
||||
) -> i64 {
|
||||
// SAFETY: Initializing process in the global table.
|
||||
// Access is safe because we verified bounds and found a Dead slot.
|
||||
unsafe {
|
||||
self.process_table
|
||||
.insert(self.next_pid, Box::new(Process::default()));
|
||||
self.process_table.insert(self.next_pid, Process::default());
|
||||
let process = self.process_table.get_mut(&self.next_pid).unwrap();
|
||||
|
||||
// Configure process metadata
|
||||
process.pid = self.next_pid as i64;
|
||||
process.name = name.into();
|
||||
process.state = ProcessState::Activable;
|
||||
process.entry = Some(code);
|
||||
process.entry = Some(Box::new(code));
|
||||
|
||||
process.fd_table = Vec::new();
|
||||
FILE_SYSTEM.mount(
|
||||
format!("/proc/{}/0", process.pid).into(),
|
||||
Box::new(TTY0.clone()),
|
||||
);
|
||||
// FILE_SYSTEM.mount(
|
||||
// format!("/proc/{}/0", process.pid).into(),
|
||||
// Box::new(TTY0.clone()),
|
||||
// );
|
||||
// FD 0
|
||||
process.fd_table.push(Some(
|
||||
FILE_SYSTEM
|
||||
.open(format!("/proc/{}/0", process.pid).as_ref())
|
||||
.unwrap(),
|
||||
));
|
||||
process
|
||||
.fd_table
|
||||
.push(Some(FILE_SYSTEM.open("/dev/null".as_ref()).unwrap()));
|
||||
// FD 1
|
||||
process
|
||||
.fd_table
|
||||
.push(Some(FILE_SYSTEM.open("/dev/null".as_ref()).unwrap()));
|
||||
// FD 2
|
||||
process
|
||||
.fd_table
|
||||
.push(Some(FILE_SYSTEM.open("/dev/null".as_ref()).unwrap()));
|
||||
|
||||
// Configure execution context
|
||||
// a0 contains the pointer to the function to execute
|
||||
process.ctx.a[0] = &raw const *process.entry.as_ref().unwrap_unchecked() as u64;
|
||||
process.ctx.a[1] = argc as u64;
|
||||
process.ctx.a[2] = argv as u64;
|
||||
|
||||
// mepc points to process_launcher which will call the function
|
||||
process.ctx.mepc = process_launcher as *const _;
|
||||
@@ -338,10 +359,15 @@ impl Scheduler {
|
||||
/// This function is installed into the process `mepc` so that when the new
|
||||
/// process is scheduled it will run this launcher which calls the user
|
||||
/// function and ensures the process exits cleanly.
|
||||
extern "C" fn process_launcher(code: *const Box<dyn Fn()>) {
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
extern "C" fn process_launcher(
|
||||
code: *const Box<ProcessEntry>,
|
||||
argc: isize,
|
||||
argv: *const *const u8,
|
||||
) {
|
||||
// SAFETY: The code pointer was initialized in create_process
|
||||
// and points to a valid function.
|
||||
unsafe { (*code)() };
|
||||
unsafe { (*code)(argc, argv) };
|
||||
|
||||
// If user code didn't exit explicitly, call exit() to clean up the process
|
||||
exit();
|
||||
|
||||
@@ -17,7 +17,7 @@ use crate::{
|
||||
#[derive(Debug)]
|
||||
pub struct Scheduler {
|
||||
pub next_pid: u64,
|
||||
pub process_table: BTreeMap<u64, Box<Process>>,
|
||||
pub process_table: BTreeMap<u64, Process>,
|
||||
}
|
||||
|
||||
pub static ACTIVE_PID: AtomicU64 = AtomicU64::new(0);
|
||||
@@ -30,7 +30,7 @@ pub static SCHEDULER: Mutex<LazyCell<Scheduler>> = Mutex::new(LazyCell::new(|| S
|
||||
/// Idle loop executed when there is no runnable process.
|
||||
///
|
||||
/// Uses the `wfi` instruction to yield the CPU while waiting for interrupts.
|
||||
pub fn idle() {
|
||||
pub fn idle(_argc: isize, _argv: *const *const u8) {
|
||||
loop {
|
||||
// write_string_temp("idle");
|
||||
// info!("idle");
|
||||
@@ -47,7 +47,7 @@ impl Scheduler {
|
||||
/// it as the active process.
|
||||
pub fn init(&mut self) {
|
||||
info!("scheduler init");
|
||||
self.create_process(Box::new(idle), "idle");
|
||||
self.create_process(Box::new(idle), "idle", 0, core::ptr::null());
|
||||
self.process_table.get_mut(&0).unwrap().state = ProcessState::Active;
|
||||
}
|
||||
|
||||
@@ -69,9 +69,7 @@ impl Scheduler {
|
||||
}
|
||||
}
|
||||
|
||||
let mut current_process_iter = self
|
||||
.process_table
|
||||
.range_mut((Bound::Excluded(prev_pid), Bound::Unbounded));
|
||||
let mut current_process_iter = self.process_table.range_mut(prev_pid + 1..);
|
||||
|
||||
ACTIVE_PID.store(
|
||||
loop {
|
||||
|
||||
@@ -6,14 +6,15 @@ use core::time::Duration;
|
||||
|
||||
use shared::syscall::{sleep, write_string_temp};
|
||||
|
||||
pub fn test() {
|
||||
pub fn test(_argc: isize, _argv: *const *const u8) {
|
||||
loop {
|
||||
// write_string_temp(str::from_utf8(_args[0]).unwrap());
|
||||
write_string_temp("test");
|
||||
sleep(Duration::new(2, 0));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn proc2() {
|
||||
pub fn proc2(_argc: isize, _argv: *const *const u8) {
|
||||
loop {
|
||||
write_string_temp("proc2");
|
||||
sleep(Duration::new(3, 0));
|
||||
|
||||
@@ -22,6 +22,7 @@ pub struct VirtioPciDriver<S, F: Fn(&mut S, &VirtioInputEvent) = fn(&mut S, &Vir
|
||||
}
|
||||
|
||||
#[repr(u16)]
|
||||
#[allow(unused)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum EventType {
|
||||
Sync = 0,
|
||||
@@ -31,6 +32,7 @@ pub enum EventType {
|
||||
}
|
||||
|
||||
#[repr(u16)]
|
||||
#[allow(unused)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum EventCodeRelative {
|
||||
X = 0,
|
||||
@@ -39,6 +41,7 @@ pub enum EventCodeRelative {
|
||||
}
|
||||
|
||||
#[repr(u16)]
|
||||
#[allow(unused)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum EventCodeValue {
|
||||
Released = 0,
|
||||
|
||||
@@ -3,7 +3,6 @@ use io::SeekFrom;
|
||||
|
||||
use crate::{
|
||||
draw::{Color, Draw, FONT_HEIGHT, FONT_WIDTH},
|
||||
println,
|
||||
vga::{self, Vga},
|
||||
virtual_fs::{self, FILE_SYSTEM, VirtualFileSystem},
|
||||
};
|
||||
@@ -41,7 +40,6 @@ impl VirtualConsole {
|
||||
}
|
||||
|
||||
pub fn write_char(&mut self, c: char) {
|
||||
println!("char_console: {:?}", c as u64);
|
||||
let mut last_cursor = self.cursor;
|
||||
match c {
|
||||
'\n' => {
|
||||
|
||||
@@ -9,6 +9,7 @@ use hashbrown::HashMap;
|
||||
use io::{IoBase, Read, Seek, Write};
|
||||
|
||||
pub mod keyboard;
|
||||
pub mod null;
|
||||
pub mod stdin;
|
||||
pub mod virtual_stdin;
|
||||
|
||||
@@ -16,10 +17,12 @@ use crate::{
|
||||
fs::Disk,
|
||||
tty::TTY0,
|
||||
vga::Vga,
|
||||
virtual_fs::{keyboard::KeyboardBuffer, virtual_stdin::VirtualStdin},
|
||||
virtual_fs::{keyboard::KeyboardBuffer, null::Null, virtual_stdin::VirtualStdin},
|
||||
};
|
||||
|
||||
pub trait VirtualNode: IoBase<Error = ()> + Read + Write + Seek + Debug {}
|
||||
pub trait VirtualNode: IoBase<Error = ()> + Read + Write + Seek + Debug {
|
||||
fn close(&mut self) {}
|
||||
}
|
||||
|
||||
pub trait VirtualFileSystem: Debug {
|
||||
fn open(&mut self, path: &Path) -> Result<Box<dyn VirtualNode + '_>, ()>;
|
||||
@@ -62,6 +65,7 @@ pub unsafe fn init_file_system() {
|
||||
unsafe {
|
||||
FILE_SYSTEM.mount("/dev/fb0".into(), Box::new(VGAFileSystem));
|
||||
FILE_SYSTEM.mount("/dev/tty0".into(), Box::new(TTY0.clone()));
|
||||
FILE_SYSTEM.mount("/dev/null".into(), Box::new(Null));
|
||||
FILE_SYSTEM.mount(
|
||||
"/dev/input/keyboard".into(),
|
||||
Box::new(KeyboardBuffer::new()),
|
||||
|
||||
51
src/virtual_fs/null.rs
Normal file
51
src/virtual_fs/null.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use alloc::boxed::Box;
|
||||
use io::{IoBase, Read, Seek, Write};
|
||||
|
||||
use crate::virtual_fs::{VirtualFileSystem, VirtualNode};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Null;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NullNode;
|
||||
|
||||
impl VirtualFileSystem for Null {
|
||||
fn open(
|
||||
&mut self,
|
||||
path: &bffs::path::Path,
|
||||
) -> Result<alloc::boxed::Box<dyn crate::virtual_fs::VirtualNode + '_>, ()> {
|
||||
if !path.is_empty() {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(Box::new(NullNode))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IoBase for NullNode {
|
||||
type Error = ();
|
||||
}
|
||||
|
||||
impl Read for NullNode {
|
||||
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, Self::Error> {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Seek for NullNode {
|
||||
fn seek(&mut self, _pos: io::SeekFrom) -> Result<u64, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for NullNode {
|
||||
fn write(&mut self, _buf: &[u8]) -> Result<usize, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualNode for NullNode {}
|
||||
1
sysroot/lib/rustlib/src/rust/library/library
Symbolic link
1
sysroot/lib/rustlib/src/rust/library/library
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../../../../library
|
||||
35
user.ld
35
user.ld
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* ld directives the for barmetal RISCV
|
||||
*/
|
||||
OUTPUT_ARCH(riscv)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY {
|
||||
RAM (wxa) : ORIGIN = 0x0, LENGTH = 128M
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
. = 0x0;
|
||||
.text : {
|
||||
KEEP(*(.text._start))
|
||||
|
||||
*(.text .text.*)
|
||||
} > RAM
|
||||
|
||||
.rodata : {
|
||||
*(.rodata .rodata.*)
|
||||
} > RAM
|
||||
|
||||
.data : {
|
||||
*(.data .data.*)
|
||||
} > RAM
|
||||
|
||||
.bss : ALIGN(8) {
|
||||
__bss_start = .;
|
||||
*(.bss .bss.*)
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
_heap_start = ALIGN(8);
|
||||
_heap_end = ORIGIN(RAM) + LENGTH(RAM);
|
||||
}
|
||||
9
user/shell/Cargo.toml
Normal file
9
user/shell/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "shell"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
# std = { path = "../../crates/std" }
|
||||
# shared = { path = "../../crates/shared", features = ["user"] }
|
||||
# core = { path = "../../crates/std/crates/core" }
|
||||
9
user/shell/src/main.rs
Normal file
9
user/shell/src/main.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
fn main() {
|
||||
let a = std::env::args();
|
||||
for a in a {
|
||||
println!("Argument: {}", a);
|
||||
}
|
||||
println!(
|
||||
"Hello from PIC program loaded dynamically with custom std and a better justfile, and syscalls ! "
|
||||
);
|
||||
}
|
||||
@@ -4,4 +4,7 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
os-std = { path = "../../crates/os-std" }
|
||||
# std = { path = "../../crates/std" }
|
||||
shared = { path = "../../crates/shared", features = ["user"] }
|
||||
io = { path = "../../crates/io" }
|
||||
bffs = { path = "../../crates/bffs" }
|
||||
|
||||
@@ -1,30 +1,24 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![allow(unused)]
|
||||
|
||||
// use core::time::Duration;
|
||||
|
||||
use os_std::syscall;
|
||||
os_std::custom_std_setup! {}
|
||||
use io::{Read, Write};
|
||||
use std::io::{Stdin, stdin};
|
||||
use shared::syscall;
|
||||
|
||||
fn main() {
|
||||
// let mut input = String::new();
|
||||
let mut input = String::new();
|
||||
input.push('a');
|
||||
// let mut file = syscall::open("/dev/fb0");
|
||||
// syscall::seek(&mut file, SeekFrom::End(-3));
|
||||
// syscall::write(&mut file, &[255; 6400 * 50]);
|
||||
// syscall::sleep(Duration::from_secs_f64(2.0));
|
||||
let mut stdin = syscall::open("/dev/tty0");
|
||||
let mut file = syscall::open("/dev/tty0");
|
||||
syscall::close(0);
|
||||
let mut tty = syscall::open("/dev/tty0");
|
||||
tty.write(input.as_bytes()).unwrap();
|
||||
syscall::spawn("/usr/bin/shell");
|
||||
loop {
|
||||
let mut test = [0; 2];
|
||||
syscall::read(&mut stdin, &mut test);
|
||||
let len = *test.iter().find(|x| **x == 0).unwrap_or(&1) + 1;
|
||||
syscall::write(
|
||||
&mut file,
|
||||
str::from_utf8(&test[..len as usize]).unwrap().as_bytes(),
|
||||
);
|
||||
let len = tty.read(&mut test).unwrap();
|
||||
tty.write(str::from_utf8(&test[..len as usize]).unwrap().as_bytes())
|
||||
.unwrap();
|
||||
}
|
||||
// println!(
|
||||
// "Hello from PIC program loaded dynamically with custom std and a better justfile, and syscalls ! {:?}",
|
||||
// str::from_utf8(&test)
|
||||
// );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user