1 use alloc::{ 2 string::{String, ToString}, 3 sync::{Arc, Weak}, 4 }; 5 use system_error::SystemError; 6 use unified_init::macros::unified_init; 7 8 use crate::{ 9 arch::ipc::signal::Signal, 10 driver::{ 11 base::{ 12 char::CharDevice, 13 class::Class, 14 device::{ 15 bus::Bus, 16 device_number::{DeviceNumber, Major}, 17 device_register, 18 driver::Driver, 19 Device, DeviceKObjType, DeviceType, IdTable, 20 }, 21 kobject::{KObject, LockedKObjectState}, 22 kset::KSet, 23 }, 24 serial::serial_init, 25 }, 26 filesystem::{ 27 devfs::{devfs_register, DevFS, DeviceINode}, 28 kernfs::KernFSInode, 29 vfs::{file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata}, 30 }, 31 init::initcall::INITCALL_DEVICE, 32 libs::{ 33 rwlock::{RwLock, RwLockWriteGuard}, 34 spinlock::SpinLockGuard, 35 }, 36 mm::VirtAddr, 37 net::event_poll::{EPollItem, KernelIoctlData}, 38 process::ProcessManager, 39 syscall::user_access::{UserBufferReader, UserBufferWriter}, 40 }; 41 42 use super::{ 43 kthread::tty_flush_thread_init, 44 pty::unix98pty::ptmx_open, 45 sysfs::sys_class_tty_instance, 46 termios::WindowSize, 47 tty_core::{TtyCore, TtyFlag, TtyIoctlCmd}, 48 tty_driver::{TtyDriverManager, TtyDriverSubType, TtyDriverType, TtyOperation}, 49 tty_job_control::TtyJobCtrlManager, 50 virtual_terminal::vty_init, 51 }; 52 53 #[derive(Debug)] 54 pub struct InnerTtyDevice { 55 /// 当前设备所述的kset 56 kset: Option<Arc<KSet>>, 57 parent_kobj: Option<Weak<dyn KObject>>, 58 /// 当前设备所述的总线 59 bus: Option<Weak<dyn Bus>>, 60 inode: Option<Arc<KernFSInode>>, 61 driver: Option<Weak<dyn Driver>>, 62 can_match: bool, 63 64 metadata: Metadata, 65 } 66 67 impl InnerTtyDevice { 68 pub fn new() -> Self { 69 Self { 70 kset: None, 71 parent_kobj: None, 72 bus: None, 73 inode: None, 74 driver: None, 75 can_match: false, 76 metadata: Metadata::new(FileType::CharDevice, ModeType::from_bits_truncate(0o755)), 77 } 78 } 79 80 pub fn metadata_mut(&mut self) -> &mut Metadata { 81 &mut self.metadata 82 } 83 } 84 85 #[derive(Debug, PartialEq)] 86 pub enum TtyType { 87 Tty, 88 Pty(PtyType), 89 } 90 91 #[derive(Debug, PartialEq)] 92 pub enum PtyType { 93 Ptm, 94 Pts, 95 } 96 97 #[derive(Debug)] 98 #[cast_to([sync] Device)] 99 pub struct TtyDevice { 100 name: String, 101 id_table: IdTable, 102 tty_type: TtyType, 103 inner: RwLock<InnerTtyDevice>, 104 kobj_state: LockedKObjectState, 105 /// TTY所属的文件系统 106 fs: RwLock<Weak<DevFS>>, 107 } 108 109 impl TtyDevice { 110 pub fn new(name: String, id_table: IdTable, tty_type: TtyType) -> Arc<TtyDevice> { 111 let dev_num = id_table.device_number(); 112 let dev = TtyDevice { 113 name, 114 id_table, 115 inner: RwLock::new(InnerTtyDevice::new()), 116 kobj_state: LockedKObjectState::new(None), 117 fs: RwLock::new(Weak::default()), 118 tty_type, 119 }; 120 121 dev.inner.write().metadata.raw_dev = dev_num; 122 123 Arc::new(dev) 124 } 125 126 pub fn inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice> { 127 self.inner.write() 128 } 129 130 pub fn name_ref(&self) -> &str { 131 &self.name 132 } 133 } 134 135 impl IndexNode for TtyDevice { 136 fn open( 137 &self, 138 mut data: SpinLockGuard<FilePrivateData>, 139 mode: &crate::filesystem::vfs::file::FileMode, 140 ) -> Result<(), SystemError> { 141 if let FilePrivateData::Tty(_) = &*data { 142 return Ok(()); 143 } 144 if self.tty_type == TtyType::Pty(PtyType::Ptm) { 145 return ptmx_open(data, mode); 146 } 147 let dev_num = self.metadata()?.raw_dev; 148 149 let (index, driver) = 150 TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?; 151 152 let tty = driver.open_tty(Some(index))?; 153 154 // 设置privdata 155 *data = FilePrivateData::Tty(TtyFilePrivateData { 156 tty: tty.clone(), 157 mode: *mode, 158 }); 159 160 let ret = tty.open(tty.core()); 161 if let Err(err) = ret { 162 if err == SystemError::ENOSYS { 163 return Err(SystemError::ENODEV); 164 } 165 return Err(err); 166 } 167 168 let driver = tty.core().driver(); 169 // 考虑noctty(当前tty) 170 if !(mode.contains(FileMode::O_NOCTTY) && dev_num == DeviceNumber::new(Major::TTY_MAJOR, 0) 171 || dev_num == DeviceNumber::new(Major::TTYAUX_MAJOR, 1) 172 || (driver.tty_driver_type() == TtyDriverType::Pty 173 && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster)) 174 { 175 let pcb = ProcessManager::current_pcb(); 176 let pcb_tty = pcb.sig_info_irqsave().tty(); 177 if pcb_tty.is_none() && tty.core().contorl_info_irqsave().session.is_none() { 178 TtyJobCtrlManager::proc_set_tty(tty); 179 } 180 } 181 182 Ok(()) 183 } 184 185 fn read_at( 186 &self, 187 _offset: usize, 188 len: usize, 189 buf: &mut [u8], 190 data: SpinLockGuard<FilePrivateData>, 191 ) -> Result<usize, system_error::SystemError> { 192 let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data { 193 (tty_priv.tty(), tty_priv.mode) 194 } else { 195 return Err(SystemError::EIO); 196 }; 197 198 drop(data); 199 200 let ld = tty.ldisc(); 201 let mut offset = 0; 202 let mut cookie = false; 203 loop { 204 let mut size = if len > buf.len() { buf.len() } else { len }; 205 size = ld.read(tty.clone(), buf, size, &mut cookie, offset, mode)?; 206 // 没有更多数据 207 if size == 0 { 208 break; 209 } 210 211 offset += size; 212 213 // 缓冲区写满 214 if offset >= len { 215 break; 216 } 217 218 // 没有更多数据 219 if !cookie { 220 break; 221 } 222 } 223 224 return Ok(offset); 225 } 226 227 fn write_at( 228 &self, 229 _offset: usize, 230 len: usize, 231 buf: &[u8], 232 data: SpinLockGuard<FilePrivateData>, 233 ) -> Result<usize, system_error::SystemError> { 234 let mut count = len; 235 let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data { 236 (tty_priv.tty(), tty_priv.mode) 237 } else { 238 return Err(SystemError::EIO); 239 }; 240 drop(data); 241 let ld = tty.ldisc(); 242 let core = tty.core(); 243 let mut chunk = 2048; 244 if core.flags().contains(TtyFlag::NO_WRITE_SPLIT) { 245 chunk = 65536; 246 } 247 chunk = chunk.min(count); 248 249 let pcb = ProcessManager::current_pcb(); 250 let mut written = 0; 251 loop { 252 // 至少需要写多少 253 let size = chunk.min(count); 254 255 // 将数据从buf拷贝到writebuf 256 257 let ret = ld.write(tty.clone(), &buf[written..], size, mode)?; 258 259 written += ret; 260 count -= ret; 261 262 if count == 0 { 263 break; 264 } 265 266 if pcb.sig_info_irqsave().sig_pending().has_pending() { 267 return Err(SystemError::ERESTARTSYS); 268 } 269 } 270 271 if written > 0 { 272 // todo: 更新时间 273 } 274 275 Ok(written) 276 } 277 278 fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> { 279 todo!() 280 } 281 282 fn as_any_ref(&self) -> &dyn core::any::Any { 283 self 284 } 285 286 fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> { 287 todo!() 288 } 289 290 fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> { 291 Ok(self.inner.read().metadata.clone()) 292 } 293 294 fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> { 295 let mut guard = self.inner_write(); 296 guard.metadata = metadata.clone(); 297 298 Ok(()) 299 } 300 301 fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 302 let (tty, _mode) = if let FilePrivateData::Tty(tty_priv) = &*data { 303 (tty_priv.tty(), tty_priv.mode) 304 } else { 305 return Err(SystemError::EIO); 306 }; 307 drop(data); 308 tty.close(tty.clone()) 309 } 310 311 fn resize(&self, _len: usize) -> Result<(), SystemError> { 312 Ok(()) 313 } 314 315 fn kernel_ioctl( 316 &self, 317 arg: Arc<dyn KernelIoctlData>, 318 data: &FilePrivateData, 319 ) -> Result<usize, SystemError> { 320 let epitem = arg 321 .arc_any() 322 .downcast::<EPollItem>() 323 .map_err(|_| SystemError::EFAULT)?; 324 325 let _ = UserBufferReader::new( 326 &epitem as *const Arc<EPollItem>, 327 core::mem::size_of::<Arc<EPollItem>>(), 328 false, 329 )?; 330 331 let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data { 332 (tty_priv.tty(), tty_priv.mode) 333 } else { 334 return Err(SystemError::EIO); 335 }; 336 337 let core = tty.core(); 338 339 core.add_epitem(epitem.clone()); 340 341 return Ok(0); 342 } 343 344 fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> { 345 let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data { 346 (tty_priv.tty(), tty_priv.mode) 347 } else { 348 return Err(SystemError::EIO); 349 }; 350 351 match cmd { 352 TtyIoctlCmd::TIOCSETD 353 | TtyIoctlCmd::TIOCSBRK 354 | TtyIoctlCmd::TIOCCBRK 355 | TtyIoctlCmd::TCSBRK 356 | TtyIoctlCmd::TCSBRKP => { 357 TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?; 358 if cmd != TtyIoctlCmd::TIOCCBRK { 359 todo!() 360 } 361 } 362 _ => {} 363 } 364 365 match cmd { 366 TtyIoctlCmd::TIOCGWINSZ => { 367 let core = tty.core(); 368 let winsize = *core.window_size(); 369 370 let mut user_writer = UserBufferWriter::new( 371 VirtAddr::new(arg).as_ptr::<WindowSize>(), 372 core::mem::size_of::<WindowSize>(), 373 true, 374 )?; 375 376 let err = user_writer.copy_one_to_user(&winsize, 0); 377 if err.is_err() { 378 return Err(SystemError::EFAULT); 379 } 380 return Ok(0); 381 } 382 TtyIoctlCmd::TIOCSWINSZ => { 383 let reader = UserBufferReader::new( 384 arg as *const (), 385 core::mem::size_of::<WindowSize>(), 386 true, 387 )?; 388 389 let user_winsize = reader.read_one_from_user::<WindowSize>(0)?; 390 391 let ret = tty.resize(tty.clone(), *user_winsize); 392 393 if ret != Err(SystemError::ENOSYS) { 394 return ret.map(|_| 0); 395 } else { 396 return tty.tty_do_resize(*user_winsize).map(|_| 0); 397 } 398 } 399 _ => match TtyJobCtrlManager::job_ctrl_ioctl(tty.clone(), cmd, arg) { 400 Ok(_) => { 401 return Ok(0); 402 } 403 Err(e) => { 404 if e != SystemError::ENOIOCTLCMD { 405 return Err(e); 406 } 407 } 408 }, 409 } 410 411 match tty.ioctl(tty.clone(), cmd, arg) { 412 Ok(_) => { 413 return Ok(0); 414 } 415 Err(e) => { 416 if e != SystemError::ENOIOCTLCMD { 417 return Err(e); 418 } 419 } 420 } 421 tty.ldisc().ioctl(tty, cmd, arg)?; 422 423 Ok(0) 424 } 425 426 fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> { 427 let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data { 428 (tty_priv.tty.clone(), tty_priv.mode) 429 } else { 430 return Err(SystemError::EIO); 431 }; 432 433 tty.ldisc().poll(tty) 434 } 435 } 436 437 impl DeviceINode for TtyDevice { 438 fn set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>) { 439 *self.fs.write() = fs; 440 } 441 } 442 443 impl KObject for TtyDevice { 444 fn as_any_ref(&self) -> &dyn core::any::Any { 445 self 446 } 447 448 fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) { 449 self.inner.write().inode = inode; 450 } 451 452 fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> { 453 self.inner.read().inode.clone() 454 } 455 456 fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> { 457 self.inner.read().parent_kobj.clone() 458 } 459 460 fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) { 461 self.inner.write().parent_kobj = parent 462 } 463 464 fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> { 465 self.inner.read().kset.clone() 466 } 467 468 fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) { 469 self.inner.write().kset = kset 470 } 471 472 fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> { 473 Some(&DeviceKObjType) 474 } 475 476 fn set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>) {} 477 478 fn name(&self) -> alloc::string::String { 479 self.name.to_string() 480 } 481 482 fn set_name(&self, _name: alloc::string::String) { 483 // self.name = name 484 } 485 486 fn kobj_state( 487 &self, 488 ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> { 489 self.kobj_state.read() 490 } 491 492 fn kobj_state_mut( 493 &self, 494 ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> { 495 self.kobj_state.write() 496 } 497 498 fn set_kobj_state(&self, state: crate::driver::base::kobject::KObjectState) { 499 *self.kobj_state.write() = state 500 } 501 } 502 503 impl Device for TtyDevice { 504 fn dev_type(&self) -> crate::driver::base::device::DeviceType { 505 DeviceType::Char 506 } 507 508 fn id_table(&self) -> crate::driver::base::device::IdTable { 509 self.id_table.clone() 510 } 511 512 fn bus(&self) -> Option<Weak<dyn Bus>> { 513 self.inner.read().bus.clone() 514 } 515 516 fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>) { 517 self.inner.write().bus = bus 518 } 519 520 fn set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>) { 521 // do nothing 522 } 523 524 fn class(&self) -> Option<Arc<dyn Class>> { 525 sys_class_tty_instance() 526 .cloned() 527 .map(|x| x as Arc<dyn Class>) 528 } 529 530 fn driver(&self) -> Option<Arc<dyn crate::driver::base::device::driver::Driver>> { 531 self.inner.read().driver.clone()?.upgrade() 532 } 533 534 fn set_driver( 535 &self, 536 driver: Option<alloc::sync::Weak<dyn crate::driver::base::device::driver::Driver>>, 537 ) { 538 self.inner.write().driver = driver 539 } 540 541 fn is_dead(&self) -> bool { 542 false 543 } 544 545 fn can_match(&self) -> bool { 546 self.inner.read().can_match 547 } 548 549 fn set_can_match(&self, can_match: bool) { 550 self.inner.write().can_match = can_match 551 } 552 553 fn state_synced(&self) -> bool { 554 true 555 } 556 557 fn dev_parent(&self) -> Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>> { 558 None 559 } 560 561 fn set_dev_parent( 562 &self, 563 _dev_parent: Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>>, 564 ) { 565 todo!() 566 } 567 } 568 569 impl CharDevice for TtyDevice { 570 fn read(&self, _len: usize, _buf: &mut [u8]) -> Result<usize, SystemError> { 571 todo!() 572 } 573 574 fn write(&self, _len: usize, _buf: &[u8]) -> Result<usize, SystemError> { 575 todo!() 576 } 577 578 fn sync(&self) -> Result<(), SystemError> { 579 todo!() 580 } 581 } 582 583 #[derive(Debug, Clone)] 584 pub struct TtyFilePrivateData { 585 pub tty: Arc<TtyCore>, 586 pub mode: FileMode, 587 } 588 589 impl TtyFilePrivateData { 590 pub fn tty(&self) -> Arc<TtyCore> { 591 self.tty.clone() 592 } 593 } 594 595 /// 初始化tty设备和console子设备 596 #[unified_init(INITCALL_DEVICE)] 597 #[inline(never)] 598 pub fn tty_init() -> Result<(), SystemError> { 599 let console = TtyDevice::new( 600 "console".to_string(), 601 IdTable::new( 602 String::from("console"), 603 Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)), 604 ), 605 TtyType::Tty, 606 ); 607 608 // 将设备注册到devfs,TODO:这里console设备应该与tty在一个设备group里面 609 device_register(console.clone())?; 610 devfs_register(&console.name.clone(), console)?; 611 612 serial_init()?; 613 614 tty_flush_thread_init(); 615 return vty_init(); 616 } 617