From 2d732a48d8a3c87bd5ce3a0382d4129eda44c879 Mon Sep 17 00:00:00 2001 From: gjz010 Date: Tue, 11 May 2021 02:09:52 +0800 Subject: [PATCH] Serial device file for user using 2nd UART. --- kernel/src/fs/devfs/mod.rs | 2 + kernel/src/fs/devfs/serial.rs | 78 +++++++++++++++++++++++++++++++++++ kernel/src/fs/mod.rs | 6 ++- 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 kernel/src/fs/devfs/serial.rs diff --git a/kernel/src/fs/devfs/mod.rs b/kernel/src/fs/devfs/mod.rs index 0e590734..4d7dfdcc 100644 --- a/kernel/src/fs/devfs/mod.rs +++ b/kernel/src/fs/devfs/mod.rs @@ -2,10 +2,12 @@ mod fbdev; mod random; +mod serial; mod shm; mod tty; pub use fbdev::*; pub use random::*; +pub use serial::*; pub use shm::*; pub use tty::*; diff --git a/kernel/src/fs/devfs/serial.rs b/kernel/src/fs/devfs/serial.rs new file mode 100644 index 00000000..39b9e8e9 --- /dev/null +++ b/kernel/src/fs/devfs/serial.rs @@ -0,0 +1,78 @@ +use crate::drivers::serial::SERIAL_ACTIVITY; +use crate::drivers::SerialDriver; +use crate::drivers::SERIAL_DRIVERS; +use crate::syscall::spin_and_wait; +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::any::Any; +use rcore_fs::vfs::*; +pub struct Serial { + id: usize, + driver: Arc, +} + +impl Serial { + pub fn new(id: usize, driver: Arc) -> Self { + Serial { id, driver } + } + pub fn wrap_all_serial_devices() -> Vec { + let drivers = SERIAL_DRIVERS.read(); + drivers + .iter() + .cloned() + .enumerate() + .map(|(i, x)| Serial::new(i, x)) + .collect() + } +} + +impl INode for Serial { + fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result { + let mut n = 0; + for r in buf.iter_mut() { + if let Some(x) = self.driver.try_read() { + *r = x; + n += 1; + } else { + break; + } + } + Ok(n) + } + + fn write_at(&self, _offset: usize, buf: &[u8]) -> Result { + self.driver.write(buf); + Ok(buf.len()) + } + + fn poll(&self) -> Result { + Ok(PollStatus { + read: true, + write: true, + error: false, + }) + } + + fn metadata(&self) -> Result { + Ok(Metadata { + dev: 1, + inode: 1, + size: 0, + blk_size: 0, + blocks: 0, + atime: Timespec { sec: 0, nsec: 0 }, + mtime: Timespec { sec: 0, nsec: 0 }, + ctime: Timespec { sec: 0, nsec: 0 }, + type_: FileType::CharDevice, + mode: 0o666, + nlinks: 1, + uid: 0, + gid: 0, + rdev: make_rdev(4, self.id), + }) + } + + fn as_any_ref(&self) -> &dyn Any { + self + } +} diff --git a/kernel/src/fs/mod.rs b/kernel/src/fs/mod.rs index ef9af81f..eddebd61 100644 --- a/kernel/src/fs/mod.rs +++ b/kernel/src/fs/mod.rs @@ -11,7 +11,7 @@ use rcore_fs_sfs::{INodeImpl, SimpleFileSystem}; use self::devfs::{Fbdev, RandomINode}; -pub use self::devfs::{ShmINode, TTY}; +pub use self::devfs::{Serial, ShmINode, TTY}; pub use self::file::*; pub use self::file_like::*; pub use self::pipe::Pipe; @@ -82,6 +82,10 @@ lazy_static! { devfs.add("tty", TTY.clone()).expect("failed to mknod /dev/tty"); devfs.add("fb0", Arc::new(Fbdev::default())).expect("failed to mknod /dev/fb0"); devfs.add("shm", Arc::new(ShmINode::default())).expect("failed to mkdir shm"); + for (i, serial) in Serial::wrap_all_serial_devices().into_iter().enumerate(){ + devfs.add(&format!("ttyS{}", i), Arc::new(serial)).expect("failed to add a serial"); + } + #[cfg(feature = "hypervisor")] devfs.add("rvm", Arc::new(crate::rvm::RvmINode::new())).expect("failed to mknod /dev/rvm");