add #![deny(missing_docs)] AND #![deny(warnings)] in main.rs, and add more comments
This commit is contained in:
parent
5946903948
commit
139fbc637a
9 changed files with 42 additions and 14 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -15,3 +15,4 @@ easy-fs-fuse/Cargo.lock
|
||||||
easy-fs-fuse/target/*
|
easy-fs-fuse/target/*
|
||||||
tools/
|
tools/
|
||||||
pushall.sh
|
pushall.sh
|
||||||
|
*.bak
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
//! We then call [`task::run_first_task()`] and for the first time go to
|
//! We then call [`task::run_first_task()`] and for the first time go to
|
||||||
//! userspace.
|
//! userspace.
|
||||||
|
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
#![deny(warnings)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(panic_info_message)]
|
#![feature(panic_info_message)]
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl<T> UPSafeCell<T> {
|
||||||
inner: RefCell::new(value),
|
inner: RefCell::new(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Panic if the data has been borrowed.
|
/// Exclusive access inner data in UPSafeCell. Panic if the data has been borrowed.
|
||||||
pub fn exclusive_access(&self) -> RefMut<'_, T> {
|
pub fn exclusive_access(&self) -> RefMut<'_, T> {
|
||||||
self.inner.borrow_mut()
|
self.inner.borrow_mut()
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::task::current_user_token;
|
||||||
|
|
||||||
const FD_STDOUT: usize = 1;
|
const FD_STDOUT: usize = 1;
|
||||||
|
|
||||||
|
/// write buf of length `len` to a file with `fd`
|
||||||
pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
|
pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
|
||||||
match fd {
|
match fd {
|
||||||
FD_STDOUT => {
|
FD_STDOUT => {
|
||||||
|
|
|
@ -3,17 +3,20 @@
|
||||||
use crate::task::{exit_current_and_run_next, suspend_current_and_run_next};
|
use crate::task::{exit_current_and_run_next, suspend_current_and_run_next};
|
||||||
use crate::timer::get_time_ms;
|
use crate::timer::get_time_ms;
|
||||||
|
|
||||||
|
/// task exits and submit an exit code
|
||||||
pub fn sys_exit(exit_code: i32) -> ! {
|
pub fn sys_exit(exit_code: i32) -> ! {
|
||||||
println!("[kernel] Application exited with code {}", exit_code);
|
println!("[kernel] Application exited with code {}", exit_code);
|
||||||
exit_current_and_run_next();
|
exit_current_and_run_next();
|
||||||
panic!("Unreachable in sys_exit!");
|
panic!("Unreachable in sys_exit!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// current task gives up resources for other tasks
|
||||||
pub fn sys_yield() -> isize {
|
pub fn sys_yield() -> isize {
|
||||||
suspend_current_and_run_next();
|
suspend_current_and_run_next();
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// get current time
|
||||||
pub fn sys_get_time() -> isize {
|
pub fn sys_get_time() -> isize {
|
||||||
get_time_ms() as isize
|
get_time_ms() as isize
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,16 @@ use crate::trap::trap_return;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
/// task context structure containing some registers
|
/// task context structure containing some registers
|
||||||
pub struct TaskContext {
|
pub struct TaskContext {
|
||||||
|
/// return address ( e.g. __restore ) of __switch ASM function
|
||||||
ra: usize,
|
ra: usize,
|
||||||
|
/// kernel stack pointer of app
|
||||||
sp: usize,
|
sp: usize,
|
||||||
|
/// callee saved registers: s 0..11
|
||||||
s: [usize; 12],
|
s: [usize; 12],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TaskContext {
|
impl TaskContext {
|
||||||
|
/// init task context
|
||||||
pub fn zero_init() -> Self {
|
pub fn zero_init() -> Self {
|
||||||
Self {
|
Self {
|
||||||
ra: 0,
|
ra: 0,
|
||||||
|
@ -17,6 +21,7 @@ impl TaskContext {
|
||||||
s: [0; 12],
|
s: [0; 12],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// set Task Context{__restore ASM funciton: trap_return, sp: kstack_ptr, s: s_0..12}
|
||||||
pub fn goto_trap_return(kstack_ptr: usize) -> Self {
|
pub fn goto_trap_return(kstack_ptr: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ra: trap_return as usize,
|
ra: trap_return as usize,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
//! A single global instance of [`TaskManager`] called `TASK_MANAGER` controls
|
//! A single global instance of [`TaskManager`] called `TASK_MANAGER` controls
|
||||||
//! all the tasks in the operating system.
|
//! all the tasks in the operating system.
|
||||||
//!
|
//!
|
||||||
//! Be careful when you see [`__switch`]. Control flow around this function
|
//! Be careful when you see `__switch` ASM function in `switch.S`. Control flow around this function
|
||||||
//! might not be what you expect.
|
//! might not be what you expect.
|
||||||
|
|
||||||
mod context;
|
mod context;
|
||||||
|
@ -49,7 +49,7 @@ struct TaskManagerInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// a `TaskManager` instance through lazy_static!
|
/// a `TaskManager` global instance through lazy_static!
|
||||||
pub static ref TASK_MANAGER: TaskManager = {
|
pub static ref TASK_MANAGER: TaskManager = {
|
||||||
println!("init TASK_MANAGER");
|
println!("init TASK_MANAGER");
|
||||||
let num_app = get_num_app();
|
let num_app = get_num_app();
|
||||||
|
|
|
@ -5,18 +5,26 @@ use riscv::register::sstatus::{self, Sstatus, SPP};
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
/// trap context structure containing sstatus, sepc and registers
|
/// trap context structure containing sstatus, sepc and registers
|
||||||
pub struct TrapContext {
|
pub struct TrapContext {
|
||||||
|
/// general regs[0..31]
|
||||||
pub x: [usize; 32],
|
pub x: [usize; 32],
|
||||||
|
/// CSR sstatus
|
||||||
pub sstatus: Sstatus,
|
pub sstatus: Sstatus,
|
||||||
|
/// CSR sepc
|
||||||
pub sepc: usize,
|
pub sepc: usize,
|
||||||
|
/// Addr of Page Table
|
||||||
pub kernel_satp: usize,
|
pub kernel_satp: usize,
|
||||||
|
/// kernel stack
|
||||||
pub kernel_sp: usize,
|
pub kernel_sp: usize,
|
||||||
|
/// Addr of trap_handler function
|
||||||
pub trap_handler: usize,
|
pub trap_handler: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TrapContext {
|
impl TrapContext {
|
||||||
|
/// set stack pointer to x_2 reg (sp)
|
||||||
pub fn set_sp(&mut self, sp: usize) {
|
pub fn set_sp(&mut self, sp: usize) {
|
||||||
self.x[2] = sp;
|
self.x[2] = sp;
|
||||||
}
|
}
|
||||||
|
/// init app context
|
||||||
pub fn app_init_context(
|
pub fn app_init_context(
|
||||||
entry: usize,
|
entry: usize,
|
||||||
sp: usize,
|
sp: usize,
|
||||||
|
@ -24,17 +32,17 @@ impl TrapContext {
|
||||||
kernel_sp: usize,
|
kernel_sp: usize,
|
||||||
trap_handler: usize,
|
trap_handler: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut sstatus = sstatus::read();
|
let mut sstatus = sstatus::read(); // CSR sstatus
|
||||||
sstatus.set_spp(SPP::User);
|
sstatus.set_spp(SPP::User); //previous privilege mode: user mode
|
||||||
let mut cx = Self {
|
let mut cx = Self {
|
||||||
x: [0; 32],
|
x: [0; 32],
|
||||||
sstatus,
|
sstatus,
|
||||||
sepc: entry,
|
sepc: entry, // entry point of app
|
||||||
kernel_satp,
|
kernel_satp, // addr of page table
|
||||||
kernel_sp,
|
kernel_sp, // kernel stack
|
||||||
trap_handler,
|
trap_handler,// addr of trap_handler function
|
||||||
};
|
};
|
||||||
cx.set_sp(sp);
|
cx.set_sp(sp); // app's user stack pointer
|
||||||
cx
|
cx // return initial Trap Context of app
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ use riscv::register::{
|
||||||
|
|
||||||
global_asm!(include_str!("trap.S"));
|
global_asm!(include_str!("trap.S"));
|
||||||
|
|
||||||
|
/// initialize CSR `stvec` as the entry of `__alltraps`
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
set_kernel_trap_entry();
|
set_kernel_trap_entry();
|
||||||
}
|
}
|
||||||
|
@ -44,6 +45,7 @@ fn set_user_trap_entry() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// enable timer interrupt in sie CSR
|
||||||
pub fn enable_timer_interrupt() {
|
pub fn enable_timer_interrupt() {
|
||||||
unsafe {
|
unsafe {
|
||||||
sie::set_stimer();
|
sie::set_stimer();
|
||||||
|
@ -51,6 +53,7 @@ pub fn enable_timer_interrupt() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
/// handle an interrupt, exception, or system call from user space
|
||||||
pub fn trap_handler() -> ! {
|
pub fn trap_handler() -> ! {
|
||||||
set_kernel_trap_entry();
|
set_kernel_trap_entry();
|
||||||
let cx = current_trap_cx();
|
let cx = current_trap_cx();
|
||||||
|
@ -86,6 +89,9 @@ pub fn trap_handler() -> ! {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
/// set the new addr of __restore asm function in TRAMPOLINE page,
|
||||||
|
/// set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table,
|
||||||
|
/// finally, jump to new addr of __restore asm function
|
||||||
pub fn trap_return() -> ! {
|
pub fn trap_return() -> ! {
|
||||||
set_user_trap_entry();
|
set_user_trap_entry();
|
||||||
let trap_cx_ptr = TRAP_CONTEXT;
|
let trap_cx_ptr = TRAP_CONTEXT;
|
||||||
|
@ -98,16 +104,18 @@ pub fn trap_return() -> ! {
|
||||||
unsafe {
|
unsafe {
|
||||||
asm!(
|
asm!(
|
||||||
"fence.i",
|
"fence.i",
|
||||||
"jr {restore_va}",
|
"jr {restore_va}", // jump to new addr of __restore asm function
|
||||||
restore_va = in(reg) restore_va,
|
restore_va = in(reg) restore_va,
|
||||||
in("a0") trap_cx_ptr,
|
in("a0") trap_cx_ptr, // a0 = virt addr of Trap Context
|
||||||
in("a1") user_satp,
|
in("a1") user_satp, // a1 = phy addr of usr page table
|
||||||
options(noreturn)
|
options(noreturn)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
/// Unimplement: traps/interrupts/exceptions from kernel mode
|
||||||
|
/// Todo: Chapter 9: I/O device
|
||||||
pub fn trap_from_kernel() -> ! {
|
pub fn trap_from_kernel() -> ! {
|
||||||
panic!("a trap from kernel!");
|
panic!("a trap from kernel!");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue