add #![deny(missing_docs)] AND #![deny(warnings)] in main.rs, and add more comments

ch4
Yu Chen 3 years ago
parent f1eae45419
commit fd0efaa03d

1
.gitignore vendored

@ -15,3 +15,4 @@ easy-fs-fuse/Cargo.lock
easy-fs-fuse/target/*
tools/
pushall.sh
*.bak

@ -15,6 +15,8 @@
//! We then call [`task::run_first_task()`] and for the first time go to
//! userspace.
#![deny(missing_docs)]
#![deny(warnings)]
#![no_std]
#![no_main]
#![feature(panic_info_message)]

@ -24,7 +24,7 @@ impl<T> UPSafeCell<T> {
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> {
self.inner.borrow_mut()
}

@ -5,6 +5,7 @@ use crate::task::current_user_token;
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 {
match fd {
FD_STDOUT => {

@ -3,17 +3,20 @@
use crate::task::{exit_current_and_run_next, suspend_current_and_run_next};
use crate::timer::get_time_ms;
/// task exits and submit an exit code
pub fn sys_exit(exit_code: i32) -> ! {
println!("[kernel] Application exited with code {}", exit_code);
exit_current_and_run_next();
panic!("Unreachable in sys_exit!");
}
/// current task gives up resources for other tasks
pub fn sys_yield() -> isize {
suspend_current_and_run_next();
0
}
/// get current time
pub fn sys_get_time() -> isize {
get_time_ms() as isize
}

@ -4,12 +4,16 @@ use crate::trap::trap_return;
#[repr(C)]
/// task context structure containing some registers
pub struct TaskContext {
/// return address ( e.g. __restore ) of __switch ASM function
ra: usize,
/// kernel stack pointer of app
sp: usize,
/// callee saved registers: s 0..11
s: [usize; 12],
}
impl TaskContext {
/// init task context
pub fn zero_init() -> Self {
Self {
ra: 0,
@ -17,6 +21,7 @@ impl TaskContext {
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 {
Self {
ra: trap_return as usize,

@ -6,7 +6,7 @@
//! A single global instance of [`TaskManager`] called `TASK_MANAGER` controls
//! 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.
mod context;
@ -49,7 +49,7 @@ struct TaskManagerInner {
}
lazy_static! {
/// a `TaskManager` instance through lazy_static!
/// a `TaskManager` global instance through lazy_static!
pub static ref TASK_MANAGER: TaskManager = {
println!("init TASK_MANAGER");
let num_app = get_num_app();

@ -5,18 +5,26 @@ use riscv::register::sstatus::{self, Sstatus, SPP};
#[repr(C)]
/// trap context structure containing sstatus, sepc and registers
pub struct TrapContext {
/// general regs[0..31]
pub x: [usize; 32],
/// CSR sstatus
pub sstatus: Sstatus,
/// CSR sepc
pub sepc: usize,
/// Addr of Page Table
pub kernel_satp: usize,
/// kernel stack
pub kernel_sp: usize,
/// Addr of trap_handler function
pub trap_handler: usize,
}
impl TrapContext {
/// set stack pointer to x_2 reg (sp)
pub fn set_sp(&mut self, sp: usize) {
self.x[2] = sp;
}
/// init app context
pub fn app_init_context(
entry: usize,
sp: usize,
@ -24,17 +32,17 @@ impl TrapContext {
kernel_sp: usize,
trap_handler: usize,
) -> Self {
let mut sstatus = sstatus::read();
sstatus.set_spp(SPP::User);
let mut sstatus = sstatus::read(); // CSR sstatus
sstatus.set_spp(SPP::User); //previous privilege mode: user mode
let mut cx = Self {
x: [0; 32],
sstatus,
sepc: entry,
kernel_satp,
kernel_sp,
trap_handler,
sepc: entry, // entry point of app
kernel_satp, // addr of page table
kernel_sp, // kernel stack
trap_handler,// addr of trap_handler function
};
cx.set_sp(sp);
cx
cx.set_sp(sp); // app's user stack pointer
cx // return initial Trap Context of app
}
}

@ -28,6 +28,7 @@ use riscv::register::{
global_asm!(include_str!("trap.S"));
/// initialize CSR `stvec` as the entry of `__alltraps`
pub fn init() {
set_kernel_trap_entry();
}
@ -44,6 +45,7 @@ fn set_user_trap_entry() {
}
}
/// enable timer interrupt in sie CSR
pub fn enable_timer_interrupt() {
unsafe {
sie::set_stimer();
@ -51,6 +53,7 @@ pub fn enable_timer_interrupt() {
}
#[no_mangle]
/// handle an interrupt, exception, or system call from user space
pub fn trap_handler() -> ! {
set_kernel_trap_entry();
let cx = current_trap_cx();
@ -86,6 +89,9 @@ pub fn trap_handler() -> ! {
}
#[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() -> ! {
set_user_trap_entry();
let trap_cx_ptr = TRAP_CONTEXT;
@ -98,16 +104,18 @@ pub fn trap_return() -> ! {
unsafe {
asm!(
"fence.i",
"jr {restore_va}",
"jr {restore_va}", // jump to new addr of __restore asm function
restore_va = in(reg) restore_va,
in("a0") trap_cx_ptr,
in("a1") user_satp,
in("a0") trap_cx_ptr, // a0 = virt addr of Trap Context
in("a1") user_satp, // a1 = phy addr of usr page table
options(noreturn)
);
}
}
#[no_mangle]
/// Unimplement: traps/interrupts/exceptions from kernel mode
/// Todo: Chapter 9: I/O device
pub fn trap_from_kernel() -> ! {
panic!("a trap from kernel!");
}

Loading…
Cancel
Save