实现pty,附带测试程序 (#685)

* 实现pty,附带测试程序

* fmt ** clippy

* 将file层的锁粒度缩小,从而不使用no_preempt。更改pipe在sleep部分的bug

* 修复拼写错误
This commit is contained in:
GnoCiYeH
2024-04-05 00:21:55 +08:00
committed by GitHub
parent b8ed38251d
commit dfe53cf087
49 changed files with 1691 additions and 384 deletions

View File

@ -18,6 +18,12 @@ impl Major {
/// /dev/fb* framebuffers
pub const FB_MAJOR: Self = Self::new(29);
/// Pty
pub const UNIX98_PTY_MASTER_MAJOR: Self = Self::new(128);
pub const UNIX98_PTY_MAJOR_COUNT: Self = Self::new(8);
pub const UNIX98_PTY_SLAVE_MAJOR: Self =
Self::new(Self::UNIX98_PTY_MASTER_MAJOR.0 + Self::UNIX98_PTY_MAJOR_COUNT.0);
pub const fn new(x: u32) -> Self {
Major(x)
}

View File

@ -6,6 +6,7 @@ use crate::filesystem::vfs::syscall::ModeType;
use crate::filesystem::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
};
use crate::libs::spinlock::SpinLockGuard;
use crate::{libs::spinlock::SpinLock, time::TimeSpec};
use alloc::{
string::String,
@ -76,11 +77,15 @@ impl IndexNode for LockedAhciInode {
self
}
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
}
@ -114,13 +119,13 @@ impl IndexNode for LockedAhciInode {
offset: usize, // lba地址
len: usize,
buf: &mut [u8],
data: &mut FilePrivateData,
data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
if buf.len() < len {
return Err(SystemError::EINVAL);
}
if let FilePrivateData::Unused = data {
if let FilePrivateData::Unused = *data {
return self.0.lock().disk.read_at_bytes(offset, len, buf);
}
@ -133,13 +138,13 @@ impl IndexNode for LockedAhciInode {
offset: usize, // lba地址
len: usize,
buf: &[u8],
data: &mut FilePrivateData,
data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
if buf.len() < len {
return Err(SystemError::EINVAL);
}
if let FilePrivateData::Unused = data {
if let FilePrivateData::Unused = *data {
return self.0.lock().disk.write_at_bytes(offset, len, buf);
}

View File

@ -36,7 +36,7 @@ use crate::{
},
libs::{
rwlock::{RwLockReadGuard, RwLockWriteGuard},
spinlock::SpinLock,
spinlock::{SpinLock, SpinLockGuard},
},
time::TimeSpec,
};
@ -587,7 +587,7 @@ impl DeviceINode for Ps2MouseDevice {
impl IndexNode for Ps2MouseDevice {
fn open(
&self,
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
_mode: &crate::filesystem::vfs::file::FileMode,
) -> Result<(), SystemError> {
let mut guard = self.inner.lock_irqsave();
@ -595,7 +595,7 @@ impl IndexNode for Ps2MouseDevice {
Ok(())
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
let mut guard = self.inner.lock_irqsave();
guard.buf.clear();
Ok(())
@ -606,7 +606,7 @@ impl IndexNode for Ps2MouseDevice {
_offset: usize,
_len: usize,
buf: &mut [u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
let mut guard = self.inner.lock_irqsave();
@ -625,7 +625,7 @@ impl IndexNode for Ps2MouseDevice {
_offset: usize,
_len: usize,
_buf: &[u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}

View File

@ -27,7 +27,11 @@ use crate::{
},
},
init::initcall::INITCALL_DEVICE,
libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock},
libs::{
keyboard_parser::TypeOneFSM,
rwlock::RwLock,
spinlock::{SpinLock, SpinLockGuard},
},
time::TimeSpec,
};
use system_error::SystemError;
@ -115,7 +119,7 @@ impl IndexNode for LockedPS2KeyBoardInode {
_offset: usize,
_len: usize,
_buf: &mut [u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
return Err(SystemError::ENOSYS);
}
@ -125,16 +129,20 @@ impl IndexNode for LockedPS2KeyBoardInode {
_offset: usize,
_len: usize,
_buf: &[u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
return Err(SystemError::ENOSYS);
}
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
return Ok(());
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
return Ok(());
}

View File

@ -5,6 +5,7 @@ use kdepends::thingbuf::StaticThingBuf;
use crate::{
arch::sched::sched,
driver::tty::virtual_terminal::virtual_console::CURRENT_VCNUM,
process::{
kthread::{KernelThreadClosure, KernelThreadMechanism},
ProcessControlBlock, ProcessFlags,
@ -54,7 +55,12 @@ fn tty_refresh_thread() -> i32 {
*item = KEYBUF.pop().unwrap();
}
let _ = current_tty_port().receive_buf(&data[0..to_dequeue], &[], to_dequeue);
if CURRENT_VCNUM.load(core::sync::atomic::Ordering::SeqCst) != -1 {
let _ = current_tty_port().receive_buf(&data[0..to_dequeue], &[], to_dequeue);
} else {
// 这里由于stdio未初始化所以无法找到port
// TODO: 考虑改用双端队列,能够将丢失的输入插回
}
}
}

View File

@ -2,6 +2,7 @@ use alloc::vec::Vec;
pub mod console;
pub mod kthread;
pub mod pty;
mod sysfs;
pub mod termios;
pub mod tty_core;

View File

@ -0,0 +1,288 @@
use alloc::{
string::{String, ToString},
sync::Arc,
};
use system_error::SystemError;
use unified_init::macros::unified_init;
use crate::{
driver::base::device::{
device_number::{DeviceNumber, Major},
device_register, IdTable,
},
filesystem::devfs::devfs_register,
init::initcall::INITCALL_DEVICE,
libs::lazy_init::Lazy,
mm::VirtAddr,
syscall::user_access::{UserBufferReader, UserBufferWriter},
};
use self::unix98pty::{Unix98PtyDriverInner, NR_UNIX98_PTY_MAX};
use super::{
termios::{ControlMode, InputMode, LocalMode, OutputMode, TTY_STD_TERMIOS},
tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyPacketStatus},
tty_device::{TtyDevice, TtyType},
tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TTY_DRIVERS},
tty_port::{DefaultTtyPort, TtyPort},
};
pub mod unix98pty;
static PTM_DRIVER: Lazy<Arc<TtyDriver>> = Lazy::new();
static PTS_DRIVER: Lazy<Arc<TtyDriver>> = Lazy::new();
pub(super) fn ptm_driver() -> Arc<TtyDriver> {
PTM_DRIVER.ensure();
PTM_DRIVER.get().clone()
}
pub(super) fn pts_driver() -> Arc<TtyDriver> {
PTS_DRIVER.ensure();
PTS_DRIVER.get().clone()
}
// lazy_static! {
// pub static ref PTM_DRIVER: Arc<TtyDriver> = {
// let mut ptm_driver = TtyDriver::new(
// NR_UNIX98_PTY_MAX,
// "ptm",
// 0,
// Major::UNIX98_PTY_MASTER_MAJOR,
// 0,
// TtyDriverType::Pty,
// *TTY_STD_TERMIOS,
// Arc::new(Unix98PtyDriverInner::new()),
// );
// ptm_driver.set_subtype(TtyDriverSubType::PtyMaster);
// let term = ptm_driver.init_termios_mut();
// term.input_mode = InputMode::empty();
// term.output_mode = OutputMode::empty();
// term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
// term.local_mode = LocalMode::empty();
// term.input_speed = 38400;
// term.output_speed = 38400;
// TtyDriverManager::tty_register_driver(ptm_driver).unwrap()
// };
// pub static ref PTS_DRIVER: Arc<TtyDriver> = {
// let mut pts_driver = TtyDriver::new(
// NR_UNIX98_PTY_MAX,
// "pts",
// 0,
// Major::UNIX98_PTY_SLAVE_MAJOR,
// 0,
// TtyDriverType::Pty,
// *TTY_STD_TERMIOS,
// Arc::new(Unix98PtyDriverInner::new()),
// );
// pts_driver.set_subtype(TtyDriverSubType::PtySlave);
// let term = pts_driver.init_termios_mut();
// term.input_mode = InputMode::empty();
// term.output_mode = OutputMode::empty();
// term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
// term.local_mode = LocalMode::empty();
// term.input_speed = 38400;
// term.output_speed = 38400;
// TtyDriverManager::tty_register_driver(pts_driver).unwrap()
// };
// }
pub struct PtyCommon;
impl PtyCommon {
pub fn pty_common_install(
driver: Arc<TtyDriver>,
tty: Arc<TtyCore>,
legacy: bool,
) -> Result<(), SystemError> {
let core = tty.core();
let other_driver = driver.other_pty_driver().unwrap();
let other_tty = TtyCore::new(other_driver.clone(), core.index());
other_driver.add_tty(other_tty.clone());
let port0: Arc<dyn TtyPort> = Arc::new(DefaultTtyPort::new());
let port1: Arc<dyn TtyPort> = Arc::new(DefaultTtyPort::new());
let o_core = other_tty.core();
if legacy {
core.init_termios();
o_core.init_termios();
driver
.other_pty_driver()
.unwrap()
.ttys()
.insert(core.index(), other_tty.clone());
driver.ttys().insert(core.index(), tty.clone());
} else {
*core.termios_write() = driver.init_termios();
*o_core.termios_write() = driver.other_pty_driver().unwrap().init_termios();
}
core.set_link(Arc::downgrade(&other_tty));
o_core.set_link(Arc::downgrade(&tty));
port0.setup_internal_tty(Arc::downgrade(&other_tty));
port1.setup_internal_tty(Arc::downgrade(&tty));
other_tty.set_port(port0);
tty.set_port(port1);
core.add_count();
o_core.add_count();
// 将pts加入pts Driver管理队列
PTS_DRIVER.ttys().insert(core.index(), other_tty);
Ok(())
}
pub fn pty_common_open(core: &TtyCoreData) -> Result<(), SystemError> {
if let Some(link) = core.link() {
let link_core = link.core();
if core.flags().contains(TtyFlag::OTHER_CLOSED) {
core.flags_write().insert(TtyFlag::IO_ERROR);
return Err(SystemError::EIO);
}
if link_core.flags().contains(TtyFlag::PTY_LOCK) {
core.flags_write().insert(TtyFlag::IO_ERROR);
return Err(SystemError::EIO);
}
if core.driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave
&& link_core.count() != 1
{
// 只能有一个master如果当前为slave则link的count必须为1
core.flags_write().insert(TtyFlag::IO_ERROR);
return Err(SystemError::EIO);
}
core.flags_write().remove(TtyFlag::IO_ERROR);
link_core.flags_write().remove(TtyFlag::OTHER_CLOSED);
core.flags_write().insert(TtyFlag::THROTTLED);
return Ok(());
}
return Err(SystemError::ENODEV);
}
pub fn pty_set_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
let user_reader =
UserBufferReader::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
if *user_reader.read_one_from_user::<i32>(0)? != 0 {
tty.flags_write().insert(TtyFlag::PTY_LOCK);
} else {
tty.flags_write().remove(TtyFlag::PTY_LOCK);
}
Ok(())
}
pub fn pty_get_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
let mut user_writer =
UserBufferWriter::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
user_writer.copy_one_to_user(&tty.flags().contains(TtyFlag::PTY_LOCK), 0)?;
Ok(())
}
pub fn pty_set_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
let user_reader =
UserBufferReader::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
let mut ctrl = tty.contorl_info_irqsave();
if *user_reader.read_one_from_user::<i32>(0)? != 0 {
if !ctrl.packet {
tty.link().unwrap().core().contorl_info_irqsave().pktstatus =
TtyPacketStatus::empty();
ctrl.packet = true;
}
} else {
ctrl.packet = false;
}
Ok(())
}
pub fn pty_get_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
let mut user_writer =
UserBufferWriter::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
user_writer.copy_one_to_user(&tty.contorl_info_irqsave().packet, 0)?;
Ok(())
}
pub fn unix98pty_init() -> Result<(), SystemError> {
let ptm_driver = ptm_driver();
let pts_driver = pts_driver();
ptm_driver.set_other_pty_driver(Arc::downgrade(&pts_driver));
pts_driver.set_other_pty_driver(Arc::downgrade(&ptm_driver));
let idt = IdTable::new(
String::from("ptmx"),
Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 2)),
);
let ptmx_dev = TtyDevice::new(
"ptmx".to_string(),
idt.clone(),
TtyType::Pty(super::tty_device::PtyType::Ptm),
);
ptmx_dev.inner_write().metadata_mut().raw_dev = idt.device_number();
device_register(ptmx_dev.clone())?;
devfs_register("ptmx", ptmx_dev)?;
TTY_DRIVERS.lock().push(ptm_driver);
TTY_DRIVERS.lock().push(pts_driver);
Ok(())
}
}
#[unified_init(INITCALL_DEVICE)]
#[inline(never)]
pub fn pty_init() -> Result<(), SystemError> {
let mut ptm_driver = TtyDriver::new(
NR_UNIX98_PTY_MAX,
"ptm",
0,
Major::UNIX98_PTY_MASTER_MAJOR,
0,
TtyDriverType::Pty,
*TTY_STD_TERMIOS,
Arc::new(Unix98PtyDriverInner::new()),
);
ptm_driver.set_subtype(TtyDriverSubType::PtyMaster);
let term = ptm_driver.init_termios_mut();
term.input_mode = InputMode::empty();
term.output_mode = OutputMode::empty();
term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
term.local_mode = LocalMode::empty();
term.input_speed = 38400;
term.output_speed = 38400;
PTM_DRIVER.init(TtyDriverManager::tty_register_driver(ptm_driver).unwrap());
let mut pts_driver = TtyDriver::new(
NR_UNIX98_PTY_MAX,
"pts",
0,
Major::UNIX98_PTY_SLAVE_MAJOR,
0,
TtyDriverType::Pty,
*TTY_STD_TERMIOS,
Arc::new(Unix98PtyDriverInner::new()),
);
pts_driver.set_subtype(TtyDriverSubType::PtySlave);
let term = pts_driver.init_termios_mut();
term.input_mode = InputMode::empty();
term.output_mode = OutputMode::empty();
term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
term.local_mode = LocalMode::empty();
term.input_speed = 38400;
term.output_speed = 38400;
PTS_DRIVER.init(TtyDriverManager::tty_register_driver(pts_driver).unwrap());
return PtyCommon::unix98pty_init();
}

View File

@ -0,0 +1,222 @@
use alloc::{string::ToString, sync::Arc};
use system_error::SystemError;
use crate::{
driver::tty::{
termios::Termios,
tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus},
tty_device::TtyFilePrivateData,
tty_driver::{TtyDriver, TtyDriverPrivateData, TtyDriverSubType, TtyOperation},
},
filesystem::{
devpts::DevPtsFs,
vfs::{
file::FileMode, syscall::ModeType, FilePrivateData, FileType, MountFS, ROOT_INODE,
VFS_MAX_FOLLOW_SYMLINK_TIMES,
},
},
libs::spinlock::SpinLockGuard,
mm::VirtAddr,
net::event_poll::EPollEventType,
syscall::user_access::UserBufferWriter,
};
use super::{ptm_driver, pts_driver, PtyCommon};
pub const NR_UNIX98_PTY_MAX: u32 = 128;
#[derive(Debug)]
pub struct Unix98PtyDriverInner;
impl Unix98PtyDriverInner {
pub fn new() -> Self {
Self
}
}
impl TtyOperation for Unix98PtyDriverInner {
fn install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
PtyCommon::pty_common_install(driver, tty, false)
}
fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
PtyCommon::pty_common_open(tty)
}
fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
let to = tty.checked_link()?;
if nr == 0 || tty.flow_irqsave().stopped {
return Ok(0);
}
to.core().port().unwrap().receive_buf(buf, &[], nr)
}
fn write_room(&self, tty: &TtyCoreData) -> usize {
// TODO 暂时
if tty.flow_irqsave().stopped {
return 0;
}
8192
}
fn flush_buffer(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
let to = tty.checked_link()?;
let mut ctrl = to.core().contorl_info_irqsave();
ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_FLUSHWRITE);
to.core().read_wq().wakeup_all();
Ok(())
}
fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> {
let core = tty.core();
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtyMaster {
return Err(SystemError::ENOSYS);
}
match cmd {
TtyIoctlCmd::TIOCSPTLCK => {
return PtyCommon::pty_set_lock(core, VirtAddr::new(arg));
}
TtyIoctlCmd::TIOCGPTLCK => {
return PtyCommon::pty_get_lock(core, VirtAddr::new(arg));
}
TtyIoctlCmd::TIOCPKT => {
return PtyCommon::pty_set_packet_mode(core, VirtAddr::new(arg));
}
TtyIoctlCmd::TIOCGPKT => {
return PtyCommon::pty_get_packet_mode(core, VirtAddr::new(arg));
}
TtyIoctlCmd::TIOCGPTN => {
let mut user_writer =
UserBufferWriter::new(arg as *mut u32, core::mem::size_of::<u32>(), true)?;
return user_writer.copy_one_to_user(&(core.index() as u32), 0);
}
_ => {
return Err(SystemError::ENOIOCTLCMD);
}
}
}
fn set_termios(&self, tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> {
let core = tty.core();
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
return Err(SystemError::ENOSYS);
}
todo!()
}
fn start(&self, core: &TtyCoreData) -> Result<(), SystemError> {
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
return Err(SystemError::ENOSYS);
}
let link = core.checked_link()?;
let mut ctrl = core.contorl_info_irqsave();
ctrl.pktstatus.remove(TtyPacketStatus::TIOCPKT_STOP);
ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_START);
link.core()
.read_wq()
.wakeup_any(EPollEventType::EPOLLIN.bits() as u64);
Ok(())
}
fn stop(&self, core: &TtyCoreData) -> Result<(), SystemError> {
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
return Err(SystemError::ENOSYS);
}
let link = core.checked_link()?;
let mut ctrl = core.contorl_info_irqsave();
ctrl.pktstatus.remove(TtyPacketStatus::TIOCPKT_START);
ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_STOP);
link.core()
.read_wq()
.wakeup_any(EPollEventType::EPOLLIN.bits() as u64);
Ok(())
}
fn flush_chars(&self, _tty: &TtyCoreData) {
// 不做处理
}
fn lookup(
&self,
index: usize,
priv_data: TtyDriverPrivateData,
) -> Result<Arc<TtyCore>, SystemError> {
if let TtyDriverPrivateData::Pty(false) = priv_data {
return pts_driver()
.ttys()
.get(&index)
.cloned()
.ok_or(SystemError::ENODEV);
}
return Err(SystemError::ENOSYS);
}
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
let driver = tty.core().driver();
driver.ttys().remove(&tty.core().index());
if tty.core().driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave {
let pts_root_inode =
ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
let _ = pts_root_inode.unlink(&tty.core().index().to_string());
}
Ok(())
}
}
pub fn ptmx_open(
mut data: SpinLockGuard<FilePrivateData>,
mode: &FileMode,
) -> Result<(), SystemError> {
let pts_root_inode =
ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
let fs = pts_root_inode
.fs()
.as_any_ref()
.downcast_ref::<MountFS>()
.unwrap()
.inner_filesystem();
let fsinfo = fs.as_any_ref().downcast_ref::<DevPtsFs>().unwrap();
let index = fsinfo.alloc_index()?;
let tty = TtyDriver::init_tty_device(ptm_driver(), index)?;
// 设置privdata
*data = FilePrivateData::Tty(TtyFilePrivateData {
tty: tty.clone(),
mode: *mode,
});
let core = tty.core();
core.flags_write().insert(TtyFlag::PTY_LOCK);
let _ = pts_root_inode.create(
&index.to_string(),
FileType::CharDevice,
ModeType::from_bits_truncate(0x666),
)?;
ptm_driver().driver_funcs().open(core)?;
Ok(())
}

