mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
Simple kernel shell
This commit is contained in:
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() {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
64
kernel/src/console.rs
Normal file
64
kernel/src/console.rs
Normal file
@ -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…
Reference in New Issue
Block a user