Simple kernel shell

master
WangRunji 6 years ago
parent 542a06d50e
commit cf1a2d3450

@ -6,14 +6,24 @@ struct SerialPort;
impl Write for SerialPort {
fn write_str(&mut self, s: &str) -> Result {
for c in s.bytes() {
if c == 8 {
sbi::console_putchar(8);
sbi::console_putchar(' ' as usize);
sbi::console_putchar(8);
} else {
sbi::console_putchar(c as usize);
}
}
Ok(())
}
}
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) {

@ -131,13 +131,12 @@ fn keyboard() {
fn com1() {
use arch::driver::serial::*;
info!("\nInterupt: COM1");
COM1.lock().receive();
trace!("\nInterupt: COM1");
}
fn com2() {
use arch::driver::serial::*;
info!("\nInterupt: COM2");
trace!("\nInterupt: COM2");
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 process;
pub fn load_sfs() {
pub fn shell() {
#[cfg(target_arch = "riscv")]
let device = {
extern {
@ -19,17 +19,23 @@ pub fn load_sfs() {
let sfs = SimpleFileSystem::open(device).unwrap();
let root = sfs.root_inode();
let files = root.borrow().list().unwrap();
trace!("Loading programs: {:?}", files);
println!("Available programs: {:?}", files);
// for name in files.iter().filter(|&f| f != "." && f != "..") {
for name in files.iter().filter(|&f| f == "hello") {
static mut BUF: [u8; 64 << 12] = [0; 64 << 12];
let file = root.borrow().lookup(name.as_str()).unwrap();
let len = file.borrow().read_at(0, unsafe { &mut BUF }).unwrap();
process::add_user_process(name, unsafe { &BUF[..len] });
let mut buf = Box::new([0; 64 << 12]);
loop {
use console::get_line;
let name = get_line();
if name == "" {
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]);

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

Loading…
Cancel
Save