View File

@ -1,9 +1,14 @@
use core::{
fmt::Debug,
sync::atomic::{AtomicBool, AtomicUsize},
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
};
use alloc::{collections::LinkedList, string::String, sync::Arc, vec::Vec};
use alloc::{
collections::LinkedList,
string::String,
sync::{Arc, Weak},
vec::Vec,
};
use system_error::SystemError;
use crate::{
@ -55,7 +60,7 @@ impl TtyCore {
ctrl: SpinLock::new(TtyContorlInfo::default()),
closing: AtomicBool::new(false),
flow: SpinLock::new(TtyFlowState::default()),
link: None,
link: RwLock::default(),
epitems: SpinLock::new(LinkedList::new()),
};
@ -138,7 +143,7 @@ impl TtyCore {
self.core()
.write_wq
.wakeup(EPollEventType::EPOLLOUT.bits() as u64);
.wakeup_any(EPollEventType::EPOLLOUT.bits() as u64);
}
pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
@ -252,7 +257,7 @@ pub struct TtyContorlInfo {
pub pgid: Option<Pid>,
/// packet模式下使用目前未用到
pub pktstatus: u8,
pub pktstatus: TtyPacketStatus,
pub packet: bool,
}
@ -296,7 +301,7 @@ pub struct TtyCoreData {
/// 流控状态
flow: SpinLock<TtyFlowState>,
/// 链接tty
link: Option<Arc<TtyCore>>,
link: RwLock<Weak<TtyCore>>,
/// epitems
epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
}
@ -332,6 +337,11 @@ impl TtyCoreData {
*self.flags.read_irqsave()
}
#[inline]
pub fn flags_write(&self) -> RwLockWriteGuard<'_, TtyFlag> {
self.flags.write_irqsave()
}
#[inline]
pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
self.termios.read_irqsave()
@ -348,6 +358,11 @@ impl TtyCoreData {
*termios_guard = termios;
}
#[inline]
pub fn count(&self) -> usize {
self.count.load(Ordering::SeqCst)
}
#[inline]
pub fn add_count(&self) {
self.count
@ -391,7 +406,36 @@ impl TtyCoreData {
#[inline]
pub fn link(&self) -> Option<Arc<TtyCore>> {
self.link.clone()
self.link.read().upgrade()
}
pub fn checked_link(&self) -> Result<Arc<TtyCore>, SystemError> {
if let Some(link) = self.link() {
return Ok(link);
}
return Err(SystemError::ENODEV);
}
pub fn set_link(&self, link: Weak<TtyCore>) {
*self.link.write() = link;
}
pub fn init_termios(&self) {
let tty_index = self.index();
let driver = self.driver();
// 初始化termios
if !driver
.flags()
.contains(super::tty_driver::TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS)
{
// 先查看是否有已经保存的termios
if let Some(t) = driver.saved_termios().get(tty_index) {
let mut termios = *t;
termios.line = driver.init_termios().line;
self.set_termios(termios);
}
}
// TODO:设置termios波特率
}
#[inline]
@ -463,6 +507,10 @@ impl TtyOperation for TtyCore {
.driver_funcs()
.set_termios(tty, old_termios);
}
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
self.core().tty_driver.driver_funcs().close(tty)
}
}
bitflags! {
@ -492,6 +540,19 @@ bitflags! {
/// 终端线路驱动程序已停止
const LDISC_HALTED = 1 << 22;
}
#[derive(Default)]
pub struct TtyPacketStatus: u8 {
/* Used for packet mode */
const TIOCPKT_DATA = 0;
const TIOCPKT_FLUSHREAD = 1;
const TIOCPKT_FLUSHWRITE = 2;
const TIOCPKT_STOP = 4;
const TIOCPKT_START = 8;
const TIOCPKT_NOSTOP = 16;
const TIOCPKT_DOSTOP = 32;
const TIOCPKT_IOCTL = 64;
}
}
#[derive(Debug, PartialEq)]
@ -614,4 +675,12 @@ impl TtyIoctlCmd {
pub const TIOCCBRK: u32 = 0x5428;
/// Return the session ID of FD
pub const TIOCGSID: u32 = 0x5429;
/// 设置ptl锁标记
pub const TIOCSPTLCK: u32 = 0x40045431;
/// 获取ptl锁标记
pub const TIOCGPTLCK: u32 = 0x80045439;
/// 获取packet标记
pub const TIOCGPKT: u32 = 0x80045438;
/// 获取pts index
pub const TIOCGPTN: u32 = 0x80045430;
}

View File

@ -29,7 +29,10 @@ use crate::{
vfs::{file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata},
},
init::initcall::INITCALL_DEVICE,
libs::rwlock::RwLock,
libs::{
rwlock::{RwLock, RwLockWriteGuard},
spinlock::SpinLockGuard,
},
mm::VirtAddr,
net::event_poll::{EPollItem, EventPoll},
process::ProcessManager,
@ -38,10 +41,11 @@ use crate::{
use super::{
kthread::tty_flush_thread_init,
pty::unix98pty::ptmx_open,
sysfs::sys_class_tty_instance,
termios::WindowSize,
tty_core::{TtyCore, TtyFlag, TtyIoctlCmd},
tty_driver::{TtyDriver, TtyDriverSubType, TtyDriverType, TtyOperation},
tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TtyOperation},
tty_job_control::TtyJobCtrlManager,
virtual_terminal::vty_init,
};
@ -72,13 +76,30 @@ impl InnerTtyDevice {
metadata: Metadata::new(FileType::CharDevice, ModeType::from_bits_truncate(0o755)),
}
}
pub fn metadata_mut(&mut self) -> &mut Metadata {
&mut self.metadata
}
}
#[derive(Debug, PartialEq)]
pub enum TtyType {
Tty,
Pty(PtyType),
}
#[derive(Debug, PartialEq)]
pub enum PtyType {
Ptm,
Pts,
}
#[derive(Debug)]
#[cast_to([sync] Device)]
pub struct TtyDevice {
name: &'static str,
name: String,
id_table: IdTable,
tty_type: TtyType,
inner: RwLock<InnerTtyDevice>,
kobj_state: LockedKObjectState,
/// TTY所属的文件系统
@ -86,7 +107,7 @@ pub struct TtyDevice {
}
impl TtyDevice {
pub fn new(name: &'static str, id_table: IdTable) -> Arc<TtyDevice> {
pub fn new(name: String, id_table: IdTable, tty_type: TtyType) -> Arc<TtyDevice> {
let dev_num = id_table.device_number();
let dev = TtyDevice {
name,
@ -94,23 +115,37 @@ impl TtyDevice {
inner: RwLock::new(InnerTtyDevice::new()),
kobj_state: LockedKObjectState::new(None),
fs: RwLock::new(Weak::default()),
tty_type,
};
dev.inner.write().metadata.raw_dev = dev_num;
Arc::new(dev)
}
pub fn inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice> {
self.inner.write()
}
}
impl IndexNode for TtyDevice {
fn open(
&self,
data: &mut crate::filesystem::vfs::FilePrivateData,
mut data: SpinLockGuard<FilePrivateData>,
mode: &crate::filesystem::vfs::file::FileMode,
) -> Result<(), SystemError> {
if self.tty_type == TtyType::Pty(PtyType::Ptm) {
if let FilePrivateData::Tty(_) = &*data {
return Ok(());
}
return ptmx_open(data, mode);
}
let dev_num = self.metadata()?.raw_dev;
let tty = TtyDriver::open_tty(dev_num)?;
let (index, driver) =
TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
let tty = TtyDriver::open_tty(index, driver)?;
// 设置privdata
*data = FilePrivateData::Tty(TtyFilePrivateData {
@ -148,14 +183,16 @@ impl IndexNode for TtyDevice {
_offset: usize,
len: usize,
buf: &mut [u8],
data: &mut crate::filesystem::vfs::FilePrivateData,
data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, system_error::SystemError> {
let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = data {
(tty_priv.tty.clone(), tty_priv.mode)
let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
(tty_priv.tty(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
drop(data);
let ld = tty.ldisc();
let mut offset = 0;
let mut cookie = false;
@ -188,15 +225,15 @@ impl IndexNode for TtyDevice {
_offset: usize,
len: usize,
buf: &[u8],
data: &mut crate::filesystem::vfs::FilePrivateData,
data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, system_error::SystemError> {
let mut count = len;
let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = data {
(tty_priv.tty.clone(), tty_priv.mode)
let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
(tty_priv.tty(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
drop(data);
let ld = tty.ldisc();
let core = tty.core();
let mut chunk = 2048;
@ -239,7 +276,7 @@ impl IndexNode for TtyDevice {
}
fn as_any_ref(&self) -> &dyn core::any::Any {
todo!()
self
}
fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
@ -250,17 +287,30 @@ impl IndexNode for TtyDevice {
Ok(self.inner.read().metadata.clone())
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
let mut guard = self.inner_write();
guard.metadata = metadata.clone();
Ok(())
}
fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
let (tty, _mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
(tty_priv.tty(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
drop(data);
tty.close(tty.clone())
}
fn resize(&self, _len: usize) -> Result<(), SystemError> {
Ok(())
}
fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
(tty_priv.tty.clone(), tty_priv.mode)
(tty_priv.tty(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
@ -485,8 +535,14 @@ impl CharDevice for TtyDevice {
#[derive(Debug, Clone)]
pub struct TtyFilePrivateData {
tty: Arc<TtyCore>,
mode: FileMode,
pub tty: Arc<TtyCore>,
pub mode: FileMode,
}
impl TtyFilePrivateData {
pub fn tty(&self) -> Arc<TtyCore> {
self.tty.clone()
}
}
/// 初始化tty设备和console子设备
@ -494,19 +550,21 @@ pub struct TtyFilePrivateData {
#[inline(never)]
pub fn tty_init() -> Result<(), SystemError> {
let tty = TtyDevice::new(
"tty0",
"tty0".to_string(),
IdTable::new(
String::from("tty0"),
Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
),
TtyType::Tty,
);
let console = TtyDevice::new(
"console",
"console".to_string(),
IdTable::new(
String::from("console"),
Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
),
TtyType::Tty,
);
// 注册tty设备
@ -536,8 +594,8 @@ pub fn tty_init() -> Result<(), SystemError> {
// 将这两个设备注册到devfsTODO这里console设备应该与tty在一个设备group里面
device_register(tty.clone())?;
device_register(console.clone())?;
devfs_register(tty.name, tty)?;
devfs_register(console.name, console)?;
devfs_register(&tty.name.clone(), tty)?;
devfs_register(&console.name.clone(), console)?;
serial_init()?;

View File

@ -1,8 +1,8 @@
use core::{fmt::Debug, sync::atomic::Ordering};
use core::fmt::Debug;
use alloc::{
string::{String, ToString},
sync::Arc,
sync::{Arc, Weak},
vec::Vec,
};
use hashbrown::HashMap;
@ -20,38 +20,46 @@ use crate::{
},
tty::tty_port::TtyPortState,
},
libs::spinlock::SpinLock,
libs::{
rwlock::RwLock,
spinlock::{SpinLock, SpinLockGuard},
},
};
use super::{
termios::Termios,
tty_core::{TtyCore, TtyCoreData},
tty_ldisc::TtyLdiscManager,
tty_port::TTY_PORTS,
virtual_terminal::virtual_console::CURRENT_VCNUM,
tty_port::{DefaultTtyPort, TtyPort},
};
lazy_static! {
static ref TTY_DRIVERS: SpinLock<Vec<Arc<TtyDriver>>> = SpinLock::new(Vec::new());
pub static ref TTY_DRIVERS: SpinLock<Vec<Arc<TtyDriver>>> = SpinLock::new(Vec::new());
}
pub enum TtyDriverPrivateData {
Unused,
/// true表示主设备 false表示从设备
Pty(bool),
}
pub struct TtyDriverManager;
impl TtyDriverManager {
pub fn lookup_tty_driver(dev_num: DeviceNumber) -> Option<(usize, Arc<TtyDriver>)> {
let drivers_guard = TTY_DRIVERS.lock();
for (index, driver) in drivers_guard.iter().enumerate() {
for driver in drivers_guard.iter() {
let base = DeviceNumber::new(driver.major, driver.minor_start);
if dev_num < base || dev_num.data() > base.data() + driver.device_count {
continue;
}
return Some((index, driver.clone()));
return Some(((dev_num.data() - base.data()) as usize, driver.clone()));
}
None
}
/// ## 注册驱动
pub fn tty_register_driver(mut driver: TtyDriver) -> Result<(), SystemError> {
pub fn tty_register_driver(mut driver: TtyDriver) -> Result<Arc<TtyDriver>, SystemError> {
// 查看是否注册设备号
if driver.major == Major::UNNAMED_MAJOR {
let dev_num = CharDevOps::alloc_chardev_region(
@ -69,11 +77,12 @@ impl TtyDriverManager {
driver.flags |= TtyDriverFlag::TTY_DRIVER_INSTALLED;
// 加入全局TtyDriver表
TTY_DRIVERS.lock().push(Arc::new(driver));
let driver = Arc::new(driver);
TTY_DRIVERS.lock().push(driver.clone());
// TODO: 加入procfs?
Ok(())
Ok(driver)
}
}
@ -104,11 +113,13 @@ pub struct TtyDriver {
/// 驱动程序标志
flags: TtyDriverFlag,
/// pty链接此driver的入口
pty: Option<Arc<TtyDriver>>,
other_pty_driver: RwLock<Weak<TtyDriver>>,
/// 具体类型的tty驱动方法
driver_funcs: Arc<dyn TtyOperation>,
/// 管理的tty设备列表
ttys: SpinLock<HashMap<usize, Arc<TtyCore>>>,
/// 管理的端口列表
ports: RwLock<Vec<Arc<dyn TtyPort>>>,
// procfs入口?
}
@ -124,6 +135,10 @@ impl TtyDriver {
default_termios: Termios,
driver_funcs: Arc<dyn TtyOperation>,
) -> Self {
let mut ports: Vec<Arc<dyn TtyPort>> = Vec::with_capacity(count as usize);
for _ in 0..count {
ports.push(Arc::new(DefaultTtyPort::new()))
}
TtyDriver {
driver_name: Default::default(),
name: node_name,
@ -135,10 +150,11 @@ impl TtyDriver {
tty_driver_sub_type: Default::default(),
init_termios: default_termios,
flags: TtyDriverFlag::empty(),
pty: Default::default(),
other_pty_driver: Default::default(),
driver_funcs,
ttys: SpinLock::new(HashMap::new()),
saved_termios: Vec::with_capacity(count as usize),
ports: RwLock::new(ports),
}
}
@ -162,34 +178,65 @@ impl TtyDriver {
self.driver_funcs.clone()
}
#[inline]
pub fn init_termios(&self) -> Termios {
self.init_termios
}
#[inline]
pub fn init_termios_mut(&mut self) -> &mut Termios {
&mut self.init_termios
}
#[inline]
pub fn other_pty_driver(&self) -> Option<Arc<TtyDriver>> {
self.other_pty_driver.read().upgrade()
}
pub fn set_other_pty_driver(&self, driver: Weak<TtyDriver>) {
*self.other_pty_driver.write() = driver
}
#[inline]
pub fn set_subtype(&mut self, tp: TtyDriverSubType) {
self.tty_driver_sub_type = tp;
}
#[inline]
pub fn ttys(&self) -> SpinLockGuard<HashMap<usize, Arc<TtyCore>>> {
self.ttys.lock()
}
#[inline]
pub fn saved_termios(&self) -> &Vec<Termios> {
&self.saved_termios
}
#[inline]
pub fn flags(&self) -> TtyDriverFlag {
self.flags
}
#[inline]
fn lockup_tty(&self, index: usize) -> Option<Arc<TtyCore>> {
let device_guard = self.ttys.lock();
return device_guard.get(&index).cloned();
fn lookup_tty(&self, index: usize) -> Option<Arc<TtyCore>> {
let ret = self
.driver_funcs()
.lookup(index, TtyDriverPrivateData::Unused);
if let Err(SystemError::ENOSYS) = ret {
let device_guard = self.ttys.lock();
return device_guard.get(&index).cloned();
}
ret.ok()
}
fn standard_install(&self, tty_core: Arc<TtyCore>) -> Result<(), SystemError> {
let tty = tty_core.core();
let tty_index = tty.index();
// 初始化termios
if !self.flags.contains(TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS) {
// 先查看是否有已经保存的termios
if let Some(t) = self.saved_termios.get(tty_index) {
let mut termios = *t;
termios.line = self.init_termios.line;
tty.set_termios(termios);
}
}
tty.init_termios();
// TODO:设置termios波特率
tty.add_count();
self.ttys.lock().insert(tty_index, tty_core);
self.ttys.lock().insert(tty.index(), tty_core);
Ok(())
}
@ -210,7 +257,10 @@ impl TtyDriver {
Ok(())
}
fn init_tty_device(driver: Arc<TtyDriver>, index: usize) -> Result<Arc<TtyCore>, SystemError> {
pub fn init_tty_device(
driver: Arc<TtyDriver>,
index: usize,
) -> Result<Arc<TtyCore>, SystemError> {
let tty = TtyCore::new(driver.clone(), index);
Self::driver_install_tty(driver.clone(), tty.clone())?;
@ -218,8 +268,9 @@ impl TtyDriver {
let core = tty.core();
if core.port().is_none() {
TTY_PORTS[core.index()].setup_tty(Arc::downgrade(&tty));
tty.set_port(TTY_PORTS[core.index()].clone());
let ports = driver.ports.read();
ports[core.index()].setup_internal_tty(Arc::downgrade(&tty));
tty.set_port(ports[core.index()].clone());
}
TtyLdiscManager::ldisc_setup(tty.clone(), None)?;
@ -228,11 +279,8 @@ impl TtyDriver {
}
/// ## 通过设备号找到对应驱动并且初始化Tty
pub fn open_tty(dev_num: DeviceNumber) -> Result<Arc<TtyCore>, SystemError> {
let (index, driver) =
TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
let tty = match driver.lockup_tty(index) {
pub fn open_tty(index: usize, driver: Arc<TtyDriver>) -> Result<Arc<TtyCore>, SystemError> {
let tty = match driver.lookup_tty(index) {
Some(tty) => {
// TODO: 暂时这么写因为还没写TtyPort
if tty.core().port().is_none() {
@ -247,8 +295,6 @@ impl TtyDriver {
None => Self::init_tty_device(driver, index)?,
};
CURRENT_VCNUM.store(index as isize, Ordering::SeqCst);
return Ok(tty);
}
@ -259,10 +305,6 @@ impl TtyDriver {
pub fn tty_driver_sub_type(&self) -> TtyDriverSubType {
self.tty_driver_sub_type
}
pub fn init_termios(&self) -> Termios {
self.init_termios
}
}
impl KObject for TtyDriver {
@ -368,7 +410,9 @@ pub trait TtyOperation: Sync + Send + Debug {
fn flush_chars(&self, tty: &TtyCoreData);
fn put_char(&self, tty: &TtyCoreData, ch: u8) -> Result<(), SystemError>;
fn put_char(&self, _tty: &TtyCoreData, _ch: u8) -> Result<(), SystemError> {
Err(SystemError::ENOSYS)
}
fn start(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
Err(SystemError::ENOSYS)
@ -391,6 +435,16 @@ pub trait TtyOperation: Sync + Send + Debug {
fn set_termios(&self, _tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> {
Err(SystemError::ENOSYS)
}
fn lookup(
&self,
_index: usize,
_priv_data: TtyDriverPrivateData,
) -> Result<Arc<TtyCore>, SystemError> {
Err(SystemError::ENOSYS)
}
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
}
#[allow(dead_code)]

View File

@ -7,7 +7,7 @@ use crate::filesystem::vfs::file::FileMode;
use super::{
termios::Termios,
tty_core::{TtyCore, TtyCoreData},
tty_core::{TtyCore, TtyCoreData, TtyFlag},
};
pub mod ntty;
@ -99,7 +99,7 @@ impl TtyLdiscManager {
/// ### 参数
/// - tty需要设置的tty
/// - o_tty: other tty 用于pty pair
pub fn ldisc_setup(tty: Arc<TtyCore>, _o_tty: Option<Arc<TtyCore>>) -> Result<(), SystemError> {
pub fn ldisc_setup(tty: Arc<TtyCore>, o_tty: Option<Arc<TtyCore>>) -> Result<(), SystemError> {
let ld = tty.ldisc();
let ret = ld.open(tty);
@ -109,7 +109,16 @@ impl TtyLdiscManager {
}
}
// TODO: 处理PTY
// 处理PTY
if let Some(o_tty) = o_tty {
let ld = o_tty.ldisc();
let ret: Result<(), SystemError> = ld.open(o_tty.clone());
if ret.is_err() {
o_tty.core().flags_write().remove(TtyFlag::LDISC_OPEN);
let _ = ld.close(o_tty.clone());
}
}
Ok(())
}

View File

@ -10,7 +10,7 @@ use crate::{
arch::ipc::signal::Signal,
driver::tty::{
termios::{ControlCharIndex, InputMode, LocalMode, OutputMode, Termios},
tty_core::{EchoOperation, TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd},
tty_core::{EchoOperation, TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus},
tty_driver::{TtyDriverFlag, TtyOperation},
tty_job_control::TtyJobCtrlManager,
},
@ -812,6 +812,10 @@ impl NTtyData {
self.read_flags.set_all(false);
self.pushing = false;
self.lookahead_count = 0;
if tty.core().link().is_some() {
self.packet_mode_flush(tty.core());
}
}
}
@ -1521,6 +1525,17 @@ impl NTtyData {
}
Ok(1)
}
fn packet_mode_flush(&self, tty: &TtyCoreData) {
let link = tty.link().unwrap();
if link.core().contorl_info_irqsave().packet {
tty.contorl_info_irqsave()
.pktstatus
.insert(TtyPacketStatus::TIOCPKT_FLUSHREAD);
link.core().read_wq().wakeup_all();
}
}
}
impl TtyLineDiscipline for NTtyLinediscipline {
@ -1551,7 +1566,10 @@ impl TtyLineDiscipline for NTtyLinediscipline {
ldata.lookahead_count = 0;
// todo: kick worker?
// todo: packet mode?
// packet mode?
if core.link().is_some() {
ldata.packet_mode_flush(core);
}
Ok(())
}
@ -1618,12 +1636,31 @@ impl TtyLineDiscipline for NTtyLinediscipline {
}
}
let packet = core.contorl_info_irqsave().packet;
let mut ret: Result<usize, SystemError> = Ok(0);
// 记录读取前 的tail
let tail = ldata.read_tail;
drop(ldata);
while nr != 0 {
// todo: 处理packet模式
if packet {
let link = core.link().unwrap();
let link = link.core();
let mut ctrl = link.contorl_info_irqsave();
if !ctrl.pktstatus.is_empty() {
if offset != 0 {
break;
}
let cs = ctrl.pktstatus;
ctrl.pktstatus = TtyPacketStatus::empty();
buf[offset] = cs.bits();
offset += 1;
// nr -= 1;
break;
}
}
let mut ldata = self.disc_data();
let core = tty.core();
@ -1676,7 +1713,11 @@ impl TtyLineDiscipline for NTtyLinediscipline {
} else {
// 非标准模式
// todo: 处理packet模式
if packet && offset == 0 {
buf[offset] = TtyPacketStatus::TIOCPKT_DATA.bits();
offset += 1;
nr -= 1;
}
// 拷贝数据
if ldata.copy_from_read_buf(core.termios(), buf, &mut nr, &mut offset)?
&& offset >= minimum
@ -2025,7 +2066,14 @@ impl TtyLineDiscipline for NTtyLinediscipline {
if core.contorl_info_irqsave().packet {
let link = core.link();
if link.is_some() && link.unwrap().core().contorl_info_irqsave().pktstatus != 0 {
if link.is_some()
&& !link
.unwrap()
.core()
.contorl_info_irqsave()
.pktstatus
.is_empty()
{
event.insert(
EPollEventType::EPOLLPRI
| EPollEventType::EPOLLIN

View File

@ -1,36 +1,29 @@
use core::{fmt::Debug, sync::atomic::Ordering};
use alloc::{
sync::{Arc, Weak},
vec::Vec,
};
use alloc::sync::{Arc, Weak};
use kdepends::thingbuf::mpsc;
use system_error::SystemError;
use crate::{
driver::tty::virtual_terminal::MAX_NR_CONSOLES,
libs::spinlock::{SpinLock, SpinLockGuard},
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
use super::{
tty_core::TtyCore,
virtual_terminal::{virtual_console::CURRENT_VCNUM, VIRT_CONSOLES},
};
use super::{tty_core::TtyCore, virtual_terminal::virtual_console::CURRENT_VCNUM};
const TTY_PORT_BUFSIZE: usize = 4096;
lazy_static! {
pub static ref TTY_PORTS: Vec<Arc<dyn TtyPort>> = {
let mut v: Vec<Arc<dyn TtyPort>> = Vec::with_capacity(MAX_NR_CONSOLES as usize);
for _ in 0..MAX_NR_CONSOLES as usize {
v.push(Arc::new(DefaultTtyPort::new()))
}
v
};
}
/// 获取当前tty port
#[inline]
pub fn current_tty_port() -> Arc<dyn TtyPort> {
TTY_PORTS[CURRENT_VCNUM.load(Ordering::SeqCst) as usize].clone()
VIRT_CONSOLES[CURRENT_VCNUM.load(Ordering::SeqCst) as usize]
.lock_irqsave()
.port()
}
#[inline]
pub fn tty_port(index: usize) -> Arc<dyn TtyPort> {
VIRT_CONSOLES[index].lock_irqsave().port()
}
#[allow(dead_code)]
@ -41,6 +34,14 @@ pub struct TtyPortData {
sender: mpsc::Sender<u8>,
receiver: mpsc::Receiver<u8>,
tty: Weak<TtyCore>,
/// 内部tty即与port直接相连的
internal_tty: Weak<TtyCore>,
}
impl Default for TtyPortData {
fn default() -> Self {
Self::new()
}
}
impl TtyPortData {
@ -52,11 +53,12 @@ impl TtyPortData {
sender,
receiver,
tty: Weak::new(),
internal_tty: Weak::new(),
}
}
pub fn tty(&self) -> Option<Arc<TtyCore>> {
self.tty.upgrade()
pub fn internal_tty(&self) -> Option<Arc<TtyCore>> {
self.internal_tty.upgrade()
}
}
@ -80,13 +82,13 @@ pub trait TtyPort: Sync + Send + Debug {
}
/// 为port设置tty
fn setup_tty(&self, tty: Weak<TtyCore>) {
self.port_data().tty = tty;
fn setup_internal_tty(&self, tty: Weak<TtyCore>) {
self.port_data().internal_tty = tty;
}
/// 作为客户端的tty ports接收数据
fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> {
let tty = self.port_data().tty.upgrade().unwrap();
let tty = self.port_data().internal_tty().unwrap();
let ld = tty.ldisc();

View File

@ -1,6 +1,10 @@
use core::sync::atomic::Ordering;
use alloc::{string::String, sync::Arc, vec::Vec};
use alloc::{
string::{String, ToString},
sync::Arc,
vec::Vec,
};
use system_error::SystemError;
use crate::{
@ -21,7 +25,7 @@ use super::{
console::ConsoleSwitch,
termios::{InputMode, TTY_STD_TERMIOS},
tty_core::{TtyCore, TtyCoreData},
tty_device::TtyDevice,
tty_device::{TtyDevice, TtyType},
tty_driver::{TtyDriver, TtyDriverManager, TtyDriverType, TtyOperation},
};
@ -191,8 +195,12 @@ impl TtyOperation for TtyConsoleDriverInner {
tty_core.termios_write().input_mode.remove(InputMode::IUTF8);
}
// 设置tty的端口为vc端口
vc_data.port().setup_internal_tty(Arc::downgrade(&tty));
tty.set_port(vc_data.port());
// 加入sysfs
CURRENT_VCNUM.store(tty_core.index() as isize, Ordering::SeqCst);
Ok(())
}
@ -207,6 +215,9 @@ impl TtyOperation for TtyConsoleDriverInner {
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/tty/vt/vt.c#2894
#[inline(never)]
fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
// if String::from_utf8_lossy(buf) == "Hello world!\n" {
// loop {}
// }
let ret = self.do_write(tty, buf, nr);
self.flush_chars(tty);
ret
@ -227,6 +238,10 @@ impl TtyOperation for TtyConsoleDriverInner {
// TODO
Err(SystemError::ENOIOCTLCMD)
}
fn close(&self, _tty: Arc<TtyCore>) -> Result<(), SystemError> {
Ok(())
}
}
#[derive(Debug, Clone)]
@ -264,11 +279,12 @@ pub struct DrawRegion {
pub fn vty_init() -> Result<(), SystemError> {
// 注册虚拟终端设备并将虚拟终端设备加入到文件系统
let vc0 = TtyDevice::new(
"vc0",
"vc0".to_string(),
IdTable::new(
String::from("vc0"),
Some(DeviceNumber::new(Major::TTY_MAJOR, 0)),
),
TtyType::Tty,
);
// 注册tty设备
// CharDevOps::cdev_add(

View File

@ -9,7 +9,11 @@ use bitmap::{traits::BitMapOps, StaticBitmap};
use crate::{
driver::{
serial::serial8250::send_to_default_serial8250_port,
tty::{console::ConsoleSwitch, ConsoleFont, KDMode},
tty::{
console::ConsoleSwitch,
tty_port::{DefaultTtyPort, TtyPort},
ConsoleFont, KDMode,
},
},
libs::{font::FontDesc, rwlock::RwLock},
process::Pid,
@ -142,6 +146,9 @@ pub struct VirtualConsoleData {
/// 对应的Console Driver funcs
driver_funcs: Option<Weak<dyn ConsoleSwitch>>,
/// 对应端口
port: Arc<dyn TtyPort>,
}
impl VirtualConsoleData {
@ -204,9 +211,15 @@ impl VirtualConsoleData {
driver_funcs: None,
cursor_type: VcCursor::empty(),
num,
port: Arc::new(DefaultTtyPort::new()),
}
}
#[inline]
pub fn port(&self) -> Arc<dyn TtyPort> {
self.port.clone()
}
pub(super) fn init(&mut self, rows: Option<usize>, cols: Option<usize>, clear: bool) {
if let Some(rows) = rows {
self.rows = rows;

View File

@ -383,11 +383,15 @@ impl DeviceINode for FbDevice {
}
impl IndexNode for FbDevice {
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
Ok(())
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
Ok(())
}
fn read_at(
@ -395,7 +399,7 @@ impl IndexNode for FbDevice {
offset: usize,
len: usize,
buf: &mut [u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
let fb = self.inner.lock().fb.upgrade().unwrap();
return fb.fb_read(&mut buf[0..len], offset);
@ -406,7 +410,7 @@ impl IndexNode for FbDevice {
offset: usize,
len: usize,
buf: &[u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
let fb = self.inner.lock().fb.upgrade().unwrap();
return fb.fb_write(&buf[0..len], offset);