Simple kernel shell

toolchain_update
WangRunji 7 years ago
parent 542a06d50e
commit cf1a2d3450

@ -6,14 +6,24 @@ struct SerialPort;
impl Write for SerialPort { impl Write for SerialPort {
fn write_str(&mut self, s: &str) -> Result { fn write_str(&mut self, s: &str) -> Result {
for c in s.bytes() { for c in s.bytes() {
sbi::console_putchar(c as usize); if c == 8 {
sbi::console_putchar(8);
sbi::console_putchar(' ' as usize);
sbi::console_putchar(8);
} else {
sbi::console_putchar(c as usize);
}
} }
Ok(()) Ok(())
} }
} }
pub fn getchar() -> char { pub fn getchar() -> char {
sbi::console_getchar() as u8 as char match sbi::console_getchar() as u8 {
255 => 0, // null
127 => 8, // back
c => c,
} as char
} }
pub fn putfmt(fmt: Arguments) { pub fn putfmt(fmt: Arguments) {

@ -131,13 +131,12 @@ fn keyboard() {
fn com1() { fn com1() {
use arch::driver::serial::*; use arch::driver::serial::*;
info!("\nInterupt: COM1"); trace!("\nInterupt: COM1");
COM1.lock().receive();
} }
fn com2() { fn com2() {
use arch::driver::serial::*; use arch::driver::serial::*;
info!("\nInterupt: COM2"); trace!("\nInterupt: COM2");
COM2.lock().receive(); COM2.lock().receive();
} }

@ -0,0 +1,64 @@
use core::ops::Deref;
pub struct LineBuf {
buf: [u8; BUF_SIZE],
len: usize,
}
pub struct LineBufGuard<'a>(&'a str);
const BUF_SIZE: usize = 256;
impl LineBuf {
pub const fn new() -> Self {
LineBuf {
buf: [0; BUF_SIZE],
len: 0,
}
}
/// Put a char received from serial. Return str if get a line.
pub fn push_u8<'a>(&'a mut self, c: u8) -> Option<LineBufGuard<'a>> {
use alloc::str;
match c {
b' '...128 if self.len != BUF_SIZE => {
self.buf[self.len] = c;
self.len += 1;
}
8 /* '\b' */ if self.len != 0 => {
self.len -= 1;
}
b'\n' | b'\r' => {
let s = str::from_utf8(&self.buf[..self.len]).unwrap();
self.len = 0;
return Some(LineBufGuard(s));
}
_ => {}
}
None
}
}
impl<'a> Deref for LineBufGuard<'a> {
type Target = str;
fn deref(&self) -> &str {
self.0
}
}
use alloc::string::String;
use arch::io::getchar;
pub fn get_line() -> String {
let mut buf = LineBuf::new();
loop {
let mut c = 0;
while c == 0 {
c = getchar() as u8;
}
print!("{}", c as char);
if let Some(line) = buf.push_u8(c) {
return String::from(&*line);
}
}
}

@ -5,7 +5,7 @@ use arch::driver::ide;
use spin::Mutex; use spin::Mutex;
use process; use process;
pub fn load_sfs() { pub fn shell() {
#[cfg(target_arch = "riscv")] #[cfg(target_arch = "riscv")]
let device = { let device = {
extern { extern {
@ -19,17 +19,23 @@ pub fn load_sfs() {
let sfs = SimpleFileSystem::open(device).unwrap(); let sfs = SimpleFileSystem::open(device).unwrap();
let root = sfs.root_inode(); let root = sfs.root_inode();
let files = root.borrow().list().unwrap(); let files = root.borrow().list().unwrap();
trace!("Loading programs: {:?}", files); println!("Available programs: {:?}", files);
// for name in files.iter().filter(|&f| f != "." && f != "..") { let mut buf = Box::new([0; 64 << 12]);
for name in files.iter().filter(|&f| f == "hello") { loop {
static mut BUF: [u8; 64 << 12] = [0; 64 << 12]; use console::get_line;
let file = root.borrow().lookup(name.as_str()).unwrap(); let name = get_line();
let len = file.borrow().read_at(0, unsafe { &mut BUF }).unwrap(); if name == "" {
process::add_user_process(name, unsafe { &BUF[..len] }); continue;
}
if let Ok(file) = root.borrow().lookup(name.as_str()) {
println!("Running: {}", name);
let len = file.borrow().read_at(0, &mut *buf).unwrap();
process::add_user_process(name, &buf[..len]);
} else {
println!("Program not exist");
}
} }
process::print();
} }
struct MemBuf(&'static [u8]); struct MemBuf(&'static [u8]);

@ -66,6 +66,7 @@ mod fs;
mod thread; mod thread;
mod sync; mod sync;
mod trap; mod trap;
mod console;
#[allow(dead_code)] #[allow(dead_code)]
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
@ -85,9 +86,10 @@ pub extern "C" fn rust_main() -> ! {
logging::init(); logging::init();
arch::init(); arch::init();
process::init(); process::init();
fs::load_sfs();
unsafe { arch::interrupt::enable(); } unsafe { arch::interrupt::enable(); }
fs::shell();
// thread::test::local_key(); // thread::test::local_key();
// thread::test::unpack(); // thread::test::unpack();
// sync::test::philosopher_using_mutex(); // sync::test::philosopher_using_mutex();

Loading…
Cancel
Save