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::{TtyDriver, 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 131 impl IndexNode for TtyDevice { 132 fn open( 133 &self, 134 mut data: SpinLockGuard<FilePrivateData>, 135 mode: &crate::filesystem::vfs::file::FileMode, 136 ) -> Result<(), SystemError> { 137 if let FilePrivateData::Tty(_) = &*data { 138 return Ok(()); 139 } 140 if self.tty_type == TtyType::Pty(PtyType::Ptm) { 141 return ptmx_open(data, mode); 142 } 143 let dev_num = self.metadata()?.raw_dev; 144 145 let (index, driver) = 146 TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?; 147 148 let tty = TtyDriver::open_tty(index, driver)?; 149 150 // 设置privdata 151 *data = FilePrivateData::Tty(TtyFilePrivateData { 152 tty: tty.clone(), 153 mode: *mode, 154 }); 155 156 let ret = tty.open(tty.core()); 157 if let Err(err) = ret { 158 if err == SystemError::ENOSYS { 159 return Err(SystemError::ENODEV); 160 } 161 return Err(err); 162 } 163 164 let driver = tty.core().driver(); 165 // 考虑noctty(当前tty) 166 if !(mode.contains(FileMode::O_NOCTTY) && dev_num == DeviceNumber::new(Major::TTY_MAJOR, 0) 167 || dev_num == DeviceNumber::new(Major::TTYAUX_MAJOR, 1) 168 || (driver.tty_driver_type() == TtyDriverType::Pty 169 && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster)) 170 { 171 let pcb = ProcessManager::current_pcb(); 172 let pcb_tty = pcb.sig_info_irqsave().tty(); 173 if pcb_tty.is_none() && tty.core().contorl_info_irqsave().session.is_none() { 174 TtyJobCtrlManager::proc_set_tty(tty); 175 } 176 } 177 178 Ok(()) 179 } 180 181 fn read_at( 182 &self, 183 _offset: usize, 184 len: usize, 185 buf: &mut [u8], 186 data: SpinLockGuard<FilePrivateData>, 187 ) -> Result<usize, system_error::SystemError> { 188 let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data { 189 (tty_priv.tty(), tty_priv.mode) 190 } else { 191 return Err(SystemError::EIO); 192 }; 193 194 drop(data); 195 196 let ld = tty.ldisc(); 197 let mut offset = 0; 198 let mut cookie = false; 199 loop { 200 let mut size = if len > buf.len() { buf.len() } else { len }; 201 size = ld.read(tty.clone(), buf, size, &mut cookie, offset, mode)?; 202 // 没有更多数据 203 if size == 0 { 204 break; 205 } 206 207 offset += size; 208 209 // 缓冲区写满 210 if offset >= len { 211 break; 212 } 213 214 // 没有更多数据 215 if !cookie { 216 break; 217 } 218 } 219 220 return Ok(offset); 221 } 222 223 fn write_at( 224 &self, 225 _offset: usize, 226 len: usize, 227 buf: &[u8], 228 data: SpinLockGuard<FilePrivateData>, 229 ) -> Result<usize, system_error::SystemError> { 230 let mut count = len; 231 let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data { 232 (tty_priv.tty(), tty_priv.mode) 233 } else { 234 return Err(SystemError::EIO); 235 }; 236 drop(data); 237 let ld = tty.ldisc(); 238 let core = tty.core(); 239 let mut chunk = 2048; 240 if core.flags().contains(TtyFlag::NO_WRITE_SPLIT) { 241 chunk = 65536; 242 } 243 chunk = chunk.min(count); 244 245 let pcb = ProcessManager::current_pcb(); 246 let mut written = 0; 247 loop { 248 // 至少需要写多少 249 let size = chunk.min(count); 250 251 // 将数据从buf拷贝到writebuf 252 253 let ret = ld.write(tty.clone(), &buf[written..], size, mode)?; 254 255 written += ret; 256 count -= ret; 257 258 if count == 0 { 259 break; 260 } 261 262 if pcb.sig_info_irqsave().sig_pending().has_pending() { 263 return Err(SystemError::ERESTARTSYS); 264 } 265 } 266 267 if written > 0 { 268 // todo: 更新时间 269 } 270 271 Ok(written) 272 } 273 274 fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> { 275 todo!() 276 } 277 278 fn as_any_ref(&self) -> &dyn core::any::Any { 279 self 280 } 281 282 fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> { 283 todo!() 284 } 285 286 fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> { 287 Ok(self.inner.read().metadata.clone()) 288 } 289 290 fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> { 291 let mut guard = self.inner_write(); 292 guard.metadata = metadata.clone(); 293 294 Ok(()) 295 } 296 297 fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> { 298 let (tty, _mode) = if let FilePrivateData::Tty(tty_priv) = &*data { 299 (tty_priv.tty(), tty_priv.mode) 300 } else { 301 return Err(SystemError::EIO); 302 }; 303 drop(data); 304 tty.close(tty.clone()) 305 } 306 307 fn resize(&self, _len: usize) -> Result<(), SystemError> { 308 Ok(()) 309 } 310 311 fn kernel_ioctl( 312 &self, 313 arg: Arc<dyn KernelIoctlData>, 314 data: &FilePrivateData, 315 ) -> Result<usize, SystemError> { 316 let epitem = arg 317 .arc_any() 318 .downcast::<EPollItem>() 319 .map_err(|_| SystemError::EFAULT)?; 320 321 let _ = UserBufferReader::new( 322 &epitem as *const Arc<EPollItem>, 323 core::mem::size_of::<Arc<EPollItem>>(), 324 false, 325 )?; 326 327 let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data { 328 (tty_priv.tty(), tty_priv.mode) 329 } else { 330 return Err(SystemError::EIO); 331 }; 332 333 let core = tty.core(); 334 335 core.add_epitem(epitem.clone()); 336 337 return Ok(0); 338 } 339 340 fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> { 341 let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data { 342 (tty_priv.tty(), tty_priv.mode) 343 } else { 344 return Err(SystemError::EIO); 345 }; 346 347 match cmd { 348 TtyIoctlCmd::TIOCSETD 349 | TtyIoctlCmd::TIOCSBRK 350 | TtyIoctlCmd::TIOCCBRK 351 | TtyIoctlCmd::TCSBRK 352 | TtyIoctlCmd::TCSBRKP => { 353 TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?; 354 if cmd != TtyIoctlCmd::TIOCCBRK { 355 todo!() 356 } 357 } 358 _ => {} 359 } 360 361 match cmd { 362 TtyIoctlCmd::TIOCGWINSZ => { 363 let core = tty.core(); 364 let winsize = *core.window_size(); 365 366 let mut user_writer = UserBufferWriter::new( 367 VirtAddr::new(arg).as_ptr::<WindowSize>(), 368 core::mem::size_of::<WindowSize>(), 369 true, 370 )?; 371 372 let err = user_writer.copy_one_to_user(&winsize, 0); 373 if err.is_err() { 374 return Err(SystemError::EFAULT); 375 } 376 return Ok(0); 377 } 378 TtyIoctlCmd::TIOCSWINSZ => { 379 let reader = UserBufferReader::new( 380 arg as *const (), 381 core::mem::size_of::<WindowSize>(), 382 true, 383 )?; 384 385 let user_winsize = reader.read_one_from_user::<WindowSize>(0)?; 386 387 let ret = tty.resize(tty.clone(), *user_winsize); 388 389 if ret != Err(SystemError::ENOSYS) { 390 return ret.map(|_| 0); 391 } else { 392 return tty.tty_do_resize(*user_winsize).map(|_| 0); 393 } 394 } 395 _ => match TtyJobCtrlManager::job_ctrl_ioctl(tty.clone(), cmd, arg) { 396 Ok(_) => { 397 return Ok(0); 398 } 399 Err(e) => { 400 if e != SystemError::ENOIOCTLCMD { 401 return Err(e); 402 } 403 } 404 }, 405 } 406 407 match tty.ioctl(tty.clone(), cmd, arg) { 408 Ok(_) => { 409 return Ok(0); 410 } 411 Err(e) => { 412 if e != SystemError::ENOIOCTLCMD { 413 return Err(e); 414 } 415 } 416 } 417 tty.ldisc().ioctl(tty, cmd, arg)?; 418 419 Ok(0) 420 } 421 422 fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> { 423 let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data { 424 (tty_priv.tty.clone(), tty_priv.mode) 425 } else { 426 return Err(SystemError::EIO); 427 }; 428 429 tty.ldisc().poll(tty) 430 } 431 } 432 433 impl DeviceINode for TtyDevice { 434 fn set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>) { 435 *self.fs.write() = fs; 436 } 437 } 438 439 impl KObject for TtyDevice { 440 fn as_any_ref(&self) -> &dyn core::any::Any { 441 self 442 } 443 444 fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) { 445 self.inner.write().inode = inode; 446 } 447 448 fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> { 449 self.inner.read().inode.clone() 450 } 451 452 fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> { 453 self.inner.read().parent_kobj.clone() 454 } 455 456 fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) { 457 self.inner.write().parent_kobj = parent 458 } 459 460 fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> { 461 self.inner.read().kset.clone() 462 } 463 464 fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) { 465 self.inner.write().kset = kset 466 } 467 468 fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> { 469 Some(&DeviceKObjType) 470 } 471 472 fn set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>) {} 473 474 fn name(&self) -> alloc::string::String { 475 self.name.to_string() 476 } 477 478 fn set_name(&self, _name: alloc::string::String) { 479 // self.name = name 480 } 481 482 fn kobj_state( 483 &self, 484 ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> { 485 self.kobj_state.read() 486 } 487 488 fn kobj_state_mut( 489 &self, 490 ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> { 491 self.kobj_state.write() 492 } 493 494 fn set_kobj_state(&self, state: crate::driver::base::kobject::KObjectState) { 495 *self.kobj_state.write() = state 496 } 497 } 498 499 impl Device for TtyDevice { 500 fn dev_type(&self) -> crate::driver::base::device::DeviceType { 501 DeviceType::Char 502 } 503 504 fn id_table(&self) -> crate::driver::base::device::IdTable { 505 self.id_table.clone() 506 } 507 508 fn bus(&self) -> Option<Weak<dyn Bus>> { 509 self.inner.read().bus.clone() 510 } 511 512 fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>) { 513 self.inner.write().bus = bus 514 } 515 516 fn set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>) { 517 // do nothing 518 } 519 520 fn class(&self) -> Option<Arc<dyn Class>> { 521 sys_class_tty_instance() 522 .cloned() 523 .map(|x| x as Arc<dyn Class>) 524 } 525 526 fn driver(&self) -> Option<Arc<dyn crate::driver::base::device::driver::Driver>> { 527 self.inner.read().driver.clone()?.upgrade() 528 } 529 530 fn set_driver( 531 &self, 532 driver: Option<alloc::sync::Weak<dyn crate::driver::base::device::driver::Driver>>, 533 ) { 534 self.inner.write().driver = driver 535 } 536 537 fn is_dead(&self) -> bool { 538 false 539 } 540 541 fn can_match(&self) -> bool { 542 self.inner.read().can_match 543 } 544 545 fn set_can_match(&self, can_match: bool) { 546 self.inner.write().can_match = can_match 547 } 548 549 fn state_synced(&self) -> bool { 550 true 551 } 552 } 553 554 impl CharDevice for TtyDevice { 555 fn read(&self, _len: usize, _buf: &mut [u8]) -> Result<usize, SystemError> { 556 todo!() 557 } 558 559 fn write(&self, _len: usize, _buf: &[u8]) -> Result<usize, SystemError> { 560 todo!() 561 } 562 563 fn sync(&self) -> Result<(), SystemError> { 564 todo!() 565 } 566 } 567 568 #[derive(Debug, Clone)] 569 pub struct TtyFilePrivateData { 570 pub tty: Arc<TtyCore>, 571 pub mode: FileMode, 572 } 573 574 impl TtyFilePrivateData { 575 pub fn tty(&self) -> Arc<TtyCore> { 576 self.tty.clone() 577 } 578 } 579 580 /// 初始化tty设备和console子设备 581 #[unified_init(INITCALL_DEVICE)] 582 #[inline(never)] 583 pub fn tty_init() -> Result<(), SystemError> { 584 let tty = TtyDevice::new( 585 "tty0".to_string(), 586 IdTable::new( 587 String::from("tty0"), 588 Some(DeviceNumber::new(Major::TTY_MAJOR, 0)), 589 ), 590 TtyType::Tty, 591 ); 592 593 let console = TtyDevice::new( 594 "console".to_string(), 595 IdTable::new( 596 String::from("console"), 597 Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)), 598 ), 599 TtyType::Tty, 600 ); 601 602 // 注册tty设备 603 // CharDevOps::cdev_add( 604 // tty.clone() as Arc<dyn CharDevice>, 605 // IdTable::new( 606 // String::from("tty0"), 607 // Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 0)), 608 // ), 609 // 1, 610 // )?; 611 612 // CharDevOps::register_chardev_region(DeviceNumber::new(Major::TTYAUX_MAJOR, 0), 1, "/dev/tty")?; 613 614 // 注册console设备 615 // CharDevOps::cdev_add( 616 // console.clone() as Arc<dyn CharDevice>, 617 // IdTable::new( 618 // String::from("console"), 619 // Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)), 620 // ), 621 // 1, 622 // )?; 623 624 // CharDevOps::register_chardev_region(DeviceNumber::new(Major::TTYAUX_MAJOR, 1), 1, "/dev/tty")?; 625 626 // 将这两个设备注册到devfs,TODO:这里console设备应该与tty在一个设备group里面 627 device_register(tty.clone())?; 628 device_register(console.clone())?; 629 devfs_register(&tty.name.clone(), tty)?; 630 devfs_register(&console.name.clone(), console)?; 631 632 serial_init()?; 633 634 tty_flush_thread_init(); 635 return vty_init(); 636 } 637