本章代码对应 commit :ca94d49d69c18ce2925e3949d718cd74ddc3432c
// in usr/rust/src/bin/hello.rs
#![no_std]
#![no_main]
#[macro_use]
extern crate rust;
#[no_mangle]
pub fn main() -> i32 {
println!("Hello world!");
return 0;
}
// in usr/rust/src/bin/shell.rs
#![no_std]
#![no_main]
#![feature(alloc)]
extern crate alloc;
#[macro_use]
extern crate rust;
use rust::io::getc;
use rust::syscall::sys_exec;
use alloc::string::String;
const LF: u8 = 0x0au8;
const CR: u8 = 0x0du8;
// IMPORTANT: Must define main() like this
#[no_mangle]
pub fn main() -> i32 {
println!("Rust user shell");
let mut line: String = String::new();
print!(">> ");
loop {
let c = getc();
match c {
LF | CR => {
println!("");
if !line.is_empty() {
sys_exec(line.as_ptr());
line.clear();
}
print!(">> ");
}
_ => {
print!("{}", c as char);
line.push(c as char)
}
}
}
}
// in usr/rust/bin/shell.rs
pub fn sys_exec(path : *const u8) {
sys_call(SyscallId::Exec, path as usize, 0, 0, 0);
}
enum SyscallId {
...
Exec = 221,
}
...
pub const SYS_EXEC: usize = 221;
pub fn syscall(id: usize, args: [usize;3], tf: &mut TrapFrame) -> isize {
match id {
...
SYS_EXEC => {
sys_exec(args[0] as *const u8);
},
_ => {
panic!("unknown syscall id {}", id);
},
};
return 0;
}
pub unsafe fn from_cstr(s: *const u8) -> &'static str {
use core::{slice, str};
let len = (0usize..).find(|&i| *s.add(i) == 0).unwrap();
str::from_utf8(slice::from_raw_parts(s, len)).unwrap()
}
fn sys_exec(path : *const u8) -> isize {
process::excute(unsafe{ from_cstr(path) });
return 0;
}
// in process/mod.rs
pub fn excute(name : &str) {
println!("excutint program: {}", name);
let data = ROOT_INODE
.lookup(name)
.unwrap()
.read_as_vec()
.unwrap();
let thread = unsafe{ Thread::new_user(data.as_slice()) };
CPU.add_thread(thread);
}
pub fn init() {
println!("+------ now to initialize process ------+");
let scheduler = Scheduler::new(1);
let thread_pool = ThreadPool::new(100, scheduler);
println!("+------ now to initialize processor ------+");
CPU.init(Thread::new_idle(), Box::new(thread_pool));
excute("rust/shell");
}