From 265e7adedfc600948a2a4436e87811ad08158c32 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Fri, 19 Jul 2024 13:52:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=89=B9=E5=A4=84=E7=90=86=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E7=B3=BB=E7=BB=9F=20(#1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-on: https://git.rrricardo.top/jackfiled/rCore/pulls/1 --- README.md | 15 +++ os/Cargo.lock | 71 ++++++++++++ os/Cargo.toml | 2 + os/build.rs | 56 ++++++++++ os/src/.gitignore | 1 + os/src/batch.rs | 162 ++++++++++++++++++++++++++++ os/src/console.rs | 4 +- os/src/main.rs | 22 ++-- os/src/sbi.rs | 4 +- os/src/sync.rs | 1 + os/src/sync/single_cell.rs | 22 ++++ os/src/syscall.rs | 18 ++++ os/src/syscall/fs.rs | 17 +++ os/src/syscall/process.rs | 7 ++ os/src/trap.asm | 65 +++++++++++ os/src/trap.rs | 53 +++++++++ os/src/trap/context.rs | 28 +++++ os/src/utils.rs | 14 +-- user/src/bin/hello_world.rs | 2 +- user/src/bin/illegal_instruction.rs | 2 +- user/src/bin/power.rs | 2 +- user/src/bin/store_fault.rs | 2 +- user/src/console.rs | 4 +- user/src/lib.rs | 3 +- user/src/syscall.rs | 4 +- user/src/utils.rs | 15 +-- 26 files changed, 559 insertions(+), 37 deletions(-) create mode 100644 README.md create mode 100644 os/build.rs create mode 100644 os/src/.gitignore create mode 100644 os/src/batch.rs create mode 100644 os/src/sync.rs create mode 100644 os/src/sync/single_cell.rs create mode 100644 os/src/syscall.rs create mode 100644 os/src/syscall/fs.rs create mode 100644 os/src/syscall/process.rs create mode 100644 os/src/trap.asm create mode 100644 os/src/trap.rs create mode 100644 os/src/trap/context.rs diff --git a/README.md b/README.md new file mode 100644 index 0000000..12c8596 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Rust RISC-V 操作系统 + +按照[rCore](https://rcore-os.cn/rCore-Tutorial-Book-v3/chapter0/index.html)的教程进行开发。 + +## 目前进度 + +- [x] 基本执行环境 +- [x] 批处理系统 +- [ ] 多道程序和分时系统 +- [ ] 地址空间 +- [ ] 文件系统 +- [ ] 进程间通信和I/O重定向 +- [ ] 并发 +- [ ] I/O设备管理 + diff --git a/os/Cargo.lock b/os/Cargo.lock index 0ddea58..3775338 100644 --- a/os/Cargo.lock +++ b/os/Cargo.lock @@ -2,13 +2,72 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + [[package]] name = "os" version = "0.1.0" dependencies = [ + "lazy_static", + "riscv", "sbi-rt", ] +[[package]] +name = "riscv" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa3145d2fae3778b1e31ec2e827b228bdc6abd9b74bb5705ba46dcb82069bc4f" +dependencies = [ + "bit_field", + "critical-section", + "embedded-hal", +] + [[package]] name = "sbi-rt" version = "0.0.2" @@ -27,8 +86,20 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/os/Cargo.toml b/os/Cargo.toml index 7fb4302..22acc70 100644 --- a/os/Cargo.toml +++ b/os/Cargo.toml @@ -5,3 +5,5 @@ edition = "2021" [dependencies] sbi-rt = { version = "0.0.2", features = ["legacy"] } +lazy_static = { version = "1.4.0", features = ["spin_no_std"] } +riscv = { version = "0.10.0" } diff --git a/os/build.rs b/os/build.rs new file mode 100644 index 0000000..3cd2e06 --- /dev/null +++ b/os/build.rs @@ -0,0 +1,56 @@ +use std::fs::{read_dir, File}; +use std::io::{Result, Write}; + +fn main() { + println!("cargo:rerun-if-changed=../user/src/"); + println!("cargo:rerun-if-changed={}", TARGET_PATH); + insert_app_data().unwrap(); +} + +static TARGET_PATH: &str = "../user/target/riscv64gc-unknown-none-elf/release/"; + +fn insert_app_data() -> Result<()> { + let mut f = File::create("src/link_app.asm").unwrap(); + let mut apps: Vec<_> = read_dir("../user/src/bin") + .unwrap() + .into_iter() + .map(|dir_entry| { + let mut name_with_ext = dir_entry.unwrap().file_name().into_string().unwrap(); + name_with_ext.drain(name_with_ext.find('.').unwrap()..name_with_ext.len()); + name_with_ext + }) + .collect(); + apps.sort(); + + writeln!( + f, + r#" + .align 3 + .section .data + .global _num_app +_num_app: + .quad {}"#, + apps.len() + )?; + + for i in 0..apps.len() { + writeln!(f, r#" .quad app_{}_start"#, i)?; + } + writeln!(f, r#" .quad app_{}_end"#, apps.len() - 1)?; + + for (idx, app) in apps.iter().enumerate() { + println!("app_{}: {}", idx, app); + writeln!( + f, + r#" + .section .data + .global app_{0}_start + .global app_{0}_end +app_{0}_start: + .incbin "{2}{1}.bin" +app_{0}_end:"#, + idx, app, TARGET_PATH + )?; + } + Ok(()) +} diff --git a/os/src/.gitignore b/os/src/.gitignore new file mode 100644 index 0000000..09f0f39 --- /dev/null +++ b/os/src/.gitignore @@ -0,0 +1 @@ +link_app.asm diff --git a/os/src/batch.rs b/os/src/batch.rs new file mode 100644 index 0000000..2b09e78 --- /dev/null +++ b/os/src/batch.rs @@ -0,0 +1,162 @@ +use core::arch::asm; + +use lazy_static::lazy_static; + +use crate::log_information; +use crate::sbi::shutdown; +use crate::sync::single_cell::SingleCell; +use crate::trap::context::TrapContext; + +const MAX_APP_NUMBER: usize = 32; +const APP_BASE_ADDRESS: usize = 0x80400000; +const APP_SIZE_LIMIT: usize = 0x20000; + +struct AppManager { + app_count: usize, + current: usize, + start_addresses: [usize; MAX_APP_NUMBER + 1], +} + +lazy_static! { + static ref APP_MANAGER: SingleCell = unsafe { + SingleCell::new({ + extern "C" { + fn _num_app(); + } + + let num_app_ptr = _num_app as usize as *const usize; + let num_app = num_app_ptr.read_volatile(); + let mut start_addresses: [usize; MAX_APP_NUMBER + 1] = [0; MAX_APP_NUMBER + 1]; + let start_addresses_raw: &[usize] = + core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1); + start_addresses[..=num_app].copy_from_slice(start_addresses_raw); + AppManager { + app_count: num_app, + current: 0, + start_addresses, + } + }) + }; +} + +impl AppManager { + pub fn print_app_information(&self) { + log_information!("[kernel] Application count is {}.", self.app_count); + + for i in 0..self.app_count { + log_information!( + "[kernel] Application_{} ({:#x} -> {:#x})", + i, + self.start_addresses[i], + self.start_addresses[i + 1] + ); + } + } + + pub fn get_current_app(&self) -> usize { + self.current + } + + pub fn move_to_next_app(&mut self) { + self.current += 1; + } + + unsafe fn load_app(&self, app_id: usize) { + if app_id >= self.app_count { + panic!("Application id is invalid!"); + } + + log_information!("[kernel] Loading application_{}...", app_id); + + core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *mut u8, APP_SIZE_LIMIT).fill(0); + + let app_source = core::slice::from_raw_parts( + self.start_addresses[app_id] as *const u8, + self.start_addresses[app_id + 1] - self.start_addresses[app_id], + ); + let app_destination = + core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *mut u8, app_source.len()); + app_destination.copy_from_slice(app_source); + + // 保证指令缓存的更新 + // 因为上述代码会修改指令数据段 + asm!("fence.i"); + } +} + +const USER_STACK_SIZE: usize = 4096 * 2; +const KERNEL_STACK_SIZE: usize = 4096 * 2; + +#[repr(align(4096))] +struct UserStack { + data: [u8; USER_STACK_SIZE], +} + +impl UserStack { + fn get_sp(&self) -> usize { + self.data.as_ptr() as usize + USER_STACK_SIZE + } +} + +#[repr(align(4096))] +struct KernelStack { + data: [u8; KERNEL_STACK_SIZE], +} + +impl KernelStack { + fn get_sp(&self) -> usize { + self.data.as_ptr() as usize + KERNEL_STACK_SIZE + } + + pub fn push_context(&self, context: TrapContext) -> &'static mut TrapContext { + let context_pointer = (self.get_sp() - size_of::()) as *mut TrapContext; + unsafe { + *context_pointer = context; + context_pointer.as_mut().unwrap() + } + } +} + +static KERNEL_STACK: KernelStack = KernelStack { + data: [0; KERNEL_STACK_SIZE], +}; +static USER_STACK: UserStack = UserStack { + data: [0; USER_STACK_SIZE], +}; + +pub fn print_app_information() { + let app_manager = APP_MANAGER.exclusive_borrow(); + app_manager.print_app_information(); +} + +pub fn run_next_application() -> ! { + let mut app_manager = APP_MANAGER.exclusive_borrow(); + let current_app = app_manager.get_current_app(); + if current_app >= app_manager.app_count { + log_information!("Run out of applications, the os will stop!"); + shutdown(true); + } + + unsafe { + app_manager.load_app(current_app); + } + app_manager.move_to_next_app(); + + // We must drop resource manually + // As this function will never return! + drop(app_manager); + + extern "C" { + fn __restore(context_address: usize); + } + + unsafe { + let context_address = KERNEL_STACK.push_context(TrapContext::init_application_context( + APP_BASE_ADDRESS, + USER_STACK.get_sp(), + )) as *const _ as usize; + __restore(context_address); + + unreachable!() + } +} diff --git a/os/src/console.rs b/os/src/console.rs index 7d2b0cf..e88704f 100644 --- a/os/src/console.rs +++ b/os/src/console.rs @@ -1,6 +1,6 @@ +use crate::sbi::console_print; use core::fmt; use core::fmt::Write; -use crate::sbi::console_print; struct Stdout; @@ -65,4 +65,4 @@ macro_rules! log_trace { ($fmt: literal $(, $($arg: tt)+)?) => { $crate::console::print(format_args!(concat!("\x1b[90m" ,concat!($fmt, "\x1b[0m\n")) $(, $($arg)+)?)); } -} \ No newline at end of file +} diff --git a/os/src/main.rs b/os/src/main.rs index 7d69b5e..c2e2c42 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -1,23 +1,25 @@ #![no_std] #![no_main] -use core::arch::global_asm; use crate::utils::clear_bss; +use core::arch::global_asm; -mod utils; -mod sbi; +mod batch; mod console; +mod sbi; +mod sync; +mod syscall; +mod trap; +mod utils; global_asm!(include_str!("entry.asm")); +global_asm!(include_str!("link_app.asm")); #[no_mangle] fn rust_main() -> ! { clear_bss(); - log_error!("Hello, rCore!"); - log_warning!("Hello, rCore!"); - log_information!("Hello, rCore!"); - log_debug!("Hello, rCore!"); - log_trace!("Hello, rCore!"); - sbi::shutdown(false); + log_information!("[kernel] Hello, rCore!"); + trap::init(); + batch::print_app_information(); + batch::run_next_application(); } - diff --git a/os/src/sbi.rs b/os/src/sbi.rs index 322fb0b..73c351c 100644 --- a/os/src/sbi.rs +++ b/os/src/sbi.rs @@ -4,7 +4,7 @@ pub fn console_print(c: usize) { } pub fn shutdown(failure: bool) -> ! { - use sbi_rt::{system_reset, Shutdown, NoReason, SystemFailure}; + use sbi_rt::{system_reset, NoReason, Shutdown, SystemFailure}; if failure { system_reset(Shutdown, SystemFailure); @@ -13,4 +13,4 @@ pub fn shutdown(failure: bool) -> ! { } unreachable!() -} \ No newline at end of file +} diff --git a/os/src/sync.rs b/os/src/sync.rs new file mode 100644 index 0000000..01d434f --- /dev/null +++ b/os/src/sync.rs @@ -0,0 +1 @@ +pub mod single_cell; diff --git a/os/src/sync/single_cell.rs b/os/src/sync/single_cell.rs new file mode 100644 index 0000000..f6687cd --- /dev/null +++ b/os/src/sync/single_cell.rs @@ -0,0 +1,22 @@ +use core::cell::{RefCell, RefMut}; + +/// 只能在单核场景下保持安全的屑RefCell +pub struct SingleCell { + inner: RefCell, +} + +unsafe impl Sync for SingleCell {} + +impl SingleCell { + pub unsafe fn new(value: T) -> SingleCell { + SingleCell { + inner: RefCell::new(value), + } + } + + /// 独占访问 + /// 当已被借用时访问会Panic + pub fn exclusive_borrow(&self) -> RefMut<'_, T> { + self.inner.borrow_mut() + } +} diff --git a/os/src/syscall.rs b/os/src/syscall.rs new file mode 100644 index 0000000..91cf8d9 --- /dev/null +++ b/os/src/syscall.rs @@ -0,0 +1,18 @@ +use crate::syscall::fs::sys_write; +use crate::syscall::process::sys_exit; + +mod fs; +mod process; + +const SYSCALL_WRITE: usize = 64; +const SYSCALL_EXIT: usize = 93; + +pub fn syscall(syscall_id: usize, args: [usize; 3]) -> usize { + match syscall_id { + SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]), + SYSCALL_EXIT => sys_exit(args[0] as i32), + _ => { + panic!("Unsupported syscall: {}", syscall_id) + } + } +} diff --git a/os/src/syscall/fs.rs b/os/src/syscall/fs.rs new file mode 100644 index 0000000..859e998 --- /dev/null +++ b/os/src/syscall/fs.rs @@ -0,0 +1,17 @@ +use crate::print; + +const STDOUT_FD: usize = 1; + +pub fn sys_write(fd: usize, buffer: *const u8, len: usize) -> usize { + match fd { + STDOUT_FD => { + let slice = unsafe { core::slice::from_raw_parts(buffer, len) }; + let str = core::str::from_utf8(slice).unwrap(); + print!("{}", str); + len as usize + } + _ => { + panic!("Unsupported file descriptor in sys_write"); + } + } +} diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs new file mode 100644 index 0000000..619c197 --- /dev/null +++ b/os/src/syscall/process.rs @@ -0,0 +1,7 @@ +use crate::batch::run_next_application; +use crate::println; + +pub fn sys_exit(exit_state: i32) -> ! { + println!("[kernel] Application exited with code {}.", exit_state); + run_next_application() +} diff --git a/os/src/trap.asm b/os/src/trap.asm new file mode 100644 index 0000000..7ca7154 --- /dev/null +++ b/os/src/trap.asm @@ -0,0 +1,65 @@ +.altmacro +.macro SAVE_GP n + sd x\n, \n*8(sp) +.endm +.macro LOAD_GP n + ld x\n, \n*8(sp) +.endm + + .section .text + .global __alltraps + .global __restore + .align 2 +__alltraps: + csrrw sp, sscratch, sp + # now sp->kernel stack, sscratch->user stack + # allocate a TrapContext on kernel stack + addi sp, sp, -34*8 + # save general-purpose registers + sd x1, 1*8(sp) + # skip sp(x2), we will save it later + sd x3, 3*8(sp) + # skip tp(x4), application does not use it + # save x5~x31 + .set n, 5 + .rept 27 + SAVE_GP %n + .set n, n+1 + .endr + # we can use t0/t1/t2 freely, because they were saved on kernel stack + csrr t0, sstatus + csrr t1, sepc + sd t0, 32*8(sp) + sd t1, 33*8(sp) + # read user stack from sscratch and save it on the kernel stack + csrr t2, sscratch + sd t2, 2*8(sp) + # set input argument of trap_handler(cx: &mut TrapContext) + mv a0, sp + call trap_handler + +__restore: + # case1: start running app by __restore + # case2: back to U after handling trap + mv sp, a0 + # now sp->kernel stack(after allocated), sscratch->user stack + # restore sstatus/sepc + ld t0, 32*8(sp) + ld t1, 33*8(sp) + ld t2, 2*8(sp) + csrw sstatus, t0 + csrw sepc, t1 + csrw sscratch, t2 + # restore general-purpuse registers except sp/tp + ld x1, 1*8(sp) + ld x3, 3*8(sp) + .set n, 5 + .rept 27 + LOAD_GP %n + .set n, n+1 + .endr + # release TrapContext on kernel stack + addi sp, sp, 34*8 + # now sp->kernel stack, sscratch->user stack + csrrw sp, sscratch, sp + sret \ No newline at end of file diff --git a/os/src/trap.rs b/os/src/trap.rs new file mode 100644 index 0000000..e7aec3e --- /dev/null +++ b/os/src/trap.rs @@ -0,0 +1,53 @@ +use crate::batch::run_next_application; +use crate::println; +use crate::syscall::syscall; +use crate::trap::context::TrapContext; +use core::arch::global_asm; +use riscv::register::{ + mtvec::TrapMode, + scause::{self, Exception, Trap}, + stval, stvec, +}; + +pub mod context; + +global_asm!(include_str!("trap.asm")); + +pub fn init() { + extern "C" { + fn __alltraps(); + } + unsafe { + stvec::write(__alltraps as usize, TrapMode::Direct); + } +} + +#[no_mangle] +pub fn trap_handler(context: &mut TrapContext) -> &mut TrapContext { + let scause = scause::read(); + let stval = stval::read(); + + match scause.cause() { + Trap::Exception(Exception::UserEnvCall) => { + context.sepc += 4; + context.x[10] = syscall(context.x[17], [context.x[10], context.x[11], context.x[12]]); + } + Trap::Exception(Exception::StoreFault) | Trap::Exception(Exception::StorePageFault) => { + println!("[kernel] PageFault in application, kernel will kill it."); + run_next_application(); + } + Trap::Exception(Exception::IllegalInstruction) => { + println!("[kernel] Illegal instruction in application, kernel will kill it."); + run_next_application(); + } + _ => { + panic!( + "[Kernel] Unsupported trap: {:?}, stval = {:#x}!", + scause.cause(), + stval + ); + } + } + + context +} diff --git a/os/src/trap/context.rs b/os/src/trap/context.rs new file mode 100644 index 0000000..c467b0a --- /dev/null +++ b/os/src/trap/context.rs @@ -0,0 +1,28 @@ +use riscv::register::sstatus::{self, Sstatus, SPP}; + +#[repr(C)] +pub struct TrapContext { + pub x: [usize; 32], + pub s_status: Sstatus, + pub sepc: usize, +} + +impl TrapContext { + pub unsafe fn init_application_context(entry: usize, sp: usize) -> Self { + let sstatus = sstatus::read(); + sstatus::set_spp(SPP::User); + let mut context = Self { + x: [0; 32], + s_status: sstatus, + sepc: entry, + }; + + context.set_sp(sp); + context + } + + pub fn set_sp(&mut self, sp: usize) { + // x2 is stack pointer register + self.x[2] = sp; + } +} diff --git a/os/src/utils.rs b/os/src/utils.rs index 9d5fdad..72f9175 100644 --- a/os/src/utils.rs +++ b/os/src/utils.rs @@ -1,17 +1,19 @@ use core::panic::PanicInfo; -use crate::println; + +use crate::log_error; use crate::sbi::shutdown; #[panic_handler] fn panic(info: &PanicInfo) -> ! { if let Some(location) = info.location() { - println!("Panicked at {}:{} {}.", + log_error!( + "Panicked at {}:{} {}.", location.file(), location.line(), info.message() ); } else { - println!("Panicked: {}.", info.message()); + log_error!("Panicked: {}.", info.message()); } shutdown(true) @@ -24,8 +26,6 @@ pub fn clear_bss() { } for m in sbss as usize..ebss as usize { - unsafe { - (m as *mut u8).write_volatile(0) - } + unsafe { (m as *mut u8).write_volatile(0) } } -} \ No newline at end of file +} diff --git a/user/src/bin/hello_world.rs b/user/src/bin/hello_world.rs index 5329f79..f457094 100644 --- a/user/src/bin/hello_world.rs +++ b/user/src/bin/hello_world.rs @@ -9,4 +9,4 @@ 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 index cbd3210..04dac37 100644 --- a/user/src/bin/illegal_instruction.rs +++ b/user/src/bin/illegal_instruction.rs @@ -14,4 +14,4 @@ fn main() -> i32 { asm!("sret"); } 0 -} \ No newline at end of file +} diff --git a/user/src/bin/power.rs b/user/src/bin/power.rs index 54fde24..f628f34 100644 --- a/user/src/bin/power.rs +++ b/user/src/bin/power.rs @@ -24,4 +24,4 @@ fn main() -> i32 { } 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 index aedf88b..f8023eb 100644 --- a/user/src/bin/store_fault.rs +++ b/user/src/bin/store_fault.rs @@ -12,4 +12,4 @@ fn main() -> i32 { 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 index 0d41582..253fb41 100644 --- a/user/src/console.rs +++ b/user/src/console.rs @@ -1,5 +1,5 @@ -use core::fmt::Write; use crate::syscall::sys_write; +use core::fmt::Write; struct Stdout; @@ -29,4 +29,4 @@ 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 index 9c42c3f..fbe8862 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -3,8 +3,8 @@ use crate::syscall::{sys_exit, sys_write}; -mod utils; mod syscall; +mod utils; #[macro_use] pub mod console; @@ -28,4 +28,3 @@ pub fn write(fd: usize, buf: &[u8]) -> isize { pub fn exit(exit_code: i32) -> isize { sys_exit(exit_code) } - diff --git a/user/src/syscall.rs b/user/src/syscall.rs index b4a305d..6025b8e 100644 --- a/user/src/syscall.rs +++ b/user/src/syscall.rs @@ -4,7 +4,7 @@ const SYSCALL_WRITE: usize = 64; const SYSCALL_EXIT: usize = 93; fn syscall(id: usize, args: [usize; 3]) -> isize { - let mut result : isize; + let mut result: isize; unsafe { asm!( @@ -25,4 +25,4 @@ pub fn sys_write(fd: usize, buffer: &[u8]) -> isize { 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 index 85b7f0f..2644afe 100644 --- a/user/src/utils.rs +++ b/user/src/utils.rs @@ -1,5 +1,5 @@ -use core::panic::PanicInfo; use crate::println; +use core::panic::PanicInfo; pub fn clear_bss() { extern "C" { @@ -9,9 +9,7 @@ pub fn clear_bss() { } for i in start_bss as usize..end_bss as usize { - unsafe { - (i as *mut u8).write_volatile(0) - } + unsafe { (i as *mut u8).write_volatile(0) } } } @@ -20,10 +18,15 @@ fn panic_handler(info: &PanicInfo) -> ! { let message = info.message(); if let Some(location) = info.location() { - println!("Panicked at {}:{} {}", location.file(), location.line(), message); + println!( + "Panicked at {}:{} {}", + location.file(), + location.line(), + message + ); } else { println!("Panicked: {}", message); } unreachable!() -} \ No newline at end of file +}