From 8eba5a3d9b424ada03595abaeb7ec9e845e8e8b9 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Tue, 16 Jul 2024 15:48:34 +0800 Subject: [PATCH] add: user library and some applications --- .idea/rCore.iml | 2 ++ user/.cargo/config.toml | 7 +++++++ user/.gitignore | 1 + user/Cargo.lock | 7 +++++++ user/Cargo.toml | 6 ++++++ user/Makefile | 18 ++++++++++++++++ user/src/bin/hello_world.rs | 12 +++++++++++ user/src/bin/illegal_instruction.rs | 17 +++++++++++++++ user/src/bin/power.rs | 27 ++++++++++++++++++++++++ user/src/bin/store_fault.rs | 15 ++++++++++++++ user/src/console.rs | 32 +++++++++++++++++++++++++++++ user/src/lib.rs | 31 ++++++++++++++++++++++++++++ user/src/linker.ld | 31 ++++++++++++++++++++++++++++ user/src/syscall.rs | 28 +++++++++++++++++++++++++ user/src/utils.rs | 29 ++++++++++++++++++++++++++ 15 files changed, 263 insertions(+) create mode 100644 user/.cargo/config.toml create mode 100644 user/.gitignore create mode 100644 user/Cargo.lock create mode 100644 user/Cargo.toml create mode 100644 user/Makefile create mode 100644 user/src/bin/hello_world.rs create mode 100644 user/src/bin/illegal_instruction.rs create mode 100644 user/src/bin/power.rs create mode 100644 user/src/bin/store_fault.rs create mode 100644 user/src/console.rs create mode 100644 user/src/lib.rs create mode 100644 user/src/linker.ld create mode 100644 user/src/syscall.rs create mode 100644 user/src/utils.rs diff --git a/.idea/rCore.iml b/.idea/rCore.iml index 31fc107..cd34bf0 100644 --- a/.idea/rCore.iml +++ b/.idea/rCore.iml @@ -3,7 +3,9 @@ + + diff --git a/user/.cargo/config.toml b/user/.cargo/config.toml new file mode 100644 index 0000000..9f0de54 --- /dev/null +++ b/user/.cargo/config.toml @@ -0,0 +1,7 @@ +[build] +target = "riscv64gc-unknown-none-elf" + +[target.riscv64gc-unknown-none-elf] +rustflags = [ + "-Clink-args=-Tsrc/linker.ld", "-Cforce-frame-pointers=yes" +] \ No newline at end of file diff --git a/user/.gitignore b/user/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/user/.gitignore @@ -0,0 +1 @@ +/target diff --git a/user/Cargo.lock b/user/Cargo.lock new file mode 100644 index 0000000..a700847 --- /dev/null +++ b/user/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "user_lib" +version = "0.1.0" diff --git a/user/Cargo.toml b/user/Cargo.toml new file mode 100644 index 0000000..3b080e3 --- /dev/null +++ b/user/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "user_lib" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/user/Makefile b/user/Makefile new file mode 100644 index 0000000..c643fbe --- /dev/null +++ b/user/Makefile @@ -0,0 +1,18 @@ +TARGET := riscv64gc-unknown-none-elf +MODE := release +APP_DIR := src/bin +TARGET_DIR := target/$(TARGET)/$(MODE) +APPS := $(wildcard $(APP_DIR)/*.rs) +ELFS := $(patsubst $(APP_DIR)/%.rs, $(TARGET_DIR)/%, $(APPS)) +BINS := $(patsubst $(APP_DIR)/%.rs, $(TARGET_DIR)/%.bin, $(APPS)) + +OBJDUMP := rust-objdump --arch-name=riscv64 +OBJCOPY := rust-objcopy --binary-architecture=riscv64 + +elf: + @cargo build --release + +binary: elf + @$(foreach elf, $(ELFS), $(OBJCOPY) $(elf) --strip-all -O binary $(patsubst $(TARGET_DIR)/%, $(TARGET_DIR)/%.bin, $(elf));) + +build: binary \ No newline at end of file diff --git a/user/src/bin/hello_world.rs b/user/src/bin/hello_world.rs new file mode 100644 index 0000000..5329f79 --- /dev/null +++ b/user/src/bin/hello_world.rs @@ -0,0 +1,12 @@ +#![no_std] +#![no_main] + +#[macro_use] +extern crate user_lib; + +#[no_mangle] +fn main() -> i32 { + println!("Hello, world!"); + + 0 +} \ No newline at end of file diff --git a/user/src/bin/illegal_instruction.rs b/user/src/bin/illegal_instruction.rs new file mode 100644 index 0000000..cbd3210 --- /dev/null +++ b/user/src/bin/illegal_instruction.rs @@ -0,0 +1,17 @@ +#![no_std] +#![no_main] + +#[macro_use] +extern crate user_lib; + +use core::arch::asm; + +#[no_mangle] +fn main() -> i32 { + println!("Try to execute privileged instruction in U Mode"); + println!("Kernel should kill this application!"); + unsafe { + asm!("sret"); + } + 0 +} \ No newline at end of file diff --git a/user/src/bin/power.rs b/user/src/bin/power.rs new file mode 100644 index 0000000..54fde24 --- /dev/null +++ b/user/src/bin/power.rs @@ -0,0 +1,27 @@ +#![no_std] +#![no_main] + +#[macro_use] +extern crate user_lib; + +const SIZE: usize = 10; +const P: u32 = 3; +const STEP: usize = 100000; +const MOD: u32 = 10007; + +#[no_mangle] +fn main() -> i32 { + let mut pow = [0u32; SIZE]; + let mut index: usize = 0; + pow[index] = 1; + for i in 1..=STEP { + let last = pow[index]; + index = (index + 1) % SIZE; + pow[index] = last * P % MOD; + if i % 10000 == 0 { + println!("{}^{}={}(MOD {})", P, i, pow[index], MOD); + } + } + println!("Test power OK!"); + 0 +} \ No newline at end of file diff --git a/user/src/bin/store_fault.rs b/user/src/bin/store_fault.rs new file mode 100644 index 0000000..aedf88b --- /dev/null +++ b/user/src/bin/store_fault.rs @@ -0,0 +1,15 @@ +#![no_std] +#![no_main] + +#[macro_use] +extern crate user_lib; + +#[no_mangle] +fn main() -> i32 { + println!("Into Test store_fault, we will insert an invalid store operation..."); + println!("Kernel should kill this application!"); + unsafe { + core::ptr::null_mut::().write_volatile(0); + } + 0 +} \ No newline at end of file diff --git a/user/src/console.rs b/user/src/console.rs new file mode 100644 index 0000000..0d41582 --- /dev/null +++ b/user/src/console.rs @@ -0,0 +1,32 @@ +use core::fmt::Write; +use crate::syscall::sys_write; + +struct Stdout; + +const STDOUT_FD: usize = 1; + +impl Write for Stdout { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + sys_write(STDOUT_FD, s.as_bytes()); + + Ok(()) + } +} + +pub fn print(args: core::fmt::Arguments) { + Stdout.write_fmt(args).unwrap(); +} + +#[macro_export] +macro_rules! print { + ($fmt: literal $(, $($arg: tt)+)?) => { + $crate::console::print(format_args!($fmt $(, $($arg)+)?)); + } +} + +#[macro_export] +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/user/src/lib.rs b/user/src/lib.rs new file mode 100644 index 0000000..9c42c3f --- /dev/null +++ b/user/src/lib.rs @@ -0,0 +1,31 @@ +#![no_std] +#![feature(linkage)] + +use crate::syscall::{sys_exit, sys_write}; + +mod utils; +mod syscall; +#[macro_use] +pub mod console; + +#[no_mangle] +#[link_section = ".text.entry"] +pub extern "C" fn _start() -> ! { + utils::clear_bss(); + exit(main()); + panic!("Unreachable after exit main!"); +} + +#[no_mangle] +#[linkage = "weak"] +pub fn main() -> i32 { + panic!("Cannot find main function!"); +} + +pub fn write(fd: usize, buf: &[u8]) -> isize { + sys_write(fd, buf) +} +pub fn exit(exit_code: i32) -> isize { + sys_exit(exit_code) +} + diff --git a/user/src/linker.ld b/user/src/linker.ld new file mode 100644 index 0000000..9d48923 --- /dev/null +++ b/user/src/linker.ld @@ -0,0 +1,31 @@ +OUTPUT_ARCH(riscv) +ENTRY(_start) + +BASE_ADDRESS = 0x80400000; + +SECTIONS +{ + . = BASE_ADDRESS; + .text : { + *(.text.entry) + *(.text .text.*) + } + .rodata : { + *(.rodata .rodata.*) + *(.srodata .srodata.*) + } + .data : { + *(.data .data.*) + *(.sdata .sdata.*) + } + .bss : { + start_bss = .; + *(.bss .bss.*) + *(.sbss .sbss.*) + end_bss = .; + } + /DISCARD/ : { + *(.eh_frame) + *(.debug*) + } +} \ No newline at end of file diff --git a/user/src/syscall.rs b/user/src/syscall.rs new file mode 100644 index 0000000..b4a305d --- /dev/null +++ b/user/src/syscall.rs @@ -0,0 +1,28 @@ +use core::arch::asm; + +const SYSCALL_WRITE: usize = 64; +const SYSCALL_EXIT: usize = 93; + +fn syscall(id: usize, args: [usize; 3]) -> isize { + let mut result : isize; + + unsafe { + asm!( + "ecall", + inlateout("x10") args[0] => result, + in("x11") args[1], + in("x12") args[2], + in("x17") id + ) + } + + result +} + +pub fn sys_write(fd: usize, buffer: &[u8]) -> isize { + syscall(SYSCALL_WRITE, [fd, buffer.as_ptr() as usize, buffer.len()]) +} + +pub fn sys_exit(exit_code: i32) -> isize { + syscall(SYSCALL_EXIT, [exit_code as usize, 0, 0]) +} \ No newline at end of file diff --git a/user/src/utils.rs b/user/src/utils.rs new file mode 100644 index 0000000..85b7f0f --- /dev/null +++ b/user/src/utils.rs @@ -0,0 +1,29 @@ +use core::panic::PanicInfo; +use crate::println; + +pub fn clear_bss() { + extern "C" { + fn start_bss(); + + fn end_bss(); + } + + for i in start_bss as usize..end_bss as usize { + unsafe { + (i as *mut u8).write_volatile(0) + } + } +} + +#[panic_handler] +fn panic_handler(info: &PanicInfo) -> ! { + let message = info.message(); + + if let Some(location) = info.location() { + println!("Panicked at {}:{} {}", location.file(), location.line(), message); + } else { + println!("Panicked: {}", message); + } + + unreachable!() +} \ No newline at end of file