diff --git a/guide-code/ch1-3mini-rt-usrland/.cargo/config b/guide-code/ch1-3mini-rt-usrland/.cargo/config new file mode 100644 index 0000000..f03976a --- /dev/null +++ b/guide-code/ch1-3mini-rt-usrland/.cargo/config @@ -0,0 +1,2 @@ +[build] +target = "riscv64gc-unknown-none-elf" diff --git a/guide-code/ch1-3mini-rt-usrland/Cargo.toml b/guide-code/ch1-3mini-rt-usrland/Cargo.toml new file mode 100644 index 0000000..60b4d6d --- /dev/null +++ b/guide-code/ch1-3mini-rt-usrland/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "os" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/guide-code/ch1-3mini-rt-usrland/README.md b/guide-code/ch1-3mini-rt-usrland/README.md new file mode 100644 index 0000000..54fb65c --- /dev/null +++ b/guide-code/ch1-3mini-rt-usrland/README.md @@ -0,0 +1,10 @@ +# rust-no-std-examples + +### Usage + +```bash +cargo build +qemu-riscv64 target/riscv64gc-unknown-none-elf/debug/os; echo $? +# Hello world! +# 9 +``` diff --git a/guide-code/ch1-3mini-rt-usrland/src/console.rs b/guide-code/ch1-3mini-rt-usrland/src/console.rs new file mode 100644 index 0000000..111b4b5 --- /dev/null +++ b/guide-code/ch1-3mini-rt-usrland/src/console.rs @@ -0,0 +1,27 @@ +use core::fmt::{Write, Arguments, Result}; +use crate::sys_write; + +struct Stdout; + +impl Write for Stdout { + fn write_str(&mut self, s: &str) -> Result { + sys_write(1, s.as_bytes()); + Ok(()) + } +} + +pub fn print(args: Arguments) { + Stdout.write_fmt(args).unwrap(); +} + +macro_rules! print { + ($fmt: literal $(, $($arg: tt)+)?) => { + $crate::console::print(format_args!($fmt $(, $($arg)+)?)); + } +} + +macro_rules! println { + ($fmt: literal $(, $($arg: tt)+)?) => { + $crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)); + } +} \ No newline at end of file diff --git a/guide-code/ch1-3mini-rt-usrland/src/lang_item.rs b/guide-code/ch1-3mini-rt-usrland/src/lang_item.rs new file mode 100644 index 0000000..c03b953 --- /dev/null +++ b/guide-code/ch1-3mini-rt-usrland/src/lang_item.rs @@ -0,0 +1,6 @@ +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop {} +} diff --git a/guide-code/ch1-3mini-rt-usrland/src/main.rs b/guide-code/ch1-3mini-rt-usrland/src/main.rs new file mode 100644 index 0000000..17547cd --- /dev/null +++ b/guide-code/ch1-3mini-rt-usrland/src/main.rs @@ -0,0 +1,40 @@ +// os/src/main.rs +#![no_std] +#![no_main] +#![feature(panic_info_message)] + +mod lang_item; +#[macro_use] +mod console; + +const SYSCALL_EXIT: usize = 93; +const SYSCALL_WRITE: usize = 64; + +fn syscall(id: usize, args: [usize; 3]) -> isize { + let mut ret; + unsafe { + core::arch::asm!( + "ecall", + inlateout("x10") args[0] => ret, + in("x11") args[1], + in("x12") args[2], + in("x17") id, + ); + } + ret +} + +pub fn sys_exit(xstate: i32) -> isize { + syscall(SYSCALL_EXIT, [xstate as usize, 0, 0]) +} + +pub fn sys_write(fd: usize, buffer: &[u8]) -> isize { + syscall(SYSCALL_WRITE, [fd, buffer.as_ptr() as usize, buffer.len()]) +} + +#[no_mangle] +extern "C" fn _start() { + print!("Hello "); + println!("world!"); + sys_exit(9); +